快速开始
定义
基于node.js来开发的静态资源打包工具,最基本的功能是递归解析依赖的文件并打包,顺便把模块化代码转化成可以直接在浏览器上运行的代码。
下载
1 | npm i webpack webpack-cli -D //下载webpack和调用webpack的命令 |
不下载到全局的原因:
不同项目可能需要使用不同版本的webpack
下载到全局无法被项目中的package.json文件记录,分享项目给其他人使用的时候需要额外下载webpack
webpack打包命令
如果全局安装:
1
webpack
如果安装到本地
1
npx webpack #npx会自动在node_modules/.bins目录下查找可执行文件
或者
1
npx webpack --watch #实时监测文件的变化,变化后保存文件自动打包
webpack.config.js
webpack配置文件,在此自定义webpack配置,就不用每次都在命令行中指定配置参数。
这个文件的执行环境是node.js,必须使用cjs语法,使用module.exports导出配置对象。
常见属性
entry
指定一个入口文件:
1
entry:'./src/main.js'
指定多个入口文件:
1
2
3
4
5
6entry:{
app:'./src/main.js',
app2:'./src/main2.js'
}
//或者
//entry: ['./src/index.js', './src/another-entry.js']更详细的配置:
1
2
3
4
5
6
7entry:{
app:{
import:'./src/main.js',//指定入口文件
dependOn:'lodash',//指定依赖的模块
filename:'page/[name].bundle.js',//指定打包后的js文件名称
} //app是模块名
}
output
属性值为一个对象
1 | { |
mode
定义打包模式(必填)
1 | mode:developmemt||production |
开发模式和打包模式的区别
开发环境:
- 不需要使用文件缓存,所以不需要给文件名额外添加[contenthash]
- 保留devServer
- 删除压缩css,js文件配置
生产环境:
- 需要使用缓存,保留文件额外名[contenthash]
- 删除devServer
- 保留压缩css,js文件配置
- 使用tree-shaking
devtool
devServer
webpack-dev-server
配置的地方
webpack-dev-server是一个由webpack团队维护的,webpack高度支持的独立的工具,用于在开发过程中提供一个开发服务器, 使用不需要导入,但是需要额外下载。
安装:
1 | npm i webpack-dev-server -D |
配置:
1 | module.exports = { |
开启服务器:
1 | npx webpack-dev-server |
运行这个命令不仅会启动Webpack的打包过程(打包到内存,不输出实际文件),还会启动一个开发服务器,部署的是打包到内存中的文件。至于是生产打包还是开发打包,就看当前的webpack配置文件了,但是一般开发环境才会用。
这个服务器会监听源文件(src目录下的js文件)的变化,源文件修改并保存会自动重新编译(因为只编译发生变化的部分)和刷新浏览器。
模块
资源模块
用来加载图片或者字体
asset/resource
导出资源打包后的路径,打包后导出源文件
1 | module:{ |
asset/inline
导出源的data:url,打包后不会导出源文件
asset/source:
导出资源的源码,如果是文本文件就是内容,不会导出源文件
asset
webpack将按照默认条件,自动地在resource和 inline 之间进行选择:小于8kb的文件,将会视为inline模块类型,否则会被视为resource模块类型。也可以修改这个配置文件。
1 | module:{ |
loader
扩展webpack的功能,帮助webpack解析其他类型(非js类型)的文件,并把这些文件转换成有效的模块,实现代码转换;只要有对应的loader,万物皆是模块。
loader在webpack.config.js文件中使用的时候通常不需要导入,直接使用即可, Webpack 会根据配置中的名称自动查找并使用相应的加载器
解析css文件
我们需要下载css-loader,以及style-loader或者mini-css-extract-plugin
style-loader: 把解析后的css样式放到打包后的html文件的style标签中
mini-css-extract-plugin:把css提取为单独的文件,多个css文件会合并为一个单独的css文件,在html-webpack-plugin插件的作用下还会自动在html文件中引入(在head标签中)。
1 | module:{ |
loader是支持链式调用的,顺序从右往左,就拿上面的例子来说,先对css文件使用css-loader,再使用style-loader。
注意:单纯打包css文件不会修改原来的css代码,也不会压缩代码,只是把原来的css代码放到一个文件中。压缩,修改css代码需要借助其他插件。
babel-loader
webpack本身只能对js代码打包,压缩,不能进行ES6到ES5的转换,需要借助babel-loader将新的语法转换成低版本的语法,实现语法降级,比如对esm语法的转化。
安装:
1 | npm i babel-loader @babel/core @babel/preset-env --save-dev |
babel-loader
是一个 Webpack 加载器,用于在 Webpack 构建过程中使用 Babel 转译 JavaScript 代码。
@babel/core
是 Babel 的核心库,负责执行实际的代码转译工作
@babel/preset-env
是一个智能预设,可以根据目标环境自动选择需要的 Babel 插件,以生成兼容的代码。
配置:
1 | module: { |
代码分离
我们可能在不同的文件引入相同的模块,这样就可能出现重复打包的问题。
将公共的代码抽离出去,减小啊打包后文件的大小,从而提高首屏的加载效率。
分离方法
模块抽离
在得知哪个模块被重复引用的前提下,抽离出该模块。
1 | entry:{ |
动态导入
1 | import('./math.js')//返回一个promise对象 |
如果引入的模块是命名导出,传入回调函数的参数格式形如
1 | { |
调用then时可以使用解构赋值来模仿按需导入
1 | export const add = (x,y)=>{ |
如果是默认导出,传入回调函数的参数格式形如,就不能直接解构了。
1 | { |
动态导入的文件打包的时候会被自动抽离为一个单独的文件,即便没有被多次使用。
编译的时候动态导入的文件会被打包好,使用的时候再导入
魔法注释
1 | import(/* webpackChunkName:'math' */'./lazy.js') //指定动态导入的文件打包后的模块名(也许不是最后文件名) |
split-chunks-plugin
使用插件split-chunks-plugin
插件
html-webpack-plugin
生成一个自动引用打包后的文件的html文件
安装:
1 | npm i html-webpack-plugin -D |
在webpack.config.js中配置:
1 | const HtmlWebpackPlugin = require(' html-webpack-plugin') //引入 |
构建多页面应用:在plugins里new多次HtmlWebpackPlugin
自定义打包后的html的标题:
- 在配置对象中添加titile属性并赋值
- 在html模板中的title标签内容替换为
<%= htmlWebpackPlugin.options.title %>
mini-css-extract-plugin
把css提取到一个单独的css文件里,代替style-loader
安装:
1 | npm i mini-css-extract-plugin -D |
配置:
1 | const MiniCssExtractPlugin = require('mini-css-extract-plugin') |
css-minimizer-webpack-plugin
压缩打包后的css文件
安装:
1 | npm i css-minimizer-webpack-plugin -D |
配置:
1 | const CssMinimizeWebpackPlugin = require('css-minimizer-webpack-plugin') |
split-chunks-plugin
自动抽离重复引用的模块,无需下载,webpack内置, 但自动抽离代码在大型项目中使用,构建过程较费时
配置:
1 | module.exports = { |
webpack-bundle-analyzer
可以帮助开发者可视化和分析 Webpack 打包后的文件大小和内容,它生成一个交互式的报告,显示每个模块的大小及其在最终打包文件中的占比,从而帮助识别和优化代码。
安装:
1 | npm i webpack-bundle-analyzer -D |
配置:
1 | const {BundleAnalyzerPlugin} = require('webpack-bundle-analyzer') |
terse-webpack-plugin
用来压缩js代码,但是Webpack 5 内置了对 Terser 的支持,在生产模式下会自动使用 Terser 进行js代码压缩,这一功能已经是webpack核心功能的一部分。但是如果需要自定义 Terser 的选项,仍然需要安装 terser-webpack-plugin
并进行相应的配置。这时,terser-webpack-plugin
是作为一个第三方插件来使用的。
tree-shaking
基于esm语法(import和
export),只有生产模式才会开启tree-shaking
,开启了生产模式就会启用tree-shaking
通过配置:
1 | module.exports = { optimization:{usedExports:true} } |
能让webpack
更积极的使用tree-shaking
,那些未在外部模块使用的导出也会被移除,就拿下面的例子来说,未开启上述配置,subtract
不会被删除,开启后就会被删除。
1 | //src/utils.js |
1 | //src/index.js |
sideEffects
配置在package.json
中,可以将其设置为 false
或提供一个数组,列出有副作用
的文件,告诉webpack哪些文件是有副作用的。因为有的文件就是没有导出的,比如css文件,不能因为这些文件没有导出就在打包的时候把他们删除。
1 | "sideEffects": ["./src/polyfills.js"] |
开发模式只要被引入就会被打包,生产环境有副作用的只要引入就会被打包,否则被使用才会被打包
搭建vue脚手架
npm包下载
webpack开发必备:
1 | npm i webpack webpack-cli html-webpack-plugin webpack-dev-server -D |
vue相关:
1 | npm i vue-template-compiler vue-loader -D |
vue-template-compiler
用来解析vue模板
vue-loader
用来解析.vue文件
配置vue-loader:
1 | const {VueLoaderPlugin} = require('vue-loader') //vue-loader还包含一个plugin |
css相关:
1 | npm i css-loader mini-css-extract-plugin -D |
sass相关:
1 | npm i sass sass-loader -D |
babel相关:
1 | npm i babel-loader @babel/core @babel/preset-env -D |
生产环境相关:
1 | npm i vue axios vue-router |
注意vue下载的是vue2
模拟vue-cli打包
1 | { |
完整配置文件
1 | const path = require('path') |
webpack打包流程
合并webapck配置文件和命令行中的参数,创建compiler对象
加载所有配置的插件,执行compiler对象的run方法,开始编译
从入口文件开始,使用配置的loader递归解析依赖的文件,把他们转化成可用的模块,并构建模块依赖图
把入口文件和它依赖的模块打包成一个单独的文件。
loader和plugin的区别
loader主要用来编译,转换文件,扩展了模块化的范围,只作用在打包文件之前。
webpack在运行过程中会产生许多广播事件,plugin通过监听webpack的广播事件,调用webpack提供的api来改变webpack的打包结果;插件可以扩展 Webpack 的功能,比如生成html文件,压缩css代码,可以作用在打包任何时期。