Webpack 中文文档(v4.15.1) 目录

webpack 迁移到新版本

以下各节描述从 webpack 1 到 webpack 2 的重大变化。

T> webpack 从 1 到 2 的变化,比从 2 到 3 要少很多,所以版本迁移起来难度应该不大。如果你遇到了问题,请查看 更新日志 以了解更多细节。

W> 随着 webpack 2 版本已经发布一段时间,此章节的内容可能会在不久的将来被转移到博客文章中。最重要的是,webpack 3 版本最近发布,webpack 4 版本即将发布。如上所述,大家最好是参考 更新日志 去进行相应的版本迁移。

resolve.root, resolve.fallback, resolve.modulesDirectories

这些选项被一个单独的选项 resolve.modules 取代。更多用法请查看解析。

  -------- -
-   ----- -------------------- ------
-   -------- -
-     -------------------- -------
-     --------------
-   -
  -

resolve.extensions

此选项不再需要传一个空字符串。此行为被迁移到 resolve.enforceExtension。更多用法请查看解析。

resolve.*

这里更改了几个 API。由于不常用,不在这里详细列出。更多用法请查看解析。

module.loaders 改为 module.rules

旧的 loader 配置被更强大的 rules 系统取代,后者允许配置 loader 以及其他更多选项。 为了兼容旧版,module.loaders 语法仍然有效,旧的属性名依然可以被解析。 新的命名约定更易于理解,并且是升级配置使用 module.rules 的好理由。

  ------- -
-   -------- -
-   ------ -
      -
        ----- ---------
-       -------- -
-         ---------------
-         -------------------------
-       ---- -
-         -
-           ------- --------------
-         --
-         -
-           ------- -------------
-           -------- -
-             -------- ----
-           -
-         -
        -
      --
      -
        ----- ---------
        ------- --------------- -- ------ -----
        -------- -
          -- ---
        -
      -
    -
  -

链式 loader

就像在 webpack 1 中,loader 可以链式调用,上一个 loader 的输出被作为输入传给下一个 loader。 使用 rule.use 配置选项,use 可以设置为一个 loader 数组。 在 webpack 1 中,loader 通常被用 ! 连写。这一写法在 webpack 2 中只在使用旧的选项 module.loaders 时才有效。

  ------- -
-   -------- --
-   ------ --
      ----- ----------
-     ------- -------------------------------------
-     ---- -
-       ---------------
-       -------------
-       -------------
-     -
    --
  -

取消「在模块名中自动添加 -loader 后缀」

在引用 loader 时,不能再省略 -loader 后缀了:

  ------- -
    ------ -
      -
        ---- -
-         --------
-         ---------------
-         ------
-         -------------
-         -------
-         --------------
        -
      -
    -
  -

你仍然可以通过配置 resolveLoader.moduleExtensions 配置选项,启用这一旧有行为,但是我们不推荐这么做。

- -------------- -
-   ----------------- -----------
- -

了解这一改变背后的原因,请查看 #2986

json-loader 不再需要手动添加

如果没有为 JSON 文件配置 loader,webpack 将自动尝试通过 json-loader 加载 JSON 文件。

  ------- -
    ------ -
-     -
-       ----- ---------
-       ------- -------------
-     -
    -
  -

我们决定这么做是为了消除 webpack、 node.js 和 browserify 之间的环境差异。

配置中的 loader 默认相对于 context 进行解析

webpack 1 中,默认配置下 loader 解析相对于被匹配的文件。然而,在 webpack 2 中,默认配置下 loader 解析相对于 context 选项。

这解决了「在使用 npm link 或引用 context 上下文目录之外的模块时,loader 所导致的模块重复载入」的问题。

你可以移除掉那些为解决此问题的 hack 方案了:

  ------- -
    ------ -
      -
        -- ---
-       ------- ----------------------------
-       ------- -----------
      -
    -
  --
  -------------- -
-   ----- ----------------------- ---------------
  -

移除 module.preLoadersmodule.postLoaders

  ------- -
-   ----------- -
-   ------ -
      -
        ----- --------
-       -------- ------
        ------- ---------------
      -
    -
  -

UglifyJsPlugin sourceMap

UglifyJsPluginsourceMap 选项现在默认为 false 而不是 true。这意味着如果你在压缩代码时启用了 source map,或者想要让 uglifyjs 的警告能够对应到正确的代码行,你需要将 UglifyJsPluginsourceMap 设为 true

  -------- -------------
  -------- -
    --- ----------------
-     ---------- ----
    --
  -

UglifyJsPlugin warnings

UglifyJsPlugincompress.warnings 选项现在默认为 false 而不是 true。 这意味着如果你想要看到 uglifyjs 的警告信息,你需要将 compress.warnings 设为 true

  -------- -------------
  -------- -
    --- ----------------
