模式(mode)配置选项是从Webpack4引入的参数。用来告知webpack使用相应环境的内置优化。可能的值有:none, development 或 production,如果没有设置,webpack会将mode的默认值设置为production。
mode用法
只需在配置对象中提供 mode 选项:
module.exports = {
mode: 'production'
};
或者从 CLI 参数中传递:
webpack --mode=production
支持以下字符串值:
选项 | 描述 |
---|---|
development | 会将 DefinePlugin 中 process.env.NODE_ENV 的值设置为 development。启用 NamedChunksPlugin 和 NamedModulesPlugin。 |
production | 会将 DefinePlugin 中 process.env.NODE_ENV 的值设置为 production。启用 FlagDependencyUsagePlugin, FlagIncludedChunksPlugin, ModuleConcatenationPlugin, NoEmitOnErrorsPlugin, OccurrenceOrderPlugin, SideEffectsFlagPlugin 和 TerserPlugin。 |
none | 退出任何默认优化选项 |
注意:设置 NODE_ENV 并不会自动地设置mode。
production生产环境中的内置优化(optimization)
UglifyJsPlugin
UglifyJsPlugin可以压缩和缩小代码来缩短代码的长度。如缩短变量名和删除空白到删除冗余代码。默认情况下,它将解析每个.js文件。
webpack.config.js
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
module.exports = {
mode: "production",
// using mode: "production" attaches the following configuration:
optimization: {
minimize: true,
minimizer: [
new UglifyJsPlugin()
]
},
}
您还可以传递给UglifyJsPlugin最重要的属性uglifyOptions。它有很多默认配置。最值得注意的部分之一是compress压缩属性。
new UglifyJsPlugin({
uglifyOptions: {
compress: {
drop_console:true
/*(...)*/
}
}
})
compress压缩属性中的drop_console属性您也可以考虑一下,drop_console默认情况下设置为false。将其更改为true将清除所有console.log调用。
UglifyJsPlugin配置的另一个重要属性是output输出:
new UglifyJsPlugin({
uglifyOptions: {
compress: {
/*(...)*/
},
output: {
/*(...)*/
}
}
})
uglifyOptions负责配置许多由uglifyjsplugin完成的关于使代码更短、更轻的繁重工作。要获得完整的可能选项列表,请查看官方列表。
DefinePlugin
此插件允许您创建在编译时解析的全局常量。如果你使用mode :“production”,webpack将默认设置“process.env.NODE_ENV” :JSON 。stringify (“production” ):
webpack.config.js
module.exports = {
mode: "production",
// using mode: "production" attaches the following configuration:
plugins: [
new webpack.DefinePlugin({
"process.env.NODE_ENV": JSON.stringify("production")
}),
]
}
注意,由于直接替换文本,给属性的值必须包含实际引号。这可以通过JSON.stringify("production")或'"production"'。
在编译时解析它意味着如果您在代码中使用process.env.NODE_ENV,它将被值生成替换。
console.log(process.env.NODE_ENV);
if(process.env.NODE_ENV === 'production') {
console.log('this is production!')
}
请记住,process.env.node_env值在编译代码后不会保留。使用Webpack运行上述代码将导致:
console.log("production");
if(true) {
console.log("this is production!")
}
通过uglifyjsplugin缩小后,可以简化。
console.log("production");
console.log("this is production!")
NoEmitOnErrorsPlugin
使用这个插件将帮助您处理编译过程中的错误。例如您可能会尝试导入Webpack无法解析的文件。在这种情况下,Webpack会创建一个新版本的应用程序,其中包含有关错误的信息。使用noemitonerrorsplugin时,根本不会创建此版本。
webpack.config.js
const webpack = require('webpack');
module.exports = {
mode: "production",
// using mode: "production" attaches the following configuration:
plugins: [
new webpack.NoEmitOnErrorsPlugin();
]
}
ModuleConcatenationPlugin
默认情况下,Webpack将包中的每个模块包装在单独的函数闭包中。这些包装器函数将使您的JavaScript执行速度变慢。查看此示例:
one.js
const dog = 'Fluffy';
export const one = 1;
two.js
const dog = 'Fluffy';
export const two = 2;
index.js
import { one } from './one';
import { two } from './two';
const dog = 'Fluffy';
console.log(one, two);
如果没有ModuleConcatenationPlugin,输出包将如下所示:
main.js
(function(module, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _one__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1);
/* harmony import */ var _two__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(2);
const dog = 'Fluffy';
console.log(_one__WEBPACK_IMPORTED_MODULE_0__["one"], _two__WEBPACK_IMPORTED_MODULE_1__["two"]);
/***/ }),
/* 1 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "one", function() { return one; });
const dog = 'Fluffy';
const one = 1;
/***/ }),
/* 2 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "two", function() { return two; });
const dog = 'Fluffy';
const two = 2;
/***/ })
/******/ ]);
ModuleConcatenationPlugin插件可以让输出包现在处于一个范围内。更少的函数意味着更少的运行时开销。
注意,在这个例子中我没有使用任何minification 缩小。由于Minimizer现在知道模块间的依赖性,所以它可以做得更好。
main.js
(function(module, __webpack_exports__, __webpack_require__) {
"use strict";
// CONCATENATED MODULE: ./src/one.js
const dog = 'Fluffy';
const one = 1;
// CONCATENATED MODULE: ./src/two.js
const two_dog = 'Fluffy';
const two = 2;
// CONCATENATED MODULE: ./src/index.js
const src_dog = 'Fluffy';
console.log(one, two);
/***/ })
/******/ ]);
关于ModuleConcatenationPlugin更多看这里。
补充一下mode模式文件表
mode: development
// webpack.development.config.js
module.exports = {
+ mode: 'development'
- devtool: 'eval',
- cache: true,
- performance: {
- hints: false
- },
- output: {
- pathinfo: true
- },
- optimization: {
- namedModules: true,
- namedChunks: true,
- nodeEnv: 'development',
- flagIncludedChunks: false,
- occurrenceOrder: false,
- sideEffects: false,
- usedExports: false,
- concatenateModules: false,
- splitChunks: {
- hidePathInfo: false,
- minSize: 10000,
- maxAsyncRequests: Infinity,
- maxInitialRequests: Infinity,
- },
- noEmitOnErrors: false,
- checkWasmTypes: false,
- minimize: false,
- },
- plugins: [
- new webpack.NamedModulesPlugin(),
- new webpack.NamedChunksPlugin(),
- new webpack.DefinePlugin({ "process.env.NODE_ENV": JSON.stringify("development") }),
- ]
}
mode: production
// webpack.production.config.js
module.exports = {
+ mode: 'production',
- performance: {
- hints: 'warning'
- },
- output: {
- pathinfo: false
- },
- optimization: {
- namedModules: false,
- namedChunks: false,
- nodeEnv: 'production',
- flagIncludedChunks: true,
- occurrenceOrder: true,
- sideEffects: true,
- usedExports: true,
- concatenateModules: true,
- splitChunks: {
- hidePathInfo: true,
- minSize: 30000,
- maxAsyncRequests: 5,
- maxInitialRequests: 3,
- },
- noEmitOnErrors: true,
- checkWasmTypes: true,
- minimize: true,
- },
- plugins: [
- new TerserPlugin(/* ... */),
- new webpack.DefinePlugin({ "process.env.NODE_ENV": JSON.stringify("production") }),
- new webpack.optimize.ModuleConcatenationPlugin(),
- new webpack.NoEmitOnErrorsPlugin()
- ]
}
mode: none
// webpack.custom.config.js
module.exports = {
+ mode: 'none',
- performance: {
- hints: false
- },
- optimization: {
- flagIncludedChunks: false,
- occurrenceOrder: false,
- sideEffects: false,
- usedExports: false,
- concatenateModules: false,
- splitChunks: {
- hidePathInfo: false,
- minSize: 10000,
- maxAsyncRequests: Infinity,
- maxInitialRequests: Infinity,
- },
- noEmitOnErrors: false,
- checkWasmTypes: false,
- minimize: false,
- },
- plugins: []
}
如果要根据 webpack.config.js 中的 mode 变量更改打包行为,则必须将配置导出为一个函数,而不是导出为一个对象:
var config = {
entry: './app.js'
//...
};
module.exports = (env, argv) => {
if (argv.mode === 'development') {
config.devtool = 'source-map';
}
if (argv.mode === 'production') {
//...
}
return config;
};