以下部分介绍了 webpack 1 到 2 的主要变化。
这些选项已被单个选项 resolve.modules
替换。有关更多用法,请参阅 解析。
resolve: {
- root: path.join(__dirname, "src")
+ modules: [
+ path.join(__dirname, "src"),
+ "node_modules"
+ ]
}
此选项不再需要传递空字符串。此行为已移至 resolve.enforceExtension
。有关更多用法,请参阅 解析。
此处更改了多个 API。未详细列出,因为它不常用。有关详细信息,请参阅 解析。
旧的加载器配置已被更强大的规则系统取代,该系统允许配置加载器等更多内容。出于兼容性考虑,旧的 module.loaders
语法仍然有效,并且旧名称已被解析。新的命名约定更容易理解,并且是使用 module.rules
升级配置的一个很好的理由。
module: {
- loaders: [
+ rules: [
{
test: /\.css$/,
- loaders: [
- "style-loader",
- "css-loader?modules=true"
+ use: [
+ {
+ loader: "style-loader"
+ },
+ {
+ loader: "css-loader",
+ options: {
+ modules: true
+ }
+ }
]
},
{
test: /\.jsx$/,
loader: "babel-loader", // Do not use "use" here
options: {
// ...
}
}
]
}
与 webpack 1 中一样,可以链接加载器以将结果从一个加载器传递到另一个加载器。使用 rule.use 配置选项,可以将 use
设置为加载器数组。在 webpack 1 中,加载器通常使用 !
链接。仅使用旧选项 module.loaders
支持此样式。
module: {
- loaders: [{
+ rules: [{
test: /\.less$/,
- loader: "style-loader!css-loader!less-loader"
+ use: [
+ "style-loader",
+ "css-loader",
+ "less-loader"
+ ]
}]
}
-loader
模块名称扩展已删除引用加载器时不再可以省略 -loader
扩展名
module: {
rules: [
{
use: [
- "style",
+ "style-loader",
- "css",
+ "css-loader",
- "less",
+ "less-loader",
]
}
]
}
您仍然可以使用 resolveLoader.moduleExtensions
配置选项选择旧行为,但不建议这样做。
+ resolveLoader: {
+ moduleExtensions: ["-loader"]
+ }
请参阅 #2986 了解此更改的原因。
如果没有为 JSON 文件配置加载器,webpack 将自动尝试使用 json-loader
加载 JSON 文件。
module: {
rules: [
- {
- test: /\.json/,
- loader: "json-loader"
- }
]
}
我们决定这样做 以消除 webpack、node.js 和 browserify 之间的环境差异。
在 webpack 1 中,配置的加载器相对于匹配的文件进行解析。但是,在 webpack 2 中,配置的加载器相对于 context
选项进行解析。
这解决了一些由加载器导致的重复模块问题,例如在使用 npm link
或引用 context
之外的模块时。
您可以删除一些解决此问题的技巧
module: {
rules: [
{
// ...
- loader: require.resolve("my-loader")
+ loader: "my-loader"
}
]
},
resolveLoader: {
- root: path.resolve(__dirname, "node_modules")
}
module: {
- preLoaders: [
+ rules: [
{
test: /\.js$/,
+ enforce: "pre",
loader: "eslint-loader"
}
]
}
UglifyJsPlugin
的 sourceMap
选项现在默认为 false
,而不是 true
。这意味着如果你正在为最小化代码使用源映射,或者想要 uglifyjs 警告的正确行号,你需要为 UglifyJsPlugin
设置 sourceMap: true
。
devtool: "source-map",
plugins: [
new UglifyJsPlugin({
+ sourceMap: true
})
]
UglifyJsPlugin
的 compress.warnings
选项现在默认为 false
,而不是 true
。这意味着如果你想要看到 uglifyjs 警告,你需要将 compress.warnings
设置为 true
。
devtool: "source-map",
plugins: [
new UglifyJsPlugin({
+ compress: {
+ warnings: true
+ }
})
]
UglifyJsPlugin
不再将加载器切换到最小化模式。minimize: true
设置需要通过加载器选项长期传递。有关相关选项,请参阅加载器文档。
加载器的最小化模式将在 webpack 3 或更高版本中移除。
为了保持与旧加载器的兼容性,可以通过插件将加载器切换到最小化模式
plugins: [
+ new webpack.LoaderOptionsPlugin({
+ minimize: true
+ })
]
webpack.optimize.DedupePlugin
不再需要。从你的配置中移除它。
BannerPlugin
不再接受两个参数,而是一个单一选项对象。
plugins: [
- new webpack.BannerPlugin('Banner', {raw: true, entryOnly: true});
+ new webpack.BannerPlugin({banner: 'Banner', raw: true, entryOnly: true});
]
OccurrenceOrderPlugin
现在默认启用,并且已重命名(在 webpack 1 中为 OccurenceOrderPlugin
)。因此,请确保从你的配置中移除该插件
plugins: [
// webpack 1
- new webpack.optimize.OccurenceOrderPlugin()
// webpack 2
- new webpack.optimize.OccurrenceOrderPlugin()
]
ExtractTextPlugin 需要版本 2 才能与 webpack 2 配合使用。
npm install --save-dev extract-text-webpack-plugin
此插件的配置更改主要是语法上的。
module: {
rules: [
{
test: /.css$/,
- loader: ExtractTextPlugin.extract("style-loader", "css-loader", { publicPath: "/dist" })
+ use: ExtractTextPlugin.extract({
+ fallback: "style-loader",
+ use: "css-loader",
+ publicPath: "/dist"
+ })
}
]
}
new ExtractTextPlugin({options})
plugins: [
- new ExtractTextPlugin("bundle.css", { allChunks: true, disable: false })
+ new ExtractTextPlugin({
+ filename: "bundle.css",
+ disable: false,
+ allChunks: true
+ })
]
仅包含表达式的依赖项(即 require(expr)
)现在将创建一个空上下文,而不是完整目录的上下文。
此类代码应重构,因为它不适用于 ES2015 模块。如果无法执行此操作,则可以使用 ContextReplacementPlugin
向编译器提示正确的解析。
如果您滥用 CLI 将自定义参数传递给配置,如下所示
webpack --custom-stuff
// webpack.config.js
var customStuff = process.argv.indexOf('--custom-stuff') >= 0;
/* ... */
module.exports = config;
您可能会注意到不再允许这样做。CLI 现在更加严格。
相反,有一个用于将参数传递给配置的界面。应改用此界面。未来的工具可能依赖于此。
webpack --env.customStuff
module.exports = function (env) {
var customStuff = env.customStuff;
/* ... */
return config;
};
请参阅 CLI。
如果已加载块,这些函数现在始终是异步的,而不是同步调用其回调。
require.ensure
现在依赖于本机 Promise
。如果在缺少本机 Promise
的环境中使用 require.ensure
,则需要一个垫片。
options
您不再可以在 webpack.config.js
中使用自定义属性配置加载器。必须通过 options
来完成。在 webpack 2 中,具有 ts
属性的以下配置不再有效
module.exports = {
//...
module: {
rules: [
{
test: /\.tsx?$/,
loader: 'ts-loader',
},
],
},
// does not work with webpack 2
ts: { transpileOnly: false },
};
options
?好问题。严格来说,它有 2 种可能;两种方法都可以配置 webpack 加载器。传统上,options
称为 query
,它是一个字符串,可以附加到加载器的名称上。非常像查询字符串,但实际上具有 更强大的功能
module.exports = {
//...
module: {
rules: [
{
test: /\.tsx?$/,
loader: 'ts-loader?' + JSON.stringify({ transpileOnly: false }),
},
],
},
};
但它也可以是一个单独指定的对象,该对象与加载器一起提供
module.exports = {
//...
module: {
rules: [
{
test: /\.tsx?$/,
loader: 'ts-loader',
options: { transpileOnly: false },
},
],
},
};
一些加载器需要上下文信息并从配置中读取它们。从长远来看,这需要通过加载器选项传递。有关相关选项,请参阅加载器文档。
为保持与旧加载器的兼容性,此信息可以通过插件传递
plugins: [
+ new webpack.LoaderOptionsPlugin({
+ options: {
+ context: __dirname
+ }
+ })
]
在 webpack 1 中,debug
选项将加载器切换到调试模式。这需要通过加载器选项长期传递。有关相关选项,请参阅加载器文档。
在 webpack 3 或更高版本中,将删除加载器的调试模式。
为保持与旧加载器的兼容性,可以通过插件将加载器切换到调试模式
- debug: true,
plugins: [
+ new webpack.LoaderOptionsPlugin({
+ debug: true
+ })
]
在 webpack 1 中,您可以使用 require.ensure()
作为一种方法,为您的应用程序延迟加载块
require.ensure([], function (require) {
var foo = require('./module');
});
ES2015 加载器规范将 import()
定义为一种方法,用于在运行时动态加载 ES2015 模块。Webpack 将 import()
视为拆分点,并将请求的模块放入单独的块中。import()
将模块名称作为参数并返回一个 Promise。
function onClick() {
import('./module')
.then((module) => {
return module.default;
})
.catch((err) => {
console.log('Chunk loading failed');
});
}
好消息:现在可以处理加载块失败,因为它们基于 Promise
。
可以将部分表达式传递给 import()
。这与 CommonJS 中的表达式类似(Webpack 创建一个包含所有可能文件的 上下文)。
import()
为每个可能的模块创建一个单独的块。
function route(path, query) {
return import(`./routes/${path}/route`).then(
(route) => new route.Route(query)
);
}
// This creates a separate chunk for each possible route
对于 AMD 和 CommonJS,您可以自由混合所有三种模块类型(甚至在同一文件中)。在这种情况下,Webpack 的行为类似于 babel 和 node-eps
// CommonJS consuming ES2015 Module
var book = require('./book');
book.currentPage;
book.readPage();
book.default === 'This is a book';
// ES2015 Module consuming CommonJS
import fs from 'fs'; // module.exports map to default
import { readFileSync } from 'fs'; // named exports are read from returned object+
typeof fs.readFileSync === 'function';
typeof readFileSync === 'function';
重要的是要注意,您需要告诉 Babel 不要解析这些模块符号,以便 Webpack 可以使用它们。您可以通过在 .babelrc
或 babel-loader
选项中设置以下内容来执行此操作。
.babelrc
{
"presets": [["es2015", { "modules": false }]]
}
无需更改任何内容,但有以下机会
Webpack 现在支持表达式中的模板字符串。这意味着您可以在 webpack 构造中开始使用它们
- require("./templates/" + name);
+ require(`./templates/${name}`);
Webpack 现在支持从配置文件返回 Promise
。这允许在您的配置文件中进行异步处理。
webpack.config.js
module.exports = function () {
return fetchLangs().then((lang) => ({
entry: '...',
// ...
plugins: [new DefinePlugin({ LANGUAGE: lang })],
}));
};
Webpack 现在支持更多内容以匹配加载器。
module.exports = {
//...
module: {
rules: [
{
resource: /filename/, // matches "/path/filename.js"
resourceQuery: /^\?querystring$/, // matches "?querystring"
issuer: /filename/, // matches "/path/something.js" if requested from "/path/filename.js"
},
],
},
};
有一些新的 CLI 选项可供你使用
--define process.env.NODE_ENV="production"
请参阅 DefinePlugin
。
--display-depth
显示每个模块到入口点的距离。
--display-used-exports
显示有关模块中使用哪些导出的信息。
--display-max-modules
设置输出中显示的模块数(默认为 15)。
-p
现在还将 process.env.NODE_ENV
定义为 "production"
。
仅与加载器作者相关的更改。
现在加载器默认可缓存。如果加载器不可缓存,则必须选择退出。
// Cacheable loader
module.exports = function(source) {
- this.cacheable();
return source;
}
// Not cacheable loader
module.exports = function(source) {
+ this.cacheable(false);
return source;
}
webpack 1 仅支持加载器的 JSON.stringify
可用选项。
webpack 2 现在支持任何 JS 对象作为加载器选项。
在 webpack 2.2.1 之前(即从 2.0.0 到 2.2.0),使用复杂选项需要为 options
对象使用 ident
以允许其他加载器引用它。这已在 2.2.1 中移除,因此当前迁移不需要使用 ident
键。
{
test: /\.ext/
use: {
loader: '...',
options: {
- ident: 'id',
fn: () => require('./foo.js')
}
}
}