基于webpack5完成工程化搭建

88 阅读3分钟

这个阶段实现将编写的业务组件通过配置webpack打包成html,css,js等最终产物文件,然后通过koa服务去加载它们,最后通过后端路由访问成功响应。

抖音“哲玄前端”《大前端全栈实践》

配置webapck主要分三大部分:解析编译、模块分包、压缩优化。先编写基础配置,然后再配置生产环境和开发环境。

解析编译

首先是入口entry,我们后面需要做多页面渲染,入口有约定好的路径。这样就可以用一个函数来读取文件,并动态的生成entryList。有了多入口,需要为它们提供不同的输出模版,这时需要使用HtmlWebpackPlugin,它可以把模版文件自动生成到打包产物中,自动引入打包后的css 、js等文件

// 动态构造 pageEntries 和 htmlWebpackPluginList
const pageEntries = {}
const htmlWebpackPluginList = []

// 获取 app/pages 目录下所有的 entry.xxx.js 文件
const entriyList = glob.sync(path.resolve(process.cwd(), './app/pages/**/entry.*.js'))
entriyList.forEach(file => {
  const entryName = path.basename(file, '.js')
  pageEntries[entryName] = file
  htmlWebpackPluginList.push(new HtmlWebpackPlugin({
    // 产物(最终模版)输出路径
    filename: path.resolve(process.cwd(), './app/public/dist', `${entryName}.tpl`),
    // 指定要使用的模版文件
    template: path.resolve(process.cwd(), './app/view/entry.tpl'),
    // 要注入的代码块
    chunks: [entryName]
  }))
})

然后是模块解析的配置,模块解析的作用是将我们书写的代码解析成浏览器可识别的内容。分别对vue、js、css、less、图片以及字体文件配置了loader解析。

模块分包

模块打包的主要思路是将第三方包和公共代码以及webpack的运行时分别打包。第三包通常不会变化,在多个文件都会使用,比如vue、lodash等。将它们单独分出来,可以充分利用浏览器的缓存,因为不会改动,文件指纹很稳定,浏览器不会重复加载它们。将公共代码抽取出来,它只用出现一次,不用多次出现在不同的文件中,可以减少打包体积同时浏览器不会重新加载它们。webapck的运行时代码和公共代码一样多次出现在不同的业务代码中,需要把它单独打包。

压缩优化

这一步需要考虑到不同环境的需求了,生产环境需要最终产物体积小和打包速度快,开发环境只需要落地模版文件,其他文件不需要生成,需要在代码变更时进行热更新.

生产环境:

  1. 使用了thread-loader开启多线程打包js、css,加快打包速度,注意: thread-loader不能MiniCssExtractPlugin.loader前,这样解析css会报错
  2. 使用MiniCssExtractPlugin插件提取公共的css, 有效利用缓存,CssMinimizerPlugin优化并压缩css资源
  3. 使用TerserPlugin利用多核cpu并发优势和缓存提升压缩阶段的性能

开发环境:

  1. 配置source-map呈现代码映射,便于代码调试
  2. 配置dev-server进行热更新,这里没有直接使用webpack的dev-server配置,这里自己实现了一个dev-server服务器。

devServer需要有监控本地文件变更和浏览器的模版文件进行双向通信的能力,其余文件存在内存中,所以在开发环境打包时配置了内存大小(--max_old_space_size=4096)。使用了devMiddleware监控文件改动,hotMiddleware往模版文件中注入代码使得devServer服务器可以和浏览器进行eventsource双向通信

其他配置

  1. 配置resolve,把代码中常用的文件后缀名加入到extensions中,配置路径别名。这样引入文件时可以不用写后缀名,书写路径时使用别名不用思考层级。
  2. webpack.ProvidePlugin把第三方库暴露到window context下,这样可以直接在业务代码中使用,无需显示导入
  3. DefinePlugin定去全局常量配置vue环境变量