webpack基础+进阶+优化
简介:
webpack是一个模块打包器(构建工具)。它的主要目标是将Javascript文件打包在一起用于在浏览器中使用,它也能胜任转换(tansform)、打包(bundle)或包裹(package)任何的资源。
演变:
webpack | grunt | gulp | |
---|---|---|---|
语言 | Javascript | Node.js | Node.js |
发布时间 | 2012.3 | 2012.6 | 2013.7 |
Github stars | 40766 | 11796 | 29427 |
周下载量 | 3,385,392 | 478,876 | 816,228 |
webpack特点:社区⽣态丰富 配置灵活和插件化扩展 官方⽅更新迭代速度快 |
webpack基本组成
-
[入口(entry)]
-
[输出(output)]
-
[loader]
-
[插件(plugin)]
-
[模式(mode)]
-
浏览器兼容性(browser compatibility),,安装 -
环境(environment)-- Node.js v10.13.0+ 的版本。
1 const path = require('path'); 2 const HtmlWebpackPlugin = require('html-webpack-plugin'); 3 module.exports = { 4 entry: './path/to/my/entry/file.js', 5 output: { 6 path: path.resolve(__dirname, 'dist'), 7 filename: 'my-first-webpack.bundle.js', 8 }, 9 module: { 10 rules: [{ test: /\.js$/, use: 'babel-loader' }], 11 }, 12 plugins: [new HtmlWebpackPlugin({ template: './src/index.html' })], 13 mode: 'production', 14 };
loader(语法转换)
常见plugins
名称 | 描述 |
---|---|
babel-loader | 抓换Es6、Es7等JS的新特性语法 |
css-loader | 支持.css文件的加载和解析 |
less-loader | 将less文件转换成css |
te-loader | 将TS转换成JS |
file-loader | 进行图片、字体等打包 |
thread-loader | 多进程打包 |
在 webpack 的配置中 loader 有两个属性:
-
test
属性,用于标识出应该被对应的 loader 进行转换的某个或某些文件。 -
use
属性,表示进行转换时,应该使用哪个 loader。补充: 解析图片和文字可以采用file-loader和url-loader两种方式。
区别: url-loader封装了file-loader。url-loader不依赖于file-loader,即使用url-loader时,只需要安装url-loader即可,不需要安装file-loader,因为url-loader内置了file-loader。
-
通过npm run build进行打包构建;原理: 模块局部安装会在 node_modules/.bin ⽬录创建软链接 ;
babel介绍:
-
关于babel的配置:
-
理解 babel-preset(预设)
-
babel-preset-es2015: 可以将es6的代码编译成es5;
-
babel-preset-es2016: 可以将es7的代码编译为es6;
-
babel-preset-es2017: 可以将es8的代码编译为es7;
-
babel-preset-env 转换高级语法。
-
-
plugins ==>preset相当于plugins的集成,二者相辅相成。
-
plugins/presets排序
plugins和presets编译,是按照一定的顺序。
-
具体而言,plugins优先于presets进行编译。
-
plugins按照数组的index增序(从数组第一个到最后一个)进行编译。
-
presets按照数组的index倒序(从数组最后一个到第一个)进行编译。
-
-
plugins介绍(作⽤于整个构建过程)
常见plugins
名称 | 描述 |
---|---|
CleanWebpackPlugin | 清除构建目录 |
MiniCssExtractPlugin | 提取打包后的css文件为单独文件 |
HtmlWebpackPlugin | 创建Html文件承载输出的bundle |
UglifyjslWebpackPlugin | 压缩Js |
Mode(指定当前的构建环境)
可选值:production、development 还是 none(默认production)
文件监听
webpack 开启监听模式,有两种⽅式:
1.再package中配置,带上 --watch 参数
2.在配置 webpack.config.js 中设置 watch: true
不足:每次需要⼿动刷新浏览器
⽂件监听的原理分析
module.export = { //默认 false,也就是不开启 watch: true, //只有开启监听模式时,watchOptions才有意义 wathcOptions: { //默认为空,不监听的文件或者文件夹,支持正则匹配 ignored: /node_modules/, //监听到变化发生后会等300ms再去执行,默认300ms aggregateTimeout: 300, //判断文件是否发生变化是通过不停询问系统指定文件有没有变化实现的,默认每秒问1000次 poll: 1000 } }
3.webapk-dev-serever
特点:WDS 不刷新浏览器、WDS 不输出⽂件,⽽是放在内存中、使⽤ HotModuleReplacementPlugin插件
文件指纹(可做版本管理 )
⽂件指纹如何⽣成
-
Hash:和整个项⽬的构建相关,只要项⽬⽂件有修改,整个项⽬构建的 hash 值就会更改
-
Chunkhash:和 webpack 打包的 chunk 有关,不同的 entry 会⽣成不同的 chunkhash 值
-
Contenthash:根据⽂件内容来定义 hash ,⽂件内容不变,则 contenthash 不变
代码压缩
js压缩: 内置了 uglifyjs-webpack-plugin;
CSS压缩:CssMinimizerPlugin
html压缩:htmlWebpackPlugin
webpack--进阶篇
多页面打包
概念:每⼀次⻚⾯跳转的时候,后台服务器都会给返回⼀个新的 html ⽂档,这种类型的⽹站也就是多⻚⽹站,也叫做多⻚应⽤。
方案(利⽤ glob):
原理:动态获取 entry 和设置 html-webpack-plugin 数量。
source map
作⽤:通过 source map 定位到源代码。开发环境开启,线上环境关闭。
source map 类型
devtool | 是否适合生产环境 | 可以定位到的代码 |
---|---|---|
eval | no | webpack生成的代码(一个个的模块) |
cheap-module-eval-source-map | no | 源代码,只能看到行 |
cheap-module-source-map | yes | 源代码,只能看到行 |
inline-cheap-source-map | no | 经过loader转换后的代码(只能看到行) |
source-map | yes | 源代码 |
基础库分离:
SplitChunksPlugin
-
进⾏公共脚本分离
-
基础包 ----利用test匹配
-
分离⻚⾯公共⽂件
tree shaking(摇树优化)
概念:1 个模块可能有多个⽅法,只要其中的某个⽅法使⽤到了,则整个⽂件都会被打到 bundle ⾥⾯去,tree shaking 就是只把⽤到的⽅法打⼊ bundle ,没⽤到的⽅法会在 uglify 阶段被擦除掉。 |
使⽤:webpack 默认⽀持,在 .babelrc ⾥设置 modules: false 即可 |
要求:必须是 ES6 的语法,CJS 的⽅式不⽀持 |
css擦除:purgecss-webpack-plugin
scope hoisting (生产默认开启)
原理:将所有模块的代码按照引⽤顺序放在⼀个函数作⽤域⾥,然后适当的重命名⼀些变量以防⽌变量名冲突 |
对⽐: 通过 scope hoisting 可以减少函数声明代码和内存开销。 |
服务端渲染 (SSR)
渲染: HTML + CSS + JS + Data -> 渲染后的 HTML |
-
所有模板等资源都存储在服务端;
-
内⽹机器拉取数据更快;
-
⼀个 HTML 返回所有数据。
客户端渲染 vs 服务端渲染
客户端渲染 | 服务端渲染 | |
---|---|---|
请求 | 多个请求(HTML,数据等) | 1个请求 |
加载过程 | HTML&数据串行加载 | 1个请求返回HTML&数据 |
渲染 | 前端渲染 | 服务端渲染 |
核心 | SSR核心减少请求(利于SEO,减少白屏时间) |
webapck构建速度和体积的优化策略
速度分析:speed-measure-webpack-plugin
分析整个打包总耗时 。可以看到每个 loader 和插件执行耗时。 |
体积分析:webpack-bundle-analyzer
可分析依赖的第三方模块文件大小 、业务里面的组件代码大小 |
使用高版本的node和webpack
在软件这一块,性能往往不是最大的问题,软件不断的迭代过程中,可以不断的提升性能,对于构建而言同样是适用的,所以推荐采用高版本的 webpack 和 node.js。 |
version | timeout | 对比 |
---|---|---|
webpack 3.10.0 | 54263ms | 构建时间降低了 60%-98%! |
webpack 4.0.0-beta.2 | 26563ms |
多进程/多实例构建
thread-loader
原理:每次 webpack 解析一个模块,thread-loader 会将它及它的依赖分配给 worker 线程中 |
多进程/多实例并行压缩
terser-webpack-plugin
terser-webpack-plugin 开启 parallel 参数
缓存-提升二次构建速度
-
babel-loader 开启缓存
-
terser-webpack-plugin 开启并行压缩缓存
-
使用 cache-loader 或者 hard-source-webpack-plugin 开启模块缓存
缩小构建目标
目的:尽可能的少构建模块 ;比如 babel-loader 不解析 node_modules。 |
图片压缩
image-minimizer-webpack-plugin
Imagemin的压缩原理
-
pngquant: 是一款PNG压缩器,通过将图像转换为具有alpha通道(通常比24/32位PNG 文件小60-80%)的更高效的8位PNG格式,可显著减小文件大小;
-
pngcrush:其主要目的是通过尝试不同的压缩级别和PNG过滤方法来降低PNG IDAT数据流的大小;
-
optipng:其设计灵感来自于pngcrush。optipng可将图像文件重新压缩为更小尺寸,而不会丢失任何信息;
-
tinypng:也是将24位png文件转化为更小有索引的8位图片,同时所有非必要的metadata 也会被剥离掉。