前言
前端构建工具 Webpack 最近特火,火到 Vue/React 官方推出的脚手架都是基于 Webpck 打造的。
为了更了解 Webpack,特意实打实地安装配置 Webpack。对以后进阶学习也能夯实基础,现在一起学习入门级的 Webpack 吧!
认识 Webpack
先来观察应用 Webpack 能做的事:

从图中得出:Webpack 能打包所有 JS 脚本;能打包所有 style 样式;能打包所有图片;能打包所有预编译语言。通俗的理解就是能打包前端所有资源。
安装 Webpack
首先确保你已经安装了 Node.js 和 Git。找到存放项目的目录,在该目录下初始化项目。在终端执行:
1 | $ npm init |
初始化后生成一个 package.json 文件,大致内容:
1 | { |
为了后续快速安装其他依赖,这里使用淘宝镜像。在终端执行:
1 | $ npm install -g cnpm --registry=https://registry.npm.taobao.org |
接来下安装 Webpack,在 npm 官网查询安装手册。在终端执行:
1 |
|
附:使用 yarn 语法安装,确保已经安装 yarn。
注意:最新版本 Webpack 中 webpack-cli 从中分离了出来需要单独安装。在终端执行:
1 | $ cnpm i webpack-cli --save-dev |
安装完 Webpack 之后需要其运行起来,得需要一个配置文件,其名称为 webpack.config.js,不能为其他名称。如果是其他名称 Webpack 找不到该配置文件,就抛出错误提示。
运行 Webpack
查询官网手册后,填写 webpack.config.js 配置。对 entry 属性值和 filename 属性值进行简单修改,webpack.config.js 大致内容如下:
1 | const path = require('path'); |
module.exports 导出一个对象,其中:
entry 表示打包资源入口,该字段属性值可以是 String / Array / Object。
output 表示打包资源出口,也就是经打包的资源从该口输出。
dist 是 Webpack 打包完成后存放资源的目录。
配置完内容后,在根目录下创建目录 src,里面编写一个叫 index.js 脚本:
1 |
|
为了方便看效果,在根目录下创建一个 index.html 模版,并引入打包后的资源 bundle.js:
1 | <!DOCTYPE html> |
使用预定义命令启动 Webpack,可以在 package.json 文件中的 scripts 字段中添加命令。
1 | // ... |
在终端执行 cnpm start 打包完成后会看到在根目录下生成 dist 目录,里面包含 bundle.js 脚本,在浏览器端运行 index.html 可以看到页面输出 Hello Webpack!。
到此完成了 Webpack 初步的打包。
执行 Webpack 打包时,终端执行输出一些信息:
1 |
|
Hash表示当前文件打包生成的hash值,文件改变,hash值就会变。Version表示项目当前安装Webpack的版本。Time表示项目打包所花费的时间。Build表示项目打包日期,打包生成文件名称和文件大小Entrypoint表示项目打包入口点。
即:
1 |
|
chunks: 打包文件的id,现在只有一个bundle.js打包文件,有多个的时候,会有多个不同的chunk。Chunk Names: 打包文件的名字。
最后一行表示打包生成的文件路径。
大多数网站中都会使用缓存,减少页面加载时长。
Webpack 打包也可以做到这点,把之前的 bundle.js 改成带有 hash 值。
修改后的 webpack.config.js
1 | const path = require('path'); |
重新运行 cnpm start 打包完成后会看到根目录下生成 dist 目录,里面包含带 hash 值的资源。如果想缩短 hash 值,可以进行截取长度,比如:[hash:6]。
如果想要优化打包后的资源和想使用 Webpack 强大的功能,请继续往下看。
认识 Plugin
plugin 是 Webpack 的核心,Webpack 自身的多数功能都是用这个插件接口,让 Webpack 打包变得极其灵活。
经过认识 Webpack 初次打包后,发现每次执行 cnpm start 打包完成后都会在 dist 目录中追加打包生成后的新资源。造成 dist 文件很大。这时 clean-webpack-plugin 就可以登场,帮助我们解决这个问题。
在 npm 官网搜索该插件,点击名称进入详情查看安装手册,在终端执行:
1 |
|
在 webpack.config.js 中添加该配置:
1 | // ... |
在终端执行 cnpm start 会看到上一次打包生成的资源自动删除后,重新创建新的打包资源。
如果在项目中要引入打包后的资源,并且该资源带有 hash 值时不易方便使用,脚本太多也不易区分,这时可以使用 Webpack 提供的 HTML 模版插件解决问题。
在 npm 官网搜索该插件,点名称进去查看安装手册,在终端执行:
1 |
|
安装成功后,在根目录 package.json 中的 devDependencies 里能看到该插件和该插件的版本。
在 Webpack 中配置该插件:
1 |
|
在终端执行 cnpm start 会看到在根目录下生成 dist 目录,里面包含带 hash 值的资源和压缩过的 index.html。
如果不想使用压缩过的资源,可以在 webpack.config.js 中进行配置:
1 |
|
根据 mode 参数 Webpack 会区分是生产环境还是开发环境。一般生成环境 mode 设置为 production,开发环境设置为 development。
设置完成后,在终端执行 cnpm start 打包完成后,然后在浏览器上运行 index.html 可以看到输出内容没变化,页面代码没有压缩。
如果想对 src/index.html 做一些调整,比如:修改 title,创建多个模版文件,多个模版文件引入不同的脚本等等;只需要在 new HtmlWebpackPlugin() 中添加一些配置项就能解决。
比如修改 title:
1 | module.exports = { |
在终端执行 cnpm start 打包完成后,在浏览器上运行 index.html 会看到 title 的变化。
项目难免会美化页面,那么就得给页面添加一些样式,可以写在单独文件中,可以写在 .html 模版中,这时处理 CSS 可以使用 css-loader 解决问题。
认识 loader
loader 用于对模块的源代码进行转换。loader 可以在 import 或”加载”模块时预处理文件。可以将文件从不同的语言(如 TypeScript)转换为 JavaScript,或将内联图像转换为 data URL。loader 甚至允许直接在 JavaScript 模块中 import CSS 文件。
①、处理 CSS
首先安装处理 CSS 相应的 loader:css-loader 和 style-loader。
在 npm 官网搜索该 loader,点击名称进去查看安装手册,在终端执行:
1 |
|
css-loader处理以.css后缀的文件。style-loader经过css-loader处理过的CSS插入到DOM中。
安装成功后,在根目录 package.json 中的 devDependencies 里能看到该 loader 和该 loader 的版本。
在 webpack.config.js 中添加处理 CSS 的 loader 配置:
1 |
|
注意:use 选项顺序,先使用 css-loader 再使用 style-loader。
项目中一般都是使用单独文件写入样式,这里使用以 .css 为后缀的文件负责控制页面样式:
1 |
|
在根目录 src/index.js 中引入该样式文件:
1 | document.write('hello webpack') |
在终端执行 cnpm start 打包完成后,在浏览器上运行 index.html,能看到页面背景色变红色。使用开发者工具也能看到页面插入 style 标签,style 标签里面嵌入刚刚写的样式:

随着项目复杂度的提升,控制页面的样式也很多;如果按照这样写法,页面会有一大段来控制样式,考虑到对后期的性能优化不友好,可以考虑把样式单独打包一个文件。
②、提取 CSS
新版本 Webpack4.x 建议使用 mini-css-extract-plugin。
在 npm 官网搜索该插件,点击名称进去查看安装手册,在终端执行:
1 |
|
安装完该插件后,在根目录 package.json 中的 devDependencies 里能看到该插件和该插件的版本。
在 webpack.config.js 中的 module 选项和 plugin 选项中配置该插件:
1 | // ... |
在终端执行 cnpm start 打包完成后,在浏览器上运行 index.html,可以看到与之前效果一样;使用开发者工具能看到生成的样式文件 style.css,之前嵌套在页面中的样式不见了。
效果如下:

大型项目中一般会选择应用预编译语言,这里使用 Sass 预编译语言。
在 nmp 官网搜索该 loader,点击名称进去查看使用安装手册,在终端执行:
1 |
|
安装完毕后,在根目录 package.json 中的 devDependencies 里能看到该 loader 和该 loader 的版本。
在 webpack.config.js 中的 module 选项中配置:
1 |
|
同样在根目录 src 下创建一个专门存放 sass 样式文件:
1 |
|
在根目录 src/index.js 中引入该 scss 文件:
1 |
|
在终端执行 cnpm start 打包完成后,在浏览器上运行 index.html,能看到页面字体变化。
③、打包图片
打包处理图片使用 url-loader 和 file-loader。
在 npm 官网搜索该 loader,点击名称进去查看安装手册,在终端执行:
1 |
|
安装完该插件后,在根目录 package.json 中的 devDependencies 里能看到该 loader 和该 loader 的版本。
在 webpack.config.js 中的 module 选项中配置:
1 | module.exports = { |
在 style.css 样式文件中引入一张图片作为背景图:
1 |
|
在终端执行 cnpm start 打包完成后,在浏览器上运行 index.html,能看到之前的背景色被改变了。
技术不断创新,前端技术领域也是如此。新项目中越来越喜欢使用 ES6 作为处理 JS 页面数据交互,接下来继续打包 ES6。
④、打包 ES6
打包处理 ES6 使用 babel-loader、babel-core、babel-preset-env、babel-preset-es2015。
在 npm 官网搜索该 loader,点击名称金进去查看安装手册,在终端执行:
1 | $ cnpm i babel-loader babel-core babel-preset-env babel-preset-es2015 --save-dev |
附:如果运行出错可以安装:@babel/core,@babel/preset-env;其中babel-loader 转换 js 加载器;@babel/core 为 babel 的核心模块;@babel/preser-env 将 ES6 转为 ES5;babel-preset-es2015将部分 ES6 转化成 ES5 语法。
安装完该插件后,在根目录 package.json 中的 devDependencies 里能看到该 loader 和该 loader 的版本。
在 webpack.config.js 中的 module 选项中配置:
1 | module.exports = { |
项目中处理页面数据交互一般都是存放单独脚本文件,因此在根目录下中的 src 目录下创建一个脚本文件 es6.js:
1 |
|
在根目录 src/index.js 中引入该脚本文件:
1 |
|
此时运行 cnpm install 肯定会报错,因为需要设置 babel。在根目录下创建 .babelre 大致内容大致如下:
1 |
|
这时在终端执行 cnpm start 打包完成后,在浏览器上运行 index.html,能看到页面弹出的语句。
目前为止打包生成的 index.html 模版每次都得重新刷新页面。为了提高开发效率 Webpack 提供了开启服务热更新替换,不用刷新界面就能实现热更新。下面实现自动开启服务热更新。
devServer
查看 Webpack 手册安装相关模块,在终端执行:
1 |
|
安装成功后,在根目录 package.json 中的 devDependencies 里能看到 dev-server 和 dev-server 的版本
在 webpack.config.js 中配置:
1 | // ... |
修改 package.json 文件中的 scripts 字段里面的 start 属性对应的属性值:
1 | // ... |
也可以添加新的自定义启动 Webpack 命令,如 run 命令:
1 | // ... |
在终端执行 cnpm start 或者 cnpm run 会看到浏览器自动打开生成的 index.html。然后在 styl.css 中添加样式,如:font-size:30px 页面会自动更新并显示最新内容。
项目中或许会用到 jQuery 库或者 Vue,那么如何使用呢?继续往下看。
快捷导入
首先在 npm 官网查询要安装的包,如 jQuery,在终端执行:
1 |
|
安装完毕之后,在根目录 package.json 中的 devDependencies 里能看到 jQuery 和 jQuery 的版本。
在 webpack.config.js 中的 plugins 选项中配置:
1 |
|
为了方便看效果,在根目录下的 src 中创建新的文件,如:es5.js:
1 | // es5.js |
在根目录 src/index.js 中引入该脚本:
1 | document.write('hello webpack') |
这时在页面上能看到 Hello World!!! 字样。到此为止一个入门级带有热更新的 Webpack 学习完毕。
总结
到这里入门级 Webpack 就算结束了。以上内容从认识 Webpack 到使用各种 loader 和各种 plugins 打包生成资源应用在项目中,认识了基本的使用语法和应用各种配置,也为以后进阶的学习夯实基础。
针对不同的项目,还有更多的 Webpack 打包细节需要调优,如:如何减少搜索文件;如何提高 loader 的打包速度;如何排除项目中无用的打包文件等等。在接下来的时间里,慢慢研究与学习。