-     --------- -
-       --------- ----
-     -
    --
  -

UglifyJsPlugin 压缩 loaders

UglifyJsPlugin 不再压缩 loaders。在未来很长一段时间里,需要通过设置 minimize:true 来压缩 loaders。参考 loader 文档里的相关选项。

loaders 的压缩模式将在 webpack 3 或后续版本中取消。

为了兼容旧的 loaders,loaders 可以通过插件来切换到压缩模式:

  -------- -
-   --- -----------------------------
-     --------- ----
-   --
  -

移除 DedupePlugin

不再需要 webpack.optimize.DedupePlugin。请从配置中移除。

BannerPlugin - 破坏性改动

BannerPlugin 不再接受两个参数,而是只接受单独的 options 对象。

  -------- -
-    --- ------------------------------ ----- ----- ---------- ------
-    --- ----------------------------- --------- ---- ----- ---------- ------
  -

默认加载 OccurrenceOrderPlugin

OccurrenceOrderPlugin 现在默认启用,并已重命名(在 webpack 1 中为 OccurenceOrderPlugin)。 因此,请确保从你的配置中删除该插件:

  -------- -
    -- ------- -
-   --- ---------------------------------------
    -- ------- -
-   --- ----------------------------------------
  -

ExtractTextWebpackPlugin - 破坏性改动

ExtractTextPlugin 需要使用版本 2,才能在 webpack 2 下正常运行。

npm install --save-dev extract-text-webpack-plugin

这一插件的配置变化主要体现在语法上。

ExtractTextPlugin.extract

------- -
  ------ -
    -
      ----- --------
-      ------- ----------------------------------------- ------------- - ----------- ------- --
-      ---- ---------------------------
-        --------- ---------------
-        ---- -------------
-        ----------- -------
-      --
    -
  -
-

new ExtractTextPlugin({options})

-------- -
-  --- ------------------------------- - ---------- ----- -------- ----- --
-  --- -------------------
-    --------- -------------
-    -------- ------
-    ---------- ----
-  --
-

全动态 require 现在默认会失败

只有一个表达式的依赖(例如 require(expr))将创建一个空的 context 而不是一个完整目录的 context。

这样的代码应该进行重构,因为它不能与 ES2015 模块一起使用。如果你确定不会有 ES2015 模块,你可以使用 ContextReplacementPlugin 来指示 compiler 进行正确的解析。

?> Link to an article about dynamic dependencies.

在 CLI 和配置中使用自定义参数

如果你之前滥用 CLI 来传自定义参数到配置中,比如:

webpack --custom-stuff

-- -----------------
--- ----------- - -------------------------------------- -- -
-- --- --
-------------- - ------

你将会发现新版中不再允许这么做。CLI 现在更加严格了。

替代地,现在提供了一个接口来传递参数给配置。我们应该采用这种新方式,在未来许多工具将可能依赖于此。

webpack --env.customStuff

-------------- - ------------- -
  --- ----------- - ---------------
  -- --- --
  ------ ------
-

详见 CLI。

require.ensure 以及 AMD require 将采用异步式调用

现在这些函数总是异步的,而不是当 chunk 已经加载完成的时候同步调用它们的回调函数(callback)。

require.ensure 现在依赖于原生的 Promise。如果在不支持 Promise 的环境里使用 require.ensure,你需要添加 polyfill。

通过 options 配置 loader

你不能再通过 webpack.config.js 的自定义属性来配置 loader。只能通过 options 来配置。下面配置的 ts 属性在 webpack 2 下不再有效:

-------------- - -
  ---
  ------- -
    ------ --
      ----- ----------
      ------- -----------
    --
  --
  -- - ------- - ---
  --- - -------------- ----- -
-

什么是 options?

好问题。严格来说,有两种办法,都可以用来配置 webpack 的 loader。典型的 options 被称为 query,是一个可以被添加到 loader 名之后的字符串。它比较像一个 query string,但是实际上有更强大的能力

-------------- - -
  ---
  ------- -
    ------ --
      ----- ----------
      ------- ------------ - ---------------- -------------- ----- --
    --
  -
-

不过它也可以分开来,写成一个单独的对象,紧跟在 loader 属性后面:

-------------- - -
  ---
  ------- -
    ------ --
      ----- ----------
      ------- ------------
      --------  - -------------- ----- -
    --
  -
-

LoaderOptionsPlugin context

有的 loader 需要从配置中读取一些 context 信息。在未来很长一段时间里,这将需要通过 loader options 传入。详见 loader 文档的相关选项。

为了保持对旧 loaders 的兼容,这些信息可以通过插件传进来:

  -------- -
