使用 webpack-dev-server 运行节点表示服务器

我正在使用 webpack 成功运行我的反应前端,使用以下配置:

{
name: 'client',
entry: './scripts/main.js',
output: {
path: __dirname,
filename: 'bundle.js'
},
module: {
loaders: [
{
test: /.jsx?$/,
loader: 'babel-loader',
exclude: /node_modules/,
query:{
presets: ['es2015', 'react', 'stage-2']
}
}
]
}
}

我正在尝试建立一个 node.js Express 后端,并希望通过 webpack 运行它,这样我就有一个单独的服务器同时运行后端和前端,因为我想使用 babel 来传输我的 javascript。

我做了一个快速测试服务器,看起来像这样:

var express = require('express');
console.log('test');


var app = express();


app.get('/', function(req, res){
res.send("Hello world from Express!!");
});


app.listen(3000, function(){
console.log('Example app listening on port 3000');
});

If I run this with node index.js and open my browser on localhost:3000 it prints "Hello world from Express!!". So far so good. Then I tried creating a web-pack config for it:

var fs = require('fs');
var nodeModules = {};
fs.readdirSync('node_modules')
.filter(function(x) {
return ['.bin'].indexOf(x) === -1;
})
.forEach(function(mod) {
nodeModules[mod] = 'commonjs ' + mod;
});


module.exports = [
{
name: 'server',
target: 'node',
entry: './index.js',
output: {
path: __dirname,
filename: 'bundle.js'
},
externals: nodeModules,
module: {
loaders: [
{
test: /\.js$/,
loaders: [
'babel-loader'
]
},
{
test:  /\.json$/,
loader: 'json-loader'
}
]
}
}

当我运行命令 webpack-dev-server时,它成功地启动了(看起来是这样)。但是,如果我现在在 localhost:3000上打开浏览器,它只是说该网页不可用,就像当服务器根本不运行时一样。

我对 node 和 webpack 都很陌生,所以要么是我在某个地方犯了一个小错误,要么就是我大错特错了;)

82033 次浏览

从您在这里的问题和 给你中可以看出,您正在 ES6中使用 ReactJS。我也面临着同样的问题,我是这样解决的

  1. 为您的应用程序提供多个入口点

特别是,您可以将所有供应商文件(如 JQuery、 React 等)放入一个块中。这样,即使在修改源文件时,供应商文件也将保持不变。您可以将此行添加到您的 webpack 配置中

entry: {
vendors: ['react','reactDom','jquery'] //Any other libraries
}

使用 CommonsChunkPlugin让 webpack 确定您使用最多的代码/模块,并将其放在一个单独的包中,以便在应用程序的任何地方使用。

plugins: [
new webpack.optimize.CommonsChunkPlugin('vendors', 'dist/js/vendors.js', Infinity),
]
  1. 使用热反应装载机

运行 npm install react-hot-loader --save-dev。请确保先安装了 webpack-dev-server

然后你需要改变你的装载机到这个-

loaders: [
{
test: /\.jsx?$/,
loaders: ['react-hot'],
include: path.join(__dirname, 'public')


},{
loader: 'babel',
query: {
presets: ['react', 'es2015']
},
include: path.join(__dirname, 'public')
},
]

确保 React Hot Loader 在装载机阵列中出现在 Babel 之前。还要确保使用 include: path.join(__dirname, 'public')来避免处理 node _ module,否则可能会出现如下错误-

Uncaught TypeError: Cannot read property 'NODE_ENV' of undefined

  1. index.html页中的脚本标记进行修改

如果您的 html 有这样的东西-

<script src="/dist/js/vendors.js"></script>
<script src="/dist/js/app.bundle.js"></script>

将其更改为指向您的 webpack-dev-server agent-

<script src="http://localhost:8080/dist/js/vendors.js"></script>
<script src="http://localhost:8080/dist/js/app.bundle.js"></script>
  1. 运行 webpack-dev-server --hot --inline,

等待捆绑完成,然后在浏览器中点击 http://localhost:3000(您的快速服务器端口)。

如果您遇到任何错误,您会发现这个 故障排除指南非常有用。

希望这有所帮助,您可以看一下我的项目 给你的 webpack 设置

Webpack-dev-server 非常适合客户端开发,但它不会部署 Express api 或中间件。因此,在开发过程中,我建议运行两个独立的服务器: 一个用于客户端,另一个用于服务器端 api。

Noemon npm install --save-dev nodemon是一个很好的后端开发服务器,它可以为您的 API 提供热重部署,或者您可以在进行更改时使用 Express 并重新启动。在生产环境中,客户机和 api 仍然由同一个快递服务器提供服务。

package.json中为 noemon 和 webpack-dev-server 设置一个生命周期事件,以便于启动它们(例如: npm run dev-server)。

"scripts": {
"start": "webpack --progress --colors",
"dev-server": "nodemon ./server.js localhost 8080",
"dev-client": "webpack-dev-server --port 3000",
}

或者,从节点直接运行 Express:

