webpack-dev-server

Posted Rank-Bill

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了webpack-dev-server相关的知识,希望对你有一定的参考价值。

本文翻译自(  https://wohugb.gitbooks.io/webpack/content/dev_tools/webpack-dev-server.html),感谢原网站整理提供的资源。

    webpack-dev-server 是一个小型的 Express(node.js)服务器,它可以通过配置webpack开发中间件来为项目服务。webpack-dev-server 通过Socket IO 可以保持服务端与客户端的运行时的状态。此时,服务端发送不同的编译状态给客户端,客户端会做出相应的反应。另外,webpack-dev-server可以配置不同的模式来自动更新页面。基本的配置如下:

var path = require("path");
module.exports = 
  entry: 
    app: ["./app/main.js"]
  ,
  output: 
    path: path.resolve(__dirname, "build"),
    publicPath: "/assets/",
    filename: "bundle.js"
  
;

Content Base(基本目录)

wepack-dev-server 通常默认当前目录,也可以配置其他的目录。(如下 可通过CLI的 --content-base更改目录)

$ webpack-dev-server --content-base public/

      webpack-dev-server 会监测文件是否变化,当监测到文件变化的时候 将会重新编译打包。这些变化的打包文件保存在内存中相对于publicPath的位置。需要注意的是,这些文件不会重写到磁盘的对应输出目录下。另外,默认情况下,如果在磁盘目录下已经存在了相同访问位置的打包文件,会优先选择内存中的打包文件(1.访问I/O操作耗时,2.便于开发环境下的实时热加载)。

通过上面的配置可以看出访问你的打包文件的目录时 localhost:8080/assets/bundle.js

为了引入打包的js文件,则需要在定义的根目录下通过index.html的文件引入,如下:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
</head>
<body>
  <script src="bundle.js"></script>
</body>
</html>

服务默认在 localhost:8080 启动。例如在上面的配置中 publicPath中 访问地址则为 localhost:8080/assets/ 

Automatic Refresh(自动更新)

webpack-dev-server 提供多种自动更新页面的模式:

  • iframe 模式(也及 页面被嵌入在 iframe中,在变化时会重新加载(reloaded) )
  • inline模式 ( 将webpack-dev-server 客户端入口 添加在打包文件中,当变化时更新页面 )

当打包文件监测到变化的时候,每一种模式均支持热加载。热加载会更新改变的部分 而不会重新的加载整个页面。

Iframe mode(iframe 模式)

       使用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.(url的变化不会显示在地址栏中)

Inline mode(inline 模式)

       使用inline模式可以在命令行中制定(注意的时不能在配置中指定inline模式)。这样会添加 webpack-dev-server 客户端入口点在 webpack的配置中。 只需访问 http://<host>:<port>/<path>,如http://localhost:8080/index.html。

  • Command line flag needed.(使用 --inline模式)
  • Status information in the browser log.(status信息会卸载浏览器的log中)
  • Url changes in the app are reflected in the browsers url bar.(url改变会反映在浏览器地址栏中)

Inline mode with node.js API(在node.js API 中使用inline模式)

在wepak-dev-server中没有配置inline:true的地方,因为webpack-dev-server没有访问webpack的配置,反而使用者需要将webpack-dev-server客户端entry 配置在webpack中。通过添加 webpack-dev-server/client?http://<path>:<port> 在entry 入口。


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);

Inline mode in HTML(inline 模式在inline)

可以将webpack-dev-server客户端 放在html页面的引用中:

<script src="http://localhost:8080/webpack-dev-server.js"></script>

Hot Module Replacement(热加载)

在命令行中 --hot 指定webpack-dev-server 来开启热加载。这样添加HotModuleReplacementPlugin在webpack的配置中。

最简单的使用热加载的方式即使用inline模式。

Hot Module Replacement with Inline mode on CLI(命令行)

废话不说。仅需要通过 --inline --hot 所有的相关的配置工作都会自动添加到运行时的环境中。使用命令行会自动添加webpack/hot/dev-server在entry中

访问地址 http://<host>:<port>/<path>

你将会看到一下信息在浏览器的log中

[HMR] Waiting for update signal from WDS...
[WDS] Hot Module Replacement enabled.

信息中以[HMR]就是来源于webpack/hot/dev-server module。[WDS]则来源自webpack-dev-server客户端

注意的是 指定正确的output.publicPath,否则热更新

Hot Module Replacement with node.js API

和inline模式的一样可以使用node.js API中配置 热加载

