[前端进阶课] 构建自己的 webpack 知识体系 (3)

在前端开发中,在不同的应用环境中,需要不同的配置。如:开发环境的API Mocker、测试流程中的数据伪造、打印调试信息。如果使用人工处理这些配置信息,不仅麻烦,而且容易出错。

使用DefinePlugin配置的全局常量

注意,因为这个插件直接执行文本替换,给定的值必须包含字符串本身内的实际引号。通常,有两种方式来达到这个效果,使用 ' "production" ', 或者使用 JSON.stringify('production')。

new webpack.DefinePlugin({ // 当然,在运行node服务器的时候就应该按环境来配置文件 // 下面模拟的测试环境运行配置 'process.env':JSON.stringify('dev'), WP_CONF: JSON.stringify('dev'), }),

测试DefinePlugin:编写

if (WP_CONF === 'dev') { console.log('This is dev'); } else { console.log('This is prod'); }

打包后WP_CONF === 'dev'会编译为false

if (false) { console.log('This is dev'); } else { console.log('This is prod'); } 清除不可达代码

当使用了DefinePlugin插件后,打包后的代码会有很多冗余。可以通过UglifyJsPlugin清除不可达代码

[ new UglifyJsPlugin({ uglifyOptions: { compress: { warnings: false, // 去除warning警告 dead_code: true, // 去除不可达代码 }, warnings: false } }) ]

最后的打包打包代码会变成console.log('This is prod')

附Uglify文档:https://github.com/mishoo/UglifyJS2

使用DefinePlugin区分环境 + UglifyJsPlugin清除不可达代码,以减轻打包代码体积

HappyPack

HappyPack可以开启多进程Loader转换,将任务分解给多个子进程,最后将结果发给主进程。

使用

exports.plugins = [ new HappyPack({ id: 'jsx', threads: 4, loaders: [ 'babel-loader' ] }), new HappyPack({ id: 'styles', threads: 2, loaders: [ 'style-loader', 'css-loader', 'less-loader' ] }) ]; exports.module.rules = [ { test: /\.js$/, use: 'happypack/loader?id=jsx' }, { test: /\.less$/, use: 'happypack/loader?id=styles' }, ] ParallelUglifyPlugin

ParallelUglifyPlugin可以开启多进程压缩JS文件

import ParallelUglifyPlugin from 'webpack-parallel-uglify-plugin'; module.exports = { plugins: [ new ParallelUglifyPlugin({ test, include, exclude, cacheDir, workerCount, sourceMap, uglifyJS: { }, uglifyES: { } }), ], }; BundleAnalyzerPlugin

webpack打包结果分析插件

const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; module.exports = { plugins: [ new BundleAnalyzerPlugin() ] } test & include & exclude

减小文件搜索范围,从而提升速度

示例

{ test: /\.css$/, include: [ path.resolve(__dirname, "app/styles"), path.resolve(__dirname, "vendor/styles") ] } 外部扩展(externals)

这玩意不是插件,是wenpack的配置选项

externals 配置选项提供了「从输出的 bundle 中排除依赖」的方法。相反,所创建的 bundle 依赖于那些存在于用户环境(consumer's environment)中的依赖。此功能通常对 library 开发人员来说是最有用的,然而也会有各种各样的应用程序用到它。

entry: { entry: './src/main.js', vendor: ['vue', 'vue-router', 'vuex'] }, externals: { // 从输出的 bundle 中排除 echarts 依赖 echarts: 'echarts', } Webpack HMR 原理解析

Hot Module Replacement(简称 HMR)

包含以下内容:

热更新图

热更新步骤讲解

[前端进阶课] 构建自己的 webpack 知识体系

第一步:webpack 对文件系统进行 watch 打包到内存中

webpack-dev-middleware 调用 webpack 的 api 对文件系统 watch,当文件发生改变后,webpack 重新对文件进行编译打包,然后保存到内存中。

webpack 将 bundle.js 文件打包到了内存中,不生成文件的原因就在于访问内存中的代码比访问文件系统中的文件更快,而且也减少了代码写入文件的开销。

这一切都归功于memory-fs,memory-fs 是 webpack-dev-middleware 的一个依赖库,webpack-dev-middleware 将 webpack 原本的 outputFileSystem 替换成了MemoryFileSystem 实例,这样代码就将输出到内存中。

webpack-dev-middleware 中该部分源码如下:

// compiler // webpack-dev-middleware/lib/Shared.js var isMemoryFs = !compiler.compilers && compiler.outputFileSystem instanceof MemoryFileSystem; if(isMemoryFs) { fs = compiler.outputFileSystem; } else { fs = compiler.outputFileSystem = new MemoryFileSystem(); } 第二步:devServer 通知浏览器端文件发生改变

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zygsyy.html