"scripts": {
"start": "webpack --progress --colors",
"dev-server": "node dev-server.js",
"dev-client": "webpack-dev-server --port 3000",
}
// dev-server.js
const express = require('express');
const app = express();
// Import routes
require('./_routes')(app);   // <-- or whatever you do to include your API endpoints and middleware
app.set('port', 8080);
app.listen(app.get('port'), function() {
console.log('Node App Started');
});

注意: API 服务器必须使用与 webpack-dev-server 不同的端口

最后,在 webpack-dev-config 中,您需要使用一个代理将对 API 的调用重定向到新端口:

devServer: {
historyApiFallback: true,
hot: true,
inline: true,


host: 'localhost', // Defaults to `localhost`
port: 3000, // Defaults to 8080
proxy: {
'^/api/*': {
target: 'http://localhost:8080/api/',
secure: false
}
}
},
// and separately, in your plugins section
plugins: [
new webpack.HotModuleReplacementPlugin({
multiStep: true
})
]

如果有一个单独的脚本来启动并杀死这两个脚本,那么就会得到额外的分数

因为 Webpack-dev-server只是一个小型的快速服务器,可以在更改和热重载时进行编译。

因此,如果您已经有了一个用于后端 API 的快速服务器,那么只需将 compile on change and hot reload合并到快速服务器中即可。

然后在看了 Webpack-dev-serverpackage.json之后,我发现关键是 Webpack-dev-中间件

const express = require('express'); //your original BE server
const app = express();


const webpack = require('webpack');
const middleware = require('webpack-dev-middleware'); //webpack hot reloading middleware
const compiler = webpack({ .. webpack options .. }); //move your `devServer` config from `webpack.config.js`




app.use(middleware(compiler, {
// webpack-dev-middleware options
}));


app.listen(3000, () => console.log('Example app listening on port 3000!'))

因此,当您运行 BE 服务器时,它将使用 webpack 编译所有的内容,并注意更改,LOL ~

另外,为热重新加载功能添加 Webpack 热中间件,请参阅 热模组更换

刚刚面临同样的问题,并带来了另一个解决方案(找到了更多的信息后,但在这里)。

不要使用 webpack-dev-server,而是使用 webpack --watch命令,以便在发生更改时再次编译文件。一旦文件在 dist (或任何其他已编译的文件文件夹)上更新,您可以设置为在 dist 文件夹上运行 noemon,并只观察 dist 文件。

通过这种方式,可以像在生产环境(或某种程度上)中那样运行快速服务器并为前端服务,并从快速重载中获益。

这里的 一种联系与一些解决方案,以结合网络包手表和无恶魔。

我的脚本部分现在是这样的(我使用 run-all 解决方案) :

  "scripts": {
"serve": "npm-run-all --parallel serve:webpack serve:nodemon",
"serve:webpack": "webpack --progress --colors --watch",
"serve:nodemon": "nodemon ./dist/app.js --watch dist"
},

我发现这是一个非常简单的解决方案,适用于 create-react-app,您只需要使用 npm start启动 webpack-dev-server,并且不能使用 webpack 配置。只需使用 Express 中的 http-proxy-middleware将服务器本身不能处理的所有请求代理到 webpack-dev-server:

import express from "express"
import { createProxyMiddleware } from "http-proxy-middleware"
const app = express()


// Put your web APIs here, for example:
app.get("/hello", (req, res) => {
res.send("Hello World")
})


...


// This goes after all your other routes:
if (!isProduction) {
app.use("*", createProxyMiddleware({ target: "http://127.0.0.1:3000", ws: true }))
}


app.listen(5000)

注1: 为了简单起见,我没有使用 HTTP (使用环境变量 HTTPS=false让 webpack-dev-server 使用 HTTP)

注2: 您只想在开发模式下创建代理-在生产中,您可能会使用 express.static来服务您编译的单页应用程序。

在 React 项目上运行 npm start并启动 Express 服务器。然后(使用示例代码中的端口号)浏览到 http://localhost:5000。您将看到您的反应前端,它将能够发送 API 请求到您的 Express 服务器,所有端口5000。热模块更换工程太!

快速回答: webpack-dev-server 内置了一个 Express,只需使用 OnAfterSetupMiddleware在安装中间件之前获取应用程序实例

module.exports = {
//...
devServer: {
onBeforeSetupMiddleware: function (devServer) {
if (!devServer) {
throw new Error('webpack-dev-server is not defined');
}
// **devServer.app is an express**
devServer.app.get('/some/path', function (req, res) {
res.json({ custom: 'response' });
});
},
},
};


博士

有一些方法可以让它工作,上面的一个是我最喜欢的,让我们看看其他的工作环境

使用代理配置 webpack 开发服务器

这样你只需要一个额外的后端进程,这意味着一个额外的步骤来启动和停止你的服务,仍然是一个足够好的解决方案,简单和工作

Webpack-dev-midware: 用于 Express 的中间件

由于缺乏文档和维护,我正在使用它并使其工作,但是当一些软件包更新失败