# 9. webpack
本文webpack版本如下所示,版本不同命令可能会不一致,相关的配置可能会不一致。

https://www.webpackjs.com/concepts/
# 前言
# 在网页中会引用哪些常见的静态资源?
js
.js
.jsx
.coffee
.ts(TypeScript)
css
.css
.less
.sass
.scss
Images
.jpg
.png
.gif
.bmp
.svg
- 字体文件(
Fonts
).svg
.ttf
.eot
.woff
.woff2
- 模板文件
.ejs
.jade
.vue
[这是在webpack
中定义组件的方式(推荐)]
# 网页中静态资源多了会产生的问题
- 网页加载速度慢,需要发起很多二次请求;
- 要处理错综复杂的依赖关系;
# 如何解决上述问题
- 合并、压缩、精灵图、图片的
Base64
编码 - 可以使用
requireJS
、也可以使用webpack
可以解决各个包之间的复杂依赖关系。
# 如何完美实现上述的解决方案
- 使用
Gulp
基于task
任务 - 使用
Webpack
基于整个项目进行构建
- 借助于
webpack
这个前端自动化构建工具,可以完美实现资源的合并、打包、压缩、混淆等诸多功能。 - webpack官网 (opens new window)
- webpack中文网 (opens new window)
# webpack是什么?
webpack
是前端的一个项目构建工具,它基于 Node.js
开发出来的一个前端打包工具。
一张图概括webpack
可以做的事情。

不仅如此,它可以为我们提供良好的语法支持。
比如在正常浏览器下某些ES6
语法并不支持,比如import
关键字,webpack
能够帮助我们把这些不被浏览器认识的语法解析成浏览器能正常识别的语法,使我们在开发过程中无需再担心ES6
语法不兼容的问题。
# webpack安装的两种方式
全局安装(不推荐)
npm i webpack -g
局部安装(推荐)
下列选择指定版本安装或者直接最新安装,建议选择版本安装。
请在项目根目录执行命令
npm install --save-dev webpack
npm install --save-dev webpack@<version>
2

webpack4.x以上还需要安装CLI
npm install --save-dev webpack-cli
# 使用webpack打包构建项目
# 列表隔行变色案例(基础打包)
1.运行
npm init -y
初始化项目,使用npm
管理项目中的依赖包。
注意:直接使用npm init
会让你输入很多信息,一般直接npm init -y
即可。
2.创建项目基本目录结构

规范化项目结构,拥有一个dist
目录、src
目录,src
下包含js
、image
、css
目录,并拥有index.html
主页,main.js
入口js文件。
3.使用
npm i jquery
安装jquery
类库
4.创建
main.js
并书写隔行变色的代码逻辑:
// main.js 是项目的入口文件
// 1. 导入jquery
// import *** from *** 是ES6中导入模块的方式
// 由于浏览器解析不了ES6语法,所以不使用打包工具这一行执行会报错
import $ from 'jquery'
// 等同于node.js 中的 const $ = require('jquery')
$(function () {
$('li:odd').css('backgroundColor', 'lightblue')
$('li:even').css('backgroundColor', function () {
return '#' + 'D97634'
})
})
2
3
4
5
6
7
8
9
10
11
12
13
5.编写
index.html
页面代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<!-- 注意: 不推荐直接在这里引入任何包和任何css文件 -->
<script src="../dist/bundle.js"></script>
<style>
</style>
</head>
<body>
<ul>
<li>这是第1个li</li>
<li>这是第2个li</li>
<li>这是第3个li</li>
<li>这是第4个li</li>
<li>这是第5个li</li>
<li>这是第6个li</li>
<li>这是第7个li</li>
<li>这是第8个li</li>
<li>这是第9个li</li>
<li>这是第10个li</li>
</ul>
</body>
</html>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
5.使用
webpack
将main.js
打包成bundle.js
文件,执行命令。
注意:
下面语法使用对应版本

npx webpack ./src/main.js -o ./dist/main.js
注意:
上述命令包含了npx
命令,该命令是调用项目安装的模块。
npx
的原理很简单,执行命令时会到node_modules/.bin
路径和环境变量$PATH
里面,检查命令是否存在。
由于 npx
会检查环境变量$PATH
,所以系统命令也可以调用。
6.直接打开
index.html
可看到如下效果。

# 使用配置文件打包
1.在项目根目录我们创建一个
webpack.config.js
文件。
// 这个配置文件,其实就是一个js文件,通过 Node 中的模块操作,向外暴露一个配置对象。
// 下面使用的 const path = require('path') 是node中的语法,获取到根目录路径。
const path = require('path')
module.exports = {
// 手动定义 入口 和 出口
entry: path.join(__dirname, './src/main.js'), // 打包哪个文件
output: { // 输出目录相关的位置
// 指定打包好的文件输出到哪个目录
path: path.join(__dirname, './dist'),
filename: 'bundle.js' // 这是指定输出的文件的名称
}
}
2
3
4
5
6
7
8
9
10
11
12
2.根目录输入命令打包
npx webpack

