webpack打包构建流程
1、初始化参数:获取用户在webpack.config.js文件配置的参数
2、开始编译:初始化compiler对象,注册所有的插件plugins,插件开始监听webpack构建过程的生命周期事件,不同环节会有相应的处理,然后开始执行编译。
3、确定入口:根据webpack.config.js文件的entry入口,开始解析文件构建ast语法树,找抽依赖,递归下去。
4、编译模块:递归过程中,根据文件类型和loader配置,调用相应的loader对不同的文件做转换处理,在找出该模块依赖的模块,递归本操作,直到项目中依赖的所有模块都经过了本操作的编译处理。
5、完成编译并输出:递归结束,得到每个文件结果,包含转换后的模块以及他们之前的依赖关系,根据entry以及output等配置生成代码块chunk
6、打包完成:根据output输出所有的chunk到相应的文件目录。
loader
直译为"加载器"。Webpack将⼀切⽂件视为模块,但是webpack原⽣是只能解析js⽂件,如果想将其他⽂件也打包的话,就会⽤到 loader 。 所以Loader的作⽤是让webpack拥有了加载和解析⾮js的能力。
webpack4
webpack5
常见loader
file-loader: 把文件输出到一个文件夹中,在代码中通过相对 URL 去引用输出的文件
url-loader: 和 file-loader 类似,但是能在文件很小的情况下以 base64 的方式把文件内容注入到代码中去
source-map-loader: 加载额外的 Source Map 文件,以方便断点调试
image-loader: 加载并且压缩图片文件
babel-loader:把ES6 转换成 ES5
css-loader: 加载 CSS,支持模块化、压缩、文件导入等特性
style-loader: 把 CSS 代码注入到 JavaScript 中,通过 DOM 操作去加载 CSS
eslint-loader: 通过 ESLint 检查 JavaScript 代码
pulgins
直译为"插件"。Plugin可以扩展webpack的功能,让webpack具有更多的灵活性。 在 Webpack 运⾏的⽣命周期中会⼴播出许多事件,Plugin 可以监听这些事件,在合适的时机通过 Webpack 提供的 API 改变输出结果。
define-plugin: 定义环境变量
html-webpack-plugin: 简化html文件创建
uglifyjs-webpack-plugin: 通过 UglifyES 压缩 ES6 代码
webpack-parallel-uglify-plugin: 多核压缩,提高压缩速度
webpack-bundle-analyzer: 可视化webpack输出文件的体积
mini-css-extract-plugin: CSS提取到单独的文件中,支持按需加载
copy-webpack-plugin:打包时将文件完整复制
打包/构建优化措施
多线程打包: HappyPack:HappyPack.ThreadPool({ size: os.cpus().length });
性能:performance:可以控制 webpack 如何通知「资源(asset)和入口起点超过指定文件限制」
优化:optimization: {splitChunks: } all async initial
webpack分析
二次开发Webpack
实现Css的TreeShaking:purgecss-webpack-plugin
扩展日期格式:antd-dayjs-webpack-plugin
分析打包后的文件大小和依赖关系: BundleAnalyzerPlugin
压缩css: optimize-css-assets-webpack-plugin
压缩js:terser-webpack-plugin
webpack 4 版本 : optimization: { minimizer: new TerserJSPlugin({}), new OptimizeCSSAssetsPlugin()}
webpack 5版本 css-minimizer-webpack-plugin
开启gzip压缩:compression-webpack-plugin
如何提高webpack的构建速度?
多入口情况下,使用 CommonsChunkPlugin 来提取公共代码
通过 externals 配置来提取常用库
利用 DIPlugin 和 DlIReferencelugin 预编译资源模块 通过 DIPugin 来对那些我们用但是绝对不会修改的npm包来进行预编译,再通过DIIReferencePlugin 将预编译的模块加载进来
使用 Happypack 实现多线程加速编译
使用 webpack-uglify-parallel 来提升 uglifyPlugin 的压缩速度,原理上 webpack-uglify-parallel 采用了多核并行压缩来提升压缩速度
使用 Tree-shaking 和 Scope Hoisting 来别除多余代码
怎么配置单页应用? 怎么配置多页应用?
单页应用可以理解为webpack的标准模式,直接在 entry 中指定单页应用的入口即可,这里不再整述多页应用的话,可以使用webpack的AutoWebPlugin 来完成简单自动化的构建,但是前提是项目的目录结构必须遵守他预设的规范,多页应用中要注意的是:每个页面都有公共的代码,可以将这些代码抽离出来,避免重复的加载。比如,每个页面都引用了同一套CSS样式表,随着业务的不断扩展,页面可能会不断的追加,所以一定要让入口的配置足够灵活,避免每次添加新页面还需要修改构建配置
如何提高webpack的打包速度?
happypack: 利用进程开行编译l0ader利用缓存来便得 rebuld 更快,遗愿的是作者表示已经不会继续开发此项目 类似的替代者是thread-loader
外部扩展(externals): 将不怎么需要更新的第三方库脱离webpack打包,不被打入bundle中,从而减少打包时间,比如Quev用script标签引入
dIl: 采用webpack的 DlIPlugin 和 DIReferencePlugin 引入d,让一些基本不会改动的代码先打包成静态资源,避免反复编译浪费时间
利用缓存: webpack.cache、babel-loader,.cacheDirectory、 HappyPack,cache 都可以利用缓存提高rebuild效率缩小文件搜索范围:比如babeloader插件如果你的文件仅存在于src中,那么可以 indude: path.resolve dimamesrc),当然大多数情况下这种操作的提升有限,除非不心build了node_modules文件