Three changes are needed:(三个注意点)

  • 在webpack中配置 entry point:webpack/hot/dev-server
  • webpack配置中 添加 new webpack.HotModuleReplacementPlugin()
  • 在webpack-dev-server添加hot:true 开启热加载

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);

Proxy(代理)

Webpack dev服务器使用node-http-proxy 将请求代理到独立的(可能是外部的)后端服务器。如下



    devServer: 
        proxy: 
            '/some/path*': 
                target: 'https://other-server.example.com',
                secure: false,
            ,
        ,
    ,

See the node-http-proxy Options documentation for available configuration.(node-http-proxyAPI链接文档)

代理一些URLs对各种各样的配置很有用。一个例子是 js文件和其他 的静态文件在本地的开发环境,但是从后端服务器上请求一些API的方法。另一种例子是 可以分离不同的后端请求,例如权限鉴定的后台 与 偏应用的后台

Bypass the Proxy (绕过代理)

(v1.13.0 新增) 代理可以根据函数的返回来选择性地绕过。该函数可以检查HTTP请求、响应和任何给定的代理选项。它必须返回false或URL路径,而不是继续代理请求。

例如,下面的配置将不会代理来自浏览器的HTTP请求。这类似于historyApiFallback选项:浏览器请求将像往常一样接收HTML文件,但API请求将被代理到后端服务器。



    devServer: 
        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';
                    
                ,
            ,
        ,
    ,

webpack-dev-server CLI(命令行)

$ webpack-dev-server <entry>

所有的webpack命令行 适用于webpack-dev-server,但是没有默认的 output 参数。一个 webpack.config.js文件在命令行中也是被接受的 (or the file passed by the --config option) 

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 used colors in the output.
  • --host <hostname/ip>: hostname or IP.(主机名或IP)
  • --port <number>: port.(端口)
  • --inline: embed the webpack-dev-server runtime into the bundle.
  • --hot: adds the HotModuleReplacementPlugin and switch the server to hot mode. Note: make sure you don't add HotModuleReplacementPlugin twice.
  • --hot --inline also adds the webpack/hot/dev-server entry.
  • --lazy: no watching, compiles on request (cannot be combined with --hot).
  • --https: serves webpack-dev-server over HTTPS Protocol.(HTTPS 协议) Includes a self-signed certificate that is used when serving the requests.
  • --cert--cacert--key: Paths the certificate files.

在devServer的webpack.config.js中的配置将会和命令行的选项合并。

API

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 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"
  ,

  // 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();

注意 wepack的配置不会出传递到WebpackDevServer API中,这样webpack配置中 devServer 选项在这种情况下没有用到。同时没有配置inline模式在WebpackDevServer中 需要手动的在HTML文件中添加webpack-dev-server中<script src="http://localhost:8080/webpack-dev-server.js"></script>

Combining with an existing server(结合已有的服务)

你也许希望跑一个后台服务或一个开发阶段的模拟服务器。最好不使用webpack-dev-server作为后台服务。webpack-dev-server主要用于处理静态资源。

你可以同时运行两个服务器,webpack-dev-server和后端服务器。

在这种情况下,你需要教会webpack 生成资源,发送到webpack-dev-server 甚至有后台发布的HTML-page。换一种说法是,需要使后台服务生成HTML 页面中script中标签 指向 webpack-dev-server的资源。除此之外,你需要建立在webpack-dev-server与webpack-dev-server 运行时之间的联系,以便触发在重新编译的时候更新。 

webpack产生对webpack-dev-server请求(例如模块加载或热加载),需要在output.publicPath选项提供完整的URL

在webpack-dev-server与其运行时建立连接最好的是使用--inline的模式。web-dev-server CLI自动加入一个入口点,该入口点建立一个WebSocket连接。

如果需要在webpack-dev-server配置--content-base只想后端服务,这种情况可以使用iframe模式。如果需要与后台服务建立websocket连接,你需要使用iframe模式。

当你使用inline模式的时候只需要在浏览器中打开后台的url即可(如果使用iframe模式,/webpack-dev-server/前缀URL)。

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/.

Or use the proxy option...


以上是关于webpack-dev-server的主要内容,如果未能解决你的问题,请参考以下文章

webpack-dev-server 安装的版本问题

webpack-dev-server报错

未找到 webpack-dev-server 命令

需要安装'webpack-dev-server'

webpack-dev-server --打开特定路径?

运行webpack-dev-server遇到的问题