-
Notifications
You must be signed in to change notification settings - Fork 0
webpack dev server.cn
The webpack-dev-server is a little node.js Express server, which uses the webpack-dev-middleware to serve a webpack bundle. It also has a little runtime which is connected to the server via Socket.IO. The server emits information about the compilation state to the client, which reacts to those events. You can choose between different modes, depending on your needs. So let's say you have the following config file (webpack.config.js
):
webpack-dev-server 是个小型node.js Express 服务器,使用了_webpack-dev-middleware来提供_webpack bundle。它也有通过Socket.IO连接到服务器的运行时服务。服务器给客户端发送有关编译状态的信息,从而客户端作出相应响应。你可以根据需要选择不同模式。譬如你有个这样的配置文件(webpack.config.js
):
var path = require("path");
module.exports = {
entry: {
app: ["./app/main.js"]
},
output: {
path: path.resolve(__dirname, "build"),
publicPath: "/assets/",
filename: "bundle.js"
}
};
You have an app
folder with your initial entry point that webpack will bundle into a bundle.js
file in the build
folder.
你有个app
文件夹存放初始入口点(文件),__webpack__会将其打包成bundle.js
输出到build
目录。
NOTE: The webpack dev server is a separate NPM package, which can be installed with the command npm install webpack-dev-server
.
注意:webpack dev sever 是一个独立的 npm 包,可以通过命令npm install webpack-dev-server
安装
The webpack-dev-server will serve the files in the current directory, unless you configure a specific content base.
webpack-dev-server 会从当前目录提供文件访问。除非,你配置了指定的资源根目录。
$ webpack-dev-server --content-base build/
Using this config webpack-dev-server will serve the static files in your build
folder. It'll watch your source files for changes and when changes are made the bundle will be recompiled. This modified bundle is served from memory at the relative path specified in publicPath
(see API). It will not be written to your configured output directory. Where a bundle already exists at the same url path the bundle in memory will take precedence (by default).
使用这个配置,webpack-dev-server 会从build
文件夹提供静态文件。它会监听源文件的更改。一旦更改,_bundle_会被重新编译。这个修改过的 bundle 是从内存里供应的,路径相对于指定的publicPath
参数(参见API)。它不会被写入配置的输出目录。相对于输出目录,当同样的路径上存在 _bundle_文件,内存中的 _bundle_会优先使用(默认)。
For example with the configuration above your bundle will be available at localhost:8080/assets/bundle.js
举个栗子,使用上面的配置,你的_bundle_可以从localhost:8080/assets/bundle.js
访问到。
To load your bundled files, you will need to create an index.html
file in the build
folder from which static files are served (--content-base
option). e.g:
为了加载打包了的文件,你需要在提供静态文件访问的build
目录(--content-base
选项)创建一个index.html
文件。譬如:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<script src="assets/bundle.js"></script>
</body>
</html>
By default go to localhost:8080/
to launch your app. For example with the configuration above (with publicPath) go to localhost:8080/assets/
.
默认情况下,访问localhost:8080/
可登陆你的应用。而结合上述的配置(带有publicPath),需访问localhost:8080/assets/
。
The webpack-dev-server supports multiple modes to automatic refresh the page:
_webpack-dev-server_支持多种模式来自动刷新页面
-
Iframe mode (page is embedded in an iframe and reloaded on change)
-
Inline mode (a small webpack-dev-server client entry is added to the bundle which refresh the page on change)
-
Iframe模式(页面被嵌入一个Iframe中,更新时重载)
-
内嵌模式(一个小型的webpack-dev-server的客户端入口被加入到打包文件,文件更新时重载页面)
Each mode also supports Hot Module Replacement in which the bundle is notified that a change happened instead of a full page reload. A Hot Module Replacement runtime could then load the updated modules and inject them into the running app.
每种模式都支持__模块热替换__——文件更新时前端会被通知,而不会整个页面重载。然后__模块热替换__的运行时会加载更新了的模块,并将其注入到运行中的app。
To use the iframe mode no additional configuration is needed. Just navigate the browser to http://<host>:<port>/webpack-dev-server/<path>
. I. e. with the above configuration http://localhost:8080/webpack-dev-server/index.html
.
使用Iframe模式不需要额外配置。只需在浏览器访问http://<host>:<port>/webpack-dev-server/<path>
。例如,使用上述的配置,就访问http://localhost:8080/webpack-dev-server/index.html
-
No configuration change needed.
-
Nice information bar on top of your app.
-
Url changes in the app are not reflected in the browsers url bar.
-
不需更改配置
-
应用顶部有个不错的信息栏
-
应用的页面地址变更不会被反映到浏览器地址栏
To use the inline mode, specify --inline
on the command line (you cannot specify it in the configuration). This adds the webpack-dev-server client entry point to the webpack configuration. There is no change in the url required. Just navigate to http://<host>:<port>/<path>
. I. e. with the above configuration http://localhost:8080/index.html
.
使用内嵌模式,命令行中指定--inline
(你不能在配置中指定)。这会将webpack-dev-server的客户端入口点加入到webpack的配置中。也不需要修改访问地址。只需访问http://<host>:<port>/<path>
。再次例如,使用上述的配置,访问http://localhost:8080/index.html
-
Command line flag needed.
-
Status information in the browser log.
-
Url changes in the app are reflected in the browsers url bar.
-
需要命令行标志
-
状态信息位于浏览器控制台
-
应用的页面地址变会被反映到浏览器地址栏
There is no inline: true
flag in the webpack-dev-server configuration, because the webpack-dev-server module has no access to the webpack configuration. Instead the user must add the webpack-dev-server client entry point to the webpack configuration.
在webpack-dev-server的配置中,没有inline: true
的选项。因为webpack-dev-server模块不能访问webpack的配置。相反,用户必须将webpack-dev-server的客户端入口点添加到webpack的配置中。
To do this just add webpack-dev-server/client?http://<path>:<port>/
to (all) entry point(s). I. e. with the above configuration:
要做到这一点只需为所有入口点(文件)添加webpack-dev-server/client?http://<path>:<port>/
。例如~,使用上述配置
var config = require("./webpack.config.js");
config.entry.app.unshift("webpack-dev-server/client?http://localhost:8080/");
var compiler = webpack(config);
var server = new webpackDevServer(compiler, {...});
server.listen(8080);
Note that many editors support "safe write" feature and have it enabled by default, which makes dev server unable to watch files correctly. "Safe write" means changes are not written directly to original file but to temporary one instead, which is renamed and replaces original file when save operation is completed successfully. This behaviour causes file watcher to lose the track because the original file is removed. In order to prevent this issue, you have to disable "safe write" feature in your editor.
要注意,很多编辑器支持“safe write”特性并默认开启,会导致 dev server 无法正确监听文件。“safe write”意味文件变更并没有直接写入源文件,而是一个临时文件,当成功保存后重命名并替换源文件。这种行为导致文件监听器失去对文件的跟踪,因为源文件被删除了。为了阻止这种问题,你需要关闭编辑器"safe write"的特性
-
VIM - set ":set backupcopy=yes" (see documentation)
-
IntelliJ - Settings -> System Settings -> Synchronization -> disable "safe write" (may differ in various IntelliJ IDEs, but you can still use the search feature)
-
VIM - 设置 ":set backupcopy=yes" (see documentation)
-
IntelliJ - Settings -> System Settings -> Synchronization -> disable "safe write" (可能在不同版本的 IntelliJ IDE 中有所不同,但你仍旧可以使用搜索功能)
There is also the option to add a reference to the webpack-dev-server client script to the HTML page: 也可以选择在HTML页面添加一个webpack-dev-server客户端脚本的引用:
<script src="http://localhost:8080/webpack-dev-server.js"></script>
To enable Hot Module Replacement with the webpack-dev-server specify --hot
on the command line. This adds the HotModuleReplacementPlugin
to the webpack configuration.
为了webpack-dev-server使用模块热替换,在命令行指定--hot
。这会将HotModuleReplacementPlugin
添加到webpack配置。
The easiest way to use Hot Module Replacement with the webpack-dev-server is to use the inline mode.
webpack-dev-server应用模块热替换最简单的方式是,使用内嵌模式。
Nothing more is needed. --inline --hot
does all the relevant work automatically. The CLI of the webpack-dev-server automatically adds the special webpack/hot/dev-server
entry point to your configuration.
无须折腾。--inline --hot
自动做了所有相关工作。webpack-dev-server的命令行接口自动将特定的webpack/hot/dev-server
添加到你的配置中。
Just navigate to http://<host>:<port>/<path>
and let the magic happen.
只需访问http://<host>:<port>/<path>
,见证奇迹的诞生。
You should see the following messages in the browser log:
你应该在浏览器控制台看到以下消息:
[HMR] Waiting for update signal from WDS...
[WDS] Hot Module Replacement enabled.
Messages prefixed with [HMR]
originate from the webpack/hot/dev-server
module. Messages prefixed with [WDS]
originate from the webpack-dev-server client.
以[HMR]
为前缀的信息来自webpack/hot/dev-server
模块,以[WDS]
为前缀的信息来自webpack-dev-server客户端模块,
It's important to specify a correct output.publicPath
otherwise the hot update chunks cannot be loaded.
重要的是指定一个有效的output.publicPath
,否则热更新的块无法被加载。
Similar to the inline mode the user must make changes to the webpack configuration.
与内嵌模式相似,用户必须修改webpack的配置。
Three changes are needed:
需要三项修改:
-
add an entry point to the webpack configuration:
webpack/hot/dev-server
. -
add the
new webpack.HotModuleReplacementPlugin()
to the webpack configuration. -
add
hot: true
to the webpack-dev-server configuration to enable HMR on the server. -
在webpack配置中添加一个入口点
webpack/hot/dev-server
-
在webpack配置中添加
new webpack.HotModuleReplacementPlugin()
-
在webpack-dev-server的配置中指定
hot: true
以开启HMR
I. e. with the above configuration:
例如,使用上述的配置:
var config = require("./webpack.config.js");
config.entry.app.unshift("webpack-dev-server/client?http://localhost:8080/", "webpack/hot/dev-server");
var compiler = webpack(config);
var server = new webpackDevServer(compiler, {
hot: true
...
});
server.listen(8080);
The Webpack dev server makes use of node-http-proxy to optionally proxy requests to a separate, possibly external, backend server. A sample configuration is below.
webpack dev server 可选择利用node-http-proxy来代理对一个独立的后端(外部?)服务器的请求。一个示例配置如下。
proxy: {
'/some/path*': {
target: 'https://other-server.example.com',
secure: false
}
}
See the node-http-proxy Options documentation for available configuration.
可用的配置参见node-http-proxy Options documentation
Proxying some URLs can be useful for a variety of configurations. One example is to serve JavaScript files and other static assets from the local development server but still send API requests to an external backend development server. Another example is splitting requests between two separate backend servers such as an authentication backend and a application backend.
对于各种配置,代理某些地址请求是有用的。一个例子是从本地开发服务器提供javascript等静态资源,但依然发送API请求到外部后端开发服务器。另一个例子是,两个独立的后端服务器之间请求的分割,如认证服务器和应用程序服务器。
(Added in v1.13.0.) The proxy can be optionally bypassed based on the return from a function. The function can inspect the HTTP request, response, and any given proxy options. It must return either false
or a URL path that will be served instead of continuing to proxy the request.
(在v1.13.0加入)代理可以根据一个函数的返回值选择性地绕过。函数可以检查HTTP的请求、响应及任何给定的代理选项。其必须返回false
或者一个会被处理的请求地址,而不是继续代理请求。
For example, the configuration below will not proxy HTTP requests that originate from a browser. This is similar to the historyApiFallback
option: browser requests will receive the HTML file as normal but API requests will be proxied to the backend server.
例如,下面的配置不会代理浏览器发起的HTTP请求。这跟historyApiFallback
选项相似:
proxy: {
'/some/path*': {
target: 'https://other-server.example.com',
secure: false,
bypass: function(req, res, proxyOptions) {
if (req.headers.accept.indexOf('html') !== -1) {
console.log('Skipping proxy for browser request.');
return '/index.html';
}
}
}
}
(Added in v???) The request to the proxy can be optionally rewritten by providing a function. The function can inspect and change the HTTP request.
(在v???加入)对代理的请求可以提供函数选择性地重写。函数可以检查和修改HTTP请求。
For example, the configuration below will rewrite the HTTP requests to remove the part /api
at the beginning of the URL.
例如,下面的配置将重写HTTP请求以将URL的开头去除/api
部分。
proxy: {
'/api/*': {
target: 'https://other-server.example.com',
rewrite: function(req) {
req.url = req.url.replace(/^\/api/, '');
}
}
}
It seems that node-http-proxy
pre-resolve the local hostnames into localhost
, you will need the following config to fix the proxy request
貌似node-http-proxy
将本地主机名预解析成localhost
,你需要下面的配置来修复代理请求。
var server = new webpackDevServer(compiler, {
quiet: false,
stats: { colors: true },
proxy: {
"/api": {
"target": {
"host": "action-js.dev",
"protocol": 'http:',
"port": 80
},
ignorePath: true,
changeOrigin: true,
secure: false
}
}
});
server.listen(8080);
$ webpack-dev-server <entry>
All webpack CLI options are valid for the webpack-dev-server CLI too, but there is no <output>
default argument. For the webpack-dev-server CLI a webpack.config.js
(or the file passed by the --config
option) is accepted as well.
所有 webpack 的CLI选项均在 webpack-dev-server CLI有效。但是<output>
没有默认参数。对于 webpack-dev-server CLI,webpack.config.js
(或者通过--config
选项传入的文件)同样会被接收处理。
There are some additional options:
下面是一些额外选项:
-
--content-base <file/directory/url/port>
: base path for the content. -
--quiet
: don't output anything to the console. -
--no-info
: suppress boring information. -
--colors
: add some colors to the output. -
--no-colors
: don't use colors in the output. -
--compress
: use gzip compression. -
--host <hostname/ip>
: hostname or IP.0.0.0.0
binds to all hosts. -
--port <number>
: port. -
--inline
: embed the webpack-dev-server runtime into the bundle. -
--hot
: adds theHotModuleReplacementPlugin
and switch the server to hot mode. Note: make sure you don't addHotModuleReplacementPlugin
twice. -
--hot --inline
also adds thewebpack/hot/dev-server
entry. -
--lazy
: no watching, compiles on request (cannot be combined with--hot
). -
--https
: serves webpack-dev-server over HTTPS Protocol. Includes a self-signed certificate that is used when serving the requests. -
--cert
,--cacert
,--key
: Paths the certificate files. -
--open
: opens the url in default browser (for webpack-dev-server versions > 2.0). -
--history-api-fallback
: enables support for history API fallback. -
--content-base <file/directory/url/port>
: 资源根路径 -
--quiet
: 不输出任何东西到控制台 -
--no-info
: 屏蔽多余的信息 -
--colors
: 输出带颜色的信息 -
--no-colors
: 输出信息不带颜色 -
--compress
: 使用 gzip 压缩. -
--host <hostname/ip>
: 主机名或IP -
--port <number>
: 端口 -
--inline
: 将 webpack-dev-server 运行时 嵌入 bundle. -
--hot
: 添加HotModuleReplacementPlugin
并 将服务器切换成 hot mode. 注意: 请确保你没有多次添加HotModuleReplacementPlugin
. -
--hot --inline
: 添加webpack/hot/dev-server
入口点. -
--lazy
: 无监视,按需编译(不能和--hot
结合使用). -
--https
: webpack-dev-server 使用 HTTPS 协议。包含一个自签名的证书,用于处理请求。 -
--cert
,--cacert
,--key
: 证书文件的路径. -
--open
: 在默认浏览器打开URL(对于 webpack-dev-server > 2.0). -
--history-api-fallback
: 开启对历史API兼容支持
When using the CLI it's possible to have the webpack-dev-server options in the configuration file under the key devServer
. Options passed via CLI arguments override options in configuration file. For options under devServer
see next section.
使用CLI时,有可能将webpack-dev-server的配置放在配置文件的devServer
属性下。通过CLI传入的选项会覆盖配置文件的选项。devServer
下的选项详情见下一节。
Example
module.exports = {
// ...
devServer: {
hot: true
}
}
var WebpackDevServer = require("webpack-dev-server");
var webpack = require("webpack");
var compiler = webpack({
// configuration
});
var server = new WebpackDevServer(compiler, {
// webpack-dev-server options
contentBase: "/path/to/directory",
// or: contentBase: "http://localhost/",
hot: true,
// Enable special support for Hot Module Replacement
// Page is no longer updated, but a "webpackHotUpdate" message is send to the content
// Use "webpack/hot/dev-server" as additional module in your entry point
// Note: this does _not_ add the `HotModuleReplacementPlugin` like the CLI option does.
// Set this as true if you want to access dev server from arbitrary url.
// This is handy if you are using a html5 router.
historyApiFallback: false,
// Set this if you want to enable gzip compression for assets
compress: true,
// Set this if you want webpack-dev-server to delegate a single path to an arbitrary server.
// Use "*" to proxy all paths to the specified server.
// This is useful if you want to get rid of 'http://localhost:8080/' in script[src],
// and has many other use cases (see https://github.com/webpack/webpack-dev-server/pull/127 ).
proxy: {
"*": "http://localhost:9090"
},
// pass [static options](http://expressjs.com/en/4x/api.html#express.static) to inner express server
staticOptions: {
},
// webpack-dev-middleware options
quiet: false,
noInfo: false,
lazy: true,
filename: "bundle.js",
watchOptions: {
aggregateTimeout: 300,
poll: 1000
},
publicPath: "/assets/",
headers: { "X-Custom-Header": "yes" },
stats: { colors: true }
});
server.listen(8080, "localhost", function() {});
// server.close();
See webpack-dev-middleware for documentation on middleware options. 查阅_webpack-dev-middleware_以了解中间件选项的文档
Notice that webpack configuration is not passed to WebpackDevServer
API, thus devServer
option in webpack configuration is not used in this case. Also, there is no inline mode for WebpackDevServer
API. <script src="http://localhost:8080/webpack-dev-server.js"></script>
should be inserted to HTML page manually.
注意_webpack的配置_没有被传给WebpackDevServer
的API,所以这个例子里webpack的配置中devServer
的选项没有用到。另外,WebpackDevServer
的API没有_内嵌模式_的配置。<script src="http://localhost:8080/webpack-dev-server.js"></script>
需要手动插入到HTML页面。
### historyApiFallback
选项
If you are using the HTML5 history API you probably need to serve your index.html
in place of 404 responses, which can be done by setting historyApiFallback: true
. However, if you have modified output.publicPath
in your Webpack configuration, you need to specify the URL to redirect to.
如果你在使用HTML5历史API,你可能需要用index.html
代替404响应,设置historyApiFallback: true
可以实现。不过,如果你修改过webpack配置中output.publicPath
,你需要指定重定向的URL。使用historyApiFallback.index
选项可以做到:
// output.publicPath: '/foo-app/'
historyApiFallback: {
index: '/foo-app/'
}
You may want to run a backend server or a mock of it in development. You should not use the webpack-dev-server as a backend. Its only purpose is to serve static (webpacked) assets.
开发时你可能需要运行一个后台服务器或一个模拟的服务器。你不应该使用_webpack-dev-server_作为后端。其唯一目的只是提供静态资源服务。
You can run two servers side-by-side: The webpack-dev-server and your backend server.
你可以同时运行两个服务器:_webpack-dev-server_和你自己的后端服务器。
In this case you need to teach the webpack-generated assets to make requests to the webpack-dev-server even when running on a HTML-page sent by the backend server. On the other side you need to teach your backend server to generate HTML pages that include script
tags that point to assets on the webpack-dev-server. In addition to that you need a connection between the webpack-dev-server and the webpack-dev-server runtime to trigger reloads on recompilation.
这种情况下,你需要指导webpack生成的资源向_webpack-dev-server_请求资源,即使其运行在由后端服务器发送的HTML页面。另一方面,你需要控制你的后端服务器在生成HTML页面时,包含script
标签来指向_webpack-dev-server_上的资源以及_webpack-dev-server_运行时以便重新编译后触发重载。
To teach webpack to make requests (for chunk loading or HMR) to the webpack-dev-server you need to provide a full URL in the output.publicPath
option.
为了指导_webpack_向_webpack-dev-server_发出请求(为了块的加载或者HMR),你需要在**output.publicPath
选项提供一个完整的路径**
To make a connection between webpack-dev-server and its runtime best, use the inline mode with --inline
. The webpack-dev-server CLI automatically includes an entry point which establishes a WebSocket connection. You can also use the iframe mode if you point --content-base
of the webpack-dev-server to your backend server. If you need a websocket connection to your backend server, you'll have to use iframe mode.
为了创建_webpack-dev-server_与其运行时之间的最佳连接,使用--inline
开启_内嵌模式_.
webpack-dev-server CLI自动一个会自动创建websocket连接的入口点。如果你将 _webpack-dev-server_的--content-base
指向你的后端服务器,你可以使用_iframe_模式。如果你需要使用websocket连接你的后端服务器,你将不得不使用iframe模式。
When you use the inline mode just open the backend server URL in your web browsers. (If you use the iframe mode open the /webpack-dev-server/
prefixed URL of the webpack-dev-server.)
当你使用_内嵌模式_,只需要在浏览器开启你后端服务器的地址。(如果你使用iframe模式,打开_webpack-dev-server_以/webpack-dev-server/
为前缀的地址。)
Summary and example: 总结并举例:
-
webpack-dev-server on port
8080
. - backend server on port
9090
. - generate HTML pages with
<script src="http://localhost:8080/assets/bundle.js">
. - webpack configuration with
output.publicPath = "http://localhost:8080/assets/"
. - when compiling files for production, use
--output-public-path /assets/
. -
inline mode:
-
--inline
. - open
http://localhost:9090
.
-
- or iframe mode:
-
webpack-dev-server
contentBase = "http://localhost:9090/"
(--content-base
). - open
http://localhost:8080/webpack-dev-server/
.
-
webpack-dev-server
Or use the proxy option...
- 端口
8080
开启_webpack-dev-server_ - 端口
9090
开启后端服务器 - 生成带有
<script src="http://localhost:8080/assets/bundle.js">
的HTML页面 - webpack配置包含
<script src="http://localhost:8080/assets/bundle.js">
- 当产品发布时编译文件,使用
--output-public-path /assets/
-
内嵌模式:
--inline
- 打开
http://localhost:9090
- 或者
iframe模式
:-
webpack-dev-server 配置
contentBase = "http://localhost:9090/"
(--content-base
) - 打开
http://localhost:8080/webpack-dev-server/
-
webpack-dev-server 配置
或者,使用代理选项...