# 使用热部署
使用 webpack-dev-server
工具实现自动打包编译的功能。
执行以下命令安装
npm i webpack-dev-server -D
安装完成后直接替换webpack命令即可。
注意:局部安装需要加上npx
命令
webpack-dev-server
# 使用命令行方式配置(推荐)
webpack-dev-server --port 80 --contentBase src --open --hot
--open
启动服务后,默认打开浏览器--contentBase xxx
指定托管的根目录--hot
热部署,修改一行代码保存只更新一行代码,同时实现浏览器异步刷新。--port xxxx
指定服务端口
# 使用配置文件方式配置
在
webpack.config.js
文件中添加依赖。
// 导入webpack包,需要用到webpack的HotModuleReplacementPlugin插件对象。
const webpack = require('webpack')
2
在
plugins
节点中创建插件对象。
plugins: [
// new 一个 热部署的模块对象
new webpack.HotModuleReplacementPlugin()
]
2
3
4
在跟节点中配置
devServer
devServer: {
open: true, // 默认打开浏览器
port: 80, // 设置端口
contentBase: 'src', // 指定托管的根目录
hot: true // 启用热部署
}
2
3
4
5
6
# 使用html-webpack-plugin插件
上述webpack
打包不会帮我们打包html
,所以需要html-webpack-plugin
来进行html的打包,并且实现自动加载js
文件。
添加依赖
npm i html-webpack-plugin -D
导入插件
在webpack.config.js文件中导入插件
// 导入html-webpack-plugin插件
const htmlWebpackPlugin = require('html-webpack-plugin')
2
创建插件对象
在plugins
节点中创建插件对象。
// 创建html-webpack-plugin插件
new htmlWebpackPlugin({
// 需要托管的html文件路径
template: path.join(__dirname, './src/index.html'),
// 托管后的html文件名
filename: 'index.html'
})
2
3
4
5
6
7
# 使用loader打包样式表
添加依赖
下面包含了css/less/sass的依赖
npm i style-loader css-loader less less-loader -D
cnpm i node-sass sass-loader -D
2
在
webpack.config.js
文件中module
的rules
增加匹配对象
module: {
// 这个节点,用于配置所有的第三方模块加载器
rules: [
// 这是所有第三方模块的匹配规则
// 匹配正则 - 使用什么loader 注意loader加载顺序为从右到左
{ test: /\.css$/, use: ['style-loader', 'css-loader'] },
{ test: /\.less$/, use: ['style-loader', 'css-loader', 'less-loader'] },
{ test: /\.scss$/, use: ['style-loader', 'css-loader', 'sass-loader'] }
]
}
2
3
4
5
6
7
8
9
10
main.js导入
css
和less
样式表
import './css/index.css'
import './css/index.less'
import './css/index.scss'
2
3
# loader
# 什么是loader?
在使用webpack经常需要跟loader打交道,loader到底是什么呢?
我们可以理解为它就是一个webpack的第三方装载器集合,它为我们提供了很多插件解决webpack无法装载一些特别文件的问题。
有了它我们可以在打包时把静态资源比如图片、字体库、css样式表这些文件一起打包。
# 使用loader打包url文件
在项目中经常用到图片等信息,如果不加loader,webpack默认不打包这些资源。
添加依赖
cnpm i url-loader file-loader -D
在
webpack.config.js
文件中module
的rules
增加匹配对象
配置打包图片
{
test: /\.(jpg|jpeg|png|gif|bmp)$/, use: {
loader: 'url-loader',
options: { limit: 5000, name: '[hash:8]-[name].[ext]' }
}
}
2
3
4
5
6
配置打包字体文件
{ test: /\.(ttf|eot|svg|woff|woff2)$/, use: 'url-loader' }
# Babel 高级语法支持

# 介绍
官方网站:https://www.babeljs.cn/
当遇到javascript
高级语法,比如class
关键字是ES6
的高级语法,使用webpack
打包默认并不支持这些语法导致无法编译。
而我们可以添加babel
的loader
对这些高级语法进行有效编译。
babel
原理是将高级语法转换为低级语法,使webpack能够识别。
下面指引将以最新的dabel7
作为标准。
# 使用步骤
添加依赖(执行下面两行命令)
npm i @babel/core@7 @babel/plugin-proposal-class-properties@7 @babel/plugin-transform-runtime@7 @babel/preset-env babel-loader -D
npm i @babel/runtime@7 -S
2
上述添加了以下包
- @babel/core
- 源码
- @babel/plugin-proposal-class-properties
- class部分语法支持
- @babel/plugin-transform-runtime
- 避免编译重复
- @babel/preset-env
- 语法支持
- babel-loader
- babel加载器
- @babel/runtime
- 配合transform-runtime,添加到构建版本中
在
webpack.config.js
中的module
节点下的rules
数组中添加新的匹配规则
{ test:/\.js$/, use: 'babel-loader', exclude: /node_modules/ }
exclude
排除node_modules
的目录,避免babel
对第三方js文件进行打包编译。
在项目根目录新建文件
.babelrc
的babel
配置文件。
文件采用JSON
格式进行编写如下配置。
{
"presets": [
"@babel/preset-env"
],
"plugins": [
"@babel/plugin-transform-runtime",
"@babel/plugin-proposal-class-properties"
]
}
2
3
4
5
6
7
8
9
配置完成