-   --- -----------------------------
-     -------- -
-       -------- ---------
-     -
-   --
  -

debug

在 webpack 1 中 debug 选项可以将 loader 切换到调试模式(debug mode)。在未来很长一段时间里,这将需要通过 loader 选项传递。详见 loader 文档的相关选项。

loaders 的调试模式将在 webpack 3 或后续版本中取消。

为了保持对旧 loaders 的兼容,loader 可以通过插件来切换到调试模式:

- ------ -----
  -------- -
-   --- -----------------------------
-     ------ ----
-   --
  -

ES2015 的代码分割

在 webpack 1 中,可以使用 require.ensure作为实现应用程序的懒加载 chunks 的一种方法:

------------------ ----------------- -
  --- --- - -------------------
--

ES2015 模块加载规范定义了 import() 方法,可以在运行时(runtime)动态地加载 ES2015 模块。webpack 将 import() 作为分割点(split-point)并将所要请求的模块(requested module)放置到一个单独的 chunk 中。import() 接收模块名作为参数,并返回一个 Promise。

-------- --------- -
  ------------------------------ -- -
    ------ --------------
  ------------ -- -
    ------------------ ------- --------
  --
-

好消息是:如果加载 chunk 失败,我们现在可以进行处理,因为现在它基于 Promise

动态表达式

可以传递部分表达式给 import()。这与 CommonJS 对表达式的处理方式一致(webpack 为所有可能匹配的文件创建 context)。

import() 为每一个可能的模块创建独立的 chunk。

-------- ----------- ------ -
  ------ --------------------------------
    ----------- -- --- -------------------
-
-- ----------------- -----

混合使用 ES2015、AMD 和 CommonJS

你可以自由混合使用三种模块类型(甚至在同一个文件中)。在这个情况中 webpack 的行为和 babel 以及 node-eps 一致:

-- -------- -- ------ --
--- ---- - -----------------

----------------
---------------
------------ --- ----- -- - -----
-- ------ ---- --------
------ -- ---- ---- -- -------------- --- -------
------ - ------------ - ---- ---- -- -------------- ------------------------ --------

--- --------------- --- ----------
--- ------------ --- ----------

值得注意的是,你需要让 Babel 不解析这些模块符号,从而让 webpack 可以使用它们。你可以通过设置如下配置到 .babelrc 或 babel-loader 来实现这一点。

.babelrc

-
  ---------- -
    ---------- - ---------- ----- --
  -
-

Hints

不需要改变什么,但有机会改变。

模板字符串

webpack 现在支持表达式中的模板字符串了。这意味着你可以在 webpack 构建中使用它们:

- ---------------------- - -----
- ------------------------------

配置中使用 Promise

webpack 现在支持在配置文件中返回 Promise 了。这让你能在配置文件中做异步处理。

webpack.config.js

-------------- - ---------- -
  ------ ---------------------- -- --
    ------ ------
    -- ---
    -------- -
      --- -------------- --------- ---- --
    -
  ---
-

高级 loader 匹配

webpack 现在支持对 loader 进行更多方式的匹配。

------- -
  ------ -
    -
      --------- ----------- -- -- -------------------
      -------------- ------------------ -- -- --------------
      ------- ----------- -- ---- ------------------- --- --------------------
    -
  -
-

更多的 CLI 参数项

你可以使用一些新的 CLI 参数项:

--define process.env.NODE_ENV="production"DefinePlugin

--display-depth 显示每个模块到入口的距离。

--display-used-exports 显示一个模块中被使用的 exports 信息。

--display-max-modules 设置输出时显示的模块数量(默认是 15)。

-p 能够定义 process.env.NODE_ENV"production"

Loader 变更

以下变更仅影响 loader 的开发者。

Cacheable

Loaders 现在默认可被缓存。Loaders 如果不想被缓存,需要选择不被缓存。

  -- -- ------
  -------------- - ---------------- -
-   ----------------
    ------ ------
  -
  -- --- ------
  -------------- - ---------------- -
-   ---------------------
    ------ ------
  -

复合 options

webpack 1 只支持能够「可 JSON.stringify的对象」作为 loader 的 options。

webpack 2 现在支持任意 JS 对象作为 loader 的 options.

webpack 2.2.1之前(即从 2.0.0 到 2.2.0),使用复合 options,需要在 options 对象上添加 ident,允许它能够被其他 loader 引用。这在 2.2.1 中被删除,因此目前的迁移不再需要使用 ident 键。

-
  ----- -------
  ---- -
    ------- ------
    -------- -
-     ------ -----
      --- -- -- -------------------
    -
  -
-

上一篇:TypeScript
下一篇:使用环境变量