如何使用 Webpack 5.x 搭建一个项目
前言
使用版本
2020 年 10 月 10 日,Webpack 5 正式发布。
本文撰写之初,所使用版本:
- Webpack 5.28.0
- Webpack-cli 4.6.0
目录结构
以项目 2048 为例,简单划分如下:
1 | ├── config # 配置目录 |
新建项目
创建一个空的目录并进入:
1 | mkdir 2048_game |
然后进行初始化:
1 | npm init |
执行初始化命令后,终端会进行一些简单问题的询问,比如项目名称、作者信息等,以此来创建 package.json 文件,后续可以在该文件内进行修改。
指令后加上 -y,表示所有选项都为 yes,全部使用默认值。
安装 webpack
webpack:核心包,包含了 webpack 构建过程中要用到的所有 api。
webpack-cli:提供一个简单的 cli 命令,它调用了 webpack 核心包的 api,来完成构建过程。
安装 webpack、webpack-cli:
1 | # 全局安装 |
命令完成后,项目中会多一个 node_modules 文件夹,用来存放项目中安装的依赖包。
补充:install 可简写为 i,--save-dev 可简写为 -D
完善项目目录
三个重要目录
src:source,源码文件,用于存放我们写的源文件
dist:distribution,编译文件,用于存放之后打包的文件
config:配置文件(这个用于后面的配置文件分离)
1 | mkdir config dist src |
项目入口文件
根目录下:index.html
src 目录下:index.js
1 | touch index.html |
原始配置文件
回到根目录,创建配置文件 webpack.config.js:
1 | cd .. |
进行配置
初次尝试
打开 webpack.config.js,先进行基本的配置:
entry:入口文件output:打包后的文件名和存放目录mode:编译模式,先设置为开发环境
1 | const path = require('path') |
好了,让我们输入打包指令来尝试一下:
1 | npx webpack |
编译完成,打开 dist 目录,就会发现多了一个 js 文件夹,里面就是打包输出的 man.js 文件。
devServer
接下来我们配置一个本地开发服务器,可以让浏览器进行实时刷新,查看修改结果。
安装:
1 | npm i webpack-dev-server -D |
webpack.config.js 中进行配置:
contentBase:为哪一个文件夹提供本地服务,默认是根文件夹inline:启动页面实时刷新compress:启动 gzip 压缩,让文件更小,打开速度更快
1 | module.exports = { |
启动:
1 | npx webpack serve |
可以看到它提供了一个本地网址:http://localhost:8080。打开该网址,就可以实时查看页面了。
注意,这个只用于开发环境方便调试,在生产环境是不需要的。
loader配置
概念
loader 主要用于转换某些类型的模块,它是一个转换器。
对于 webpack 本身的能力来说,它只能理解 JavaScript,而对于其他转化是不支持的,比如加载 css、图片,将 ES6 转成 ES5 代码等,此时就需要通过 loader 了。
配置参数:
test:匹配 loaders 所处理文件的拓展名的正则表达式(必须)loader:loader 的名称(必须)include/exclude:手动添加必须处理的文件(文件夹)或屏蔽不需要处理的文件(文件夹)(可选)options:为 loader 提供额外的设置选项(可选)
使用:
- 下载:npm 安装需要使用的 loader
- 配置:在
webpack.config.js中的module关键字下进行配置
某个文件类型使用多个loader时,执行顺序从右往左。
样式资源
loader:css-loader、style-loader
如果还要使用预处理器比如 less,那就还需要 less-loader 和 less
作用:
css-loader:将 css 文件变成 commonjs 模块加载到 js 中,里面内容是样式字符串。style-loader:创建一个<style>标签,将 js 中的样式资源插入进去,然后添加到<head>中生效。less-loader:加载和转译 less 文件。
下载:
1 | npm i css-loader style-loader -D |
配置:
1 | module.exports = { |
静态资源
webpack5 新增了资源模块类型(asset module type),通过添加 4 种新的模块类型,替换了三个 loader:
asset/resource:发送一个单独的文件并导出 URL。替代了file-loaderasset/inline:导出一个资源的 data URI。替代了url-loaderasset/source:导出资源的源代码。替代了raw-loaderasset:在导出一个 data URI 和发送一个单独的文件之间自动选择:- 小于 8kb 的文件,将会视为
inline模块类型 - 否则会被视为
resource模块类型。 - 之前是通过使用
url-loader,并且配置资源体积限制实现。
- 小于 8kb 的文件,将会视为
配置:
1 | module.exports = { |
img 标签图片
loader:html-withimg-loader
静态资源模块处理的是 css 和 js 中的图片路径,但是它并不处理 html 中的图片路径。
所以我们还需要下载一个 loader 来处理。
作用:处理 html 文件的 img 图片。它负责引入图片,从而能被静态资源模块处理。
下载:
1 | npm i html-withimg-loader -D |
配置:
1 | module.exports = { |
js语法兼容
loader:babel-loader、@babel/core、@babel/preset-env
作用:用来处理 ES6 语法,将其编译为浏览器可以执行的 js 语法。
下载:
1 | npm i -D babel-loader @babel/core @babel/preset-env |
配置:
1 | module: { |
注意:@babel/preset-env 只能转换基本语法,高级 API 比如 promise 就不能转换了。
高级语法按需加载处理:
- 下载开发依赖(
-D):@babel/plugin-transform-runtime - 下载生产依赖:
@babel/runtime-corejs3
1 | npm install @babel/plugin-transform-runtime -D |
然后修改配置:
1 | rules: [ |
插件配置
plugin 是对 webpack 现有功能的各种扩展,比如打包优化,文件压缩等。
打包 html 文件
目前我们的 index.html 文件是存放在项目的根目录下的。
在真实发布项目时,发布的是 dist 文件夹中的内容,但是现在 dist 文件夹中还没有 index.html 文件,所以我们需要先把它打包进来。
作用:
- 自动生成一个 index.html 文件
- 将打包的 js 文件,自动通过
script标签插入到body中
安装:
1 | npm i html-webpack-plugin -D |
配置:
template:根据什么模板来生成 index.html 文件。favicon:网站的 icon。
1 | const HtmlWebpackPlugin = require('html-webpack-plugin') |
网站图标 favicon 文件需放在根目录下,不需要在源文件里引入,它会自动寻找并打包。
重新打包:
1 | npx webpack |
然后打开 dist 文件夹,就可以看到多出来一个 index.html 和 favicon.ico文件了。
自动清理 dist 目录
之后每次构建都会重新进行打包,所以需要先清除旧文件,再生成新文件。
安装:
1 | npm i clean-webpack-plugin -D |
配置:
1 | const { CleanWebpackPlugin } = require('clean-webpack-plugin') |
以后每次打包之前,都会先删除旧文件。
优化输出日志
打包编译时,很大一部分输出信息是无效信息,所以可以通过插件进行优化,让终端看起来更简洁明了。
安装:
1 | npm i @soda/friendly-errors-webpack-plugin -D |
配置:
devServer中增加:quiet: true- 增加
stats属性,让日志只在报错时显示
1 | const FriendlyErrorsWebpackPlugin = require('@soda/friendly-errors-webpack-plugin') |
最后
以上就是使用 webpack5 搭建一个项目的基本配置了,后续还有进阶配置,比如生产环境和开发环境的分离,还有不同环境下的优化配置,我们在下篇文章继续讨论。







