由于webpack的plugin相关知识不在我们这篇文章的讨论范畴,所以我只简单的介绍一下它是如何介入webpack的工作流程中并生成入口的。(如果有兴趣想了解这些可以私信我,有时间的话可能会整理一些资料出来给大家)该插件实际做了两件事:
通过compiler的entryOption钩子,我们将递归生成的入口数组一项一项的加入entry中。
通过compiler的watchRun钩子监听重新编译时是否有新的页面加入,如果有就会以新加入的页面生成一个依赖数组,然后再加入entry中。
现在我们将这个插件应用到之前的webpack策略中,将上面的配置更改为:(记得安装chalk replace-ext依赖)
/** build/webpack.config.js */ const EntryExtractPlugin = require('./entry-extract-plugin'); module.exports = { ... entry: { app: './app.js' }, plugins: [ ... new EntryExtractPlugin() ] }
样式预编译与EsLint
样式预编译和EsLint应用其实已经有许多优秀的文章了,在这里我就只贴出我们的实践代码:
/** build/webpack.config.js */ const MiniCssExtractPlugin = require('mini-css-extract-plugin'); module.exports = { ... module: { rules: [ ... { enforce: 'pre', test: /\.js$/, exclude: /node_modules/, loader: 'eslint-loader', options: { cache: true, fix: true, }, }, { test: /\.less$/, use: [ { loader: MiniCssExtractPlugin.loader, }, { loader: 'css-loader', }, { loader: 'less-loader', }, ], }, ] }, plugins: [ ... new MiniCssExtractPlugin({ filename: '[name].wxss' }) ] }
我们修改完策略后就可以将wxss后缀名的文件更改为less后缀名(如果你想用其他的预编译语言,可以自行修改loader),然后我们在js文件中加入import './index.less'语句就能看到样式文件正常编译生成了。样式文件能够正常的生成最大的功臣就是mini-css-extract-plugin工具包,它帮助我们转换了后缀名并且生成到目标目录中。
环境切换
环境变量的切换我们使用cross-env工具包来进行配置,我们在package.json文件中添加两句脚本命令:
"scripts": { "dev": "cross-env OPERATING_ENV=development webpack --config build/webpack.config.js --watch", "build": "cross-env OPERATING_ENV=production webpack --config build/webpack.config.js }
相应的我们也修改一下webpack的配置文件,将我们应用的环境也告诉webpack,这样webpack会针对环境对代码进行优化处理。
/** build/webpack.config.js */ const { OPERATING_ENV } = process.env; module.exports = { ... mode: OPERATING_ENV, devtool: OPERATING_ENV === 'production' ? 'source-map' : 'inline-source-map' }
虽然我们也可以通过命令为webpack设置mode,这样也可以在项目中通过process.env.NODE_ENV访问环境变量,但是我还是推荐使用工具包,因为你可能会有多个环境uat test pre等等。
针对JS优化
小程序对包的大小有严格的要求,单个包的大小不能超过2M,所以我们应该对JS做进一步的优化,这有利于我们控制包的大小。我所做的优化主要针对runtime和多个入口页面之间引用的公共部分,修改配置文件为:
/** build/webpack.config.js */ module.exports = { ... optimization: { splitChunks: { cacheGroups: { commons: { chunks: 'initial', name: 'commons', minSize: 0, maxSize: 0, minChunks: 2, }, }, }, runtimeChunk: { name: 'manifest', }, }, }
webpack会将公共的部分抽离出来在dist文件夹根目录中生成common.js和manifest.js文件,这样整个项目的体积就会有明显的缩小,但是你会发现当我们运行命令是开发者工具里面项目其实是无法正常运行的,这是为什么?
这主要是因为这种优化使小程序其他的js文件丢失了对公共部分的依赖,我们对webpack配置文件做如下修改就可以解决了:
/** build/webpack.config.js */ module.exports = { ... output: { ... globalObject: 'global' }, plugins: [ new webpack.BannerPlugin({ banner: 'const commons = require("./commons");\nconst runtime = require("./runtime");', raw: true, include: 'app.js', }) ] }
小小解惑