Webpack入坑指北
初始化项目
首先新建一个项目然后初始化。
| 1 |  | 
创建一个 src/main.js 文件,随便写点啥
在根目录创建 build/webpack.common.js 文件
| 1 |  | 
这里需要注意一点是为什么 webpack 配置文件要用 cjs 来写 ?
答案就是因为 webpack 打包过程是在 node 环境下
在 package.json 加上打包命令
| 1 |  | 
通过执行  pnpm run build 进行打包,执行后会生成一个 dist 目录,里面就是我们打包的产物。
打包时控制台会报
The 'mode' option has not been set的警告,意思就是我们需要设置一个 mode 它可以是development开发模式、production生产模式、none无模式。另外如果 shell 命令中参数和配置文件冲突,生效的是 shell 命令参数。
创建 HTML
打包好的产物我们希望能通过html在浏览器中打开看效果,需要通过 html-webpack-plugin 插件实现
| 1 |  | 
在配置文件中写入
| 1 |  | 
plugins 就是我们声明插件来对 webpack 的功能进行扩展的地方。这时候再打包,发现产物目录下有一个 html 文件,并且通过 script 引入了我们打包的 js 文件。
打包时显示进度
| 1 |  | 
这里的 chalk 最新版本(5.3.0)使用 esm 引入,我们使用 4.1.2 版本
使用
| 1 |  | 
再进行打包就能看到进度条了,另外可以通过 chalk 来修改进度条的颜色等。
处理样式
我们定义一个 main.css 文件,在 main.js 引入,进行打包时会发现控制台报错,并提示我们需要用 loader 来处理这个类型的文件。
处理 css 类型文件需要用到以下两个 loader。
| 1 |  | 
在配置文件中声明使用这两个 loader 来处理 css 类型文件。
| 1 |  | 
module 是我们用来定义某种资源通过指定的 loader 来处理,如上代码我们通过 "style-loader" 和 "css-loader" 来处理后缀名为 css 的文件,"css-loader" 做的是解析 css 文件,翻译成 JavaScript 代码,使得 webpack 能够如同处理 JS 代码一样解析 CSS,"style-loader"" 做的是将解析出来的文件通过 style 标签插入到页面中。
另外 loader 的书写顺序也是有要求的,一般情况下,会按照由右到左,由上到下的顺序执行。所以上面代码才是先解析再插入到页面。
通过打包的产物发现我们的 css 已经被打包进 js 文件中,下面我们把 css 代码抽离出来。安装MiniCssExtractPlugin插件
| 1 |  | 
然后进行配置
| 1 |  | 
这时候再打包可以看到产物中多一个 css 文件,这样我们就把 css 文件抽离出来了
再看产物中的 index.html,多了一行 link 标签,所以这个插件的作用就是把 css 文件抽离并通过 link 标签的形式插入到页面中,这也是为什么在上面的配置中我们去掉了 style-loader。
| 1 |  | 
使用 MiniCssExtractPlugin 插件的好处在于,避免了 js 和 css 只能同步加载,对性能有影响,并且其中任意一个更新都会导致缓存失效。另外该插件必须和上面写到的 HTMLWebpackPlugin 插件一起使用(不然连 html 文件都没有怎么插入到页面)。
预处理器
我们以 less 为例
| 1 |  | 
然后新建一个 less 文件,随便写点样式,在打包入口文件导入,接着进行对 less 的配置
| 1 |  | 
无非在处理 css 文件的基础上,多了一个 less-loader ,这个 loader 做的就是把 less 翻译成 css。
postcss
安装 postcss 和 postcss-loader
| 1 |  | 
自动添加前缀
postcss 有强大的插件生态来处理各种问题,常用的如 autoprefixer,他能根据配置的浏览器兼容性,检测出需要添加前缀的 css 属性,构建的时候进行添加。
| 1 |  | 
对 postcss 配置
| 1 |  | 
在 less 文件中写入
| 1 |  | 
打包后可以看到产物已经增加了前缀
关于系统支持的浏览器可以通过 package.json 的 browserslist 或者
.browserslistrc文件进行配置
另外postcss-preset-env也可以做同样的事情,甚至更强大,他还能将现代 CSS 转换成大多数浏览器都能理解的东西。
处理 js
webpack 默认是支持处理 js 文件的,但在一些情况下,js 代码会存在兼容性的问题,在低版本的浏览器无法运行的情况,所以我们需要对这部分代码进行处理。这里用到的是 babel 对代码进行转译。
| 1 |  | 
@babel/core:babel核心库
@babel/preset-env 根据目标环境转译 JavaScript 的预设
babel-loader webpack 中的一个 loader,将 babel 集成到 webpack 构建过程中
配置
| 1 |  | 
在入口文件我们声明一个箭头函数并执行,然后分别看使用 babel-loader 进行语法降级和 不使用的效果,可以看到用 babel 后,箭头函数被转译成如下的形式。
| 1 |  | 
处理 ts
使用 ts-loader
| 1 |  | 
配置
| 1 |  | 
还需要创建 ts 的配置文件 tsconfig.json
| 1 |  | 
这时候就可以执行构建了
使用 babel
| 1 |  | 
配置
| 1 |  | 
两者区别
使用 @babel/preset-typescript 只是进行了代码转换,而 ts-loader 还会对代码进行类型检查。例如我们将 number 赋值给一个 string 类型。ts-loader 在构建时会报错。
处理资源
file-loader
安装
| 1 |  | 
file-loader 将资源重命名,在代码中插入 url 地址。
url-loader
安装
| 1 |  | 
配置
| 1 |  | 
url-loader 会对比资源大小和配置的限制大小,如果没超出限制就转为 Base64 编码,超出的话就同 file-loader 一致。
raw-loader
不转译,直接将文件复制到产物。
Webpack5 通过 module.rules.type 指定资源类型。
asset/resource 对标 file-loaderasset 对标 url-loader,module.rules.parser.dataUrlCondition 用于限定文件大小阈值asset/source 对标 raw-loader / asset/inline
区分开发环境和生产环境
我们上面写到的 webpack.common.js 可以作为一个基础的配置,在开发环境和生产环境中配置也是有差异的,所以我们还需要分别去配置。
创建 build/webpack.dev.js 和 build/webpack.prod.js
因为开发环境和生产环境都基于基础配置,我们需要通过 webpack.merge 将他们连接起来。
| 1 |  | 
webpack-dev-server
一般开发环境我们希望项目构建后能直接在浏览器运行,这一点通过 webpack-dev-server 来实现
| 1 |  | 
配置
| 1 |  | 
重写启动命令
| 1 |  | 
执行 pnpm run dev 将会在 3000 端口启动。
关于打包命名
| 格式 | 描述 | 
|---|---|
| [name] | 文件名称 | 
| [hash] | 每次webpack构建时生成一个唯一的hash值 | 
| [chunkhash] | 根据chunk生成hash值,来源于同一个chunk,则hash值就一样 | 
| [contenthash] | 根据内容生成hash值,文件内容相同hash值就相同 | 
source map
一般建议在开发环境中开启 sourcemap 开启方法也很简单 配置中设置 devtool 即可,默认在开发环境中是 eval 生产环境是 none
开发环境一些参数(具体需要看文档)
eval 会在构建时使用 eval 来执行代码,在末尾加上 //# sourceURL=xxx.js 来指定映射文件路径,报错时会指向webpack 生成的一个临时文件中,速度最快
eval-source-map 和 eval 类似, 区别在于使用的是 dataUrl 的方式
cheap-eval–source-map 类似 eval-source-map 但开销更低 只映射行数,会忽略 loader 的sourcemap
cheap-module-eval–source-map 支持 loader 的 sourcemap