Webpack4模式(mode)及production内置优化

2019-05-1079次阅读webpack

模式(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;
};

 

 

上一篇: React16的JavaScript环境要求  下一篇: Webpack将多个文件夹入口输出到多个文件夹实践  

Webpack4模式(mode)及production内置优化相关文章