其实不然, mode 只可以定义成 development 或 production ,而在项目中,我们不仅仅只有开发或生产环境,很多情况下需要配置不同的环境(例如测试环境),此时我们就需要手动配置其它环境变量(例如测试环境,就需要定义 process.env.NODE_ENV 为 'test' ),你可以采取以下方式:
方法二:webpack.DefinePlugin
// webpack编译过程中设置全局变量process.env new webpack.DefinePlugin({ 'process.env': require('../config/dev.env.js') }
config/prod.env.js :
module.exports ={ // 或 '"production"' ,环境变量的值需要是一个由双引号包裹的字符串 NODE_ENV: JSON.stringify('production') }
方法三:webpack 命令时, NODE_ENV=development
在 window 中配置 NODE_ENV=production 可能会卡住,所以使用 cross-env:
cross-env NODE_ENV=production webpack --config webpack.config.prod.js
方法四:使用 new webpack.EnvironmentPlugin(['NODE_ENV'])
EnvironmentPlugin 是一个通过 webpack.DefinePlugin 来设置 process.env 环境变量的快捷方式。
new webpack.EnvironmentPlugin({ NODE_ENV: 'production', });
注意:上面其实是给 NODE_ENV 设置一个默认值 'production' ,如果其它地方有定义 process.env.NODE_ENV ,则该默认值无效。
四、配置解析策略 resolve
自定义寻找依赖模块时的策略(例如 import _ from 'lodash' ):
module.exports = { resolve: { // 设置模块导入规则,import/require时会直接在这些目录找文件 // 可以指明存放第三方模块的绝对路径,以减少寻找, // 默认 node_modules modules: [path.resolve(`${project}/components`), 'node_modules'], // import导入时省略后缀 // 注意:尽可能的减少后缀尝试的可能性 extensions: ['.js', '.jsx', '.react.js', '.css', '.json'], // import导入时别名,减少耗时的递归解析操作 alias: { '@components': path.resolve(`${project}/components`), '@style': path.resolve('asset/style'), }, // 很多第三方库会针对不同的环境提供几份代码 // webpack 会根据 mainFields 的配置去决定优先采用那份代码 // 它会根据 webpack 配置中指定的 target 不同,默认值也会有所不同 mainFields: ['browser', 'module', 'main'], }, }
五、配置解析和转换文件的策略 module
决定如何处理项目中不同类型的模块,通常是配置 module.rules 里的 Loader:
module.exports = { module: { // 指明 webpack 不去解析某些内容,该方式有助于提升 webpack 的构建性能 noParse: /jquery/, rules: [ { // 这里编译 js、jsx // 注意:如果项目源码中没有 jsx 文件就不要写 /\.jsx?$/,提升正则表达式性能 test: /\.(js|jsx)$/, // 指定要用什么 loader 及其相关 loader 配置 use: { loader: "babel-loader", options: { // babel-loader 支持缓存转换出的结果,通过 cacheDirectory 选项开启 // 使用 cacheDirectory 选项将 babel-loader 的速度提高2倍 cacheDirectory: true, // Save disk space when time isn't as important cacheCompression: true, compact: true, } }, // 排除 node_modules 目录下的文件 // node_modules 目录下的文件都是采用的 ES5 语法,没必要再通过 Babel 去转换 exclude: /node_modules/ // 也可以配置 include:需要引入的文件 } ] } }
1. noParse
指明 webpack 不去解析某些内容,该方式有助于提升 webpack 的构建性能。
2. rules
常见的 loader 有:
babel-loader :解析 .js 和 .jsx 文件
// 配置 .babelrc { "presets": [ [ "@babel/preset-env", ], "@babel/preset-react" ], "plugins": [ [ "@babel/plugin-proposal-class-properties", { "loose": true } ], [ "@babel/plugin-transform-runtime", { "absoluteRuntime": false, "corejs": false, "helpers": true, "regenerator": true, "useESModules": false } ], ] }
tsx-loader :处理 ts 文件
less-loader :处理 less 文件,并将其编译为 css
sass-loader :处理 sass、scss 文件,并将其编译为 css
postcss-loader:
// postcss.config.js module.exports = { // 解析CSS文件并且添加浏览器前缀到 CSS 内容里 plugins: [require('autoprefixer')], };
css-loader :处理 css 文件
style-loader :将 css 注入到 DOM
file-loader :将文件上的 import / require 解析为 url ,并将该文件输出到输出目录中
url-loader :用于将文件转换成 base64 uri 的 webpack 加载程序
html-loader :将 HTML 导出为字符串, 当编译器要求时,将 HTML 最小化
更多 loaders 可查看LOADERS 。
六、配置优化 optimization(webpack4)
webapck4 会根据你所选择的 mode 进行优化,你可以手动配置,它将会覆盖自动优化,详细配置请见。
主要涉及两方面的优化:
最小化包
拆包
1. 最小化包
使用 optimization.removeAvailableModules 删除已可用模块
使用 optimization.removeEmptyChunks 删除空模块
使用 optimization.occurrenceOrder 标记模块的加载顺序,使初始包更小
使用 optimization.providedExports 、 optimization.usedExports 、 concatenateModules 、 optimization.sideEffects 删除死代码
使用 optimization.splitChunks 提取公共包
使用 optimization.minimizer || TerserPlugin 来最小化包
2. 拆包