本质上,webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler)。当 webpack 处理应用程序时,它会递归地构建一个依赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个 bundle。
1、安装
前提条件
已安装 Node.js 的最新版本,使用旧版本,可能会缺少 webpack 功能以及/或者缺少相关 package 包。
本地安装
// 安装最新版本
npm install --save-dev webpack
// 安装指定版本
npm install --save-dev webpack@<version>
注意,如果使用 webpack 4+ 版本,还需要安装 CLI。
npm install --save-dev webpack-cli
全局安装
npm install --global webpack
全局安装 webpack,可以让我们在全局环境下可用 webpack,但同时,这会将你项目中的 webpack 锁定到指定版本,并且在使用不同的 webpack 版本的项目中,可能会导致构建失败。
2、基本使用
基本安装
首先创建一个目录,在该目录下打开终端,初始化 npm,然后在本地安装 webpack,接着安装 webpack-cli(此工具用于在命令行中运行 webpack),最后安装工程需要使用到的外部模块——jQuery:
// 初始化工程
npm init -y
// 安装 webpack-cli
npm install webpack webpack-cli --save-dev
// 安装 jQuery
npm i jquery -S
目录结构
- 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>
<!-- 直接引入打包后的文件 -->
<script src="../dist/bundle.js"></script>
</head>
<body>
<ul>
<li>First</li>
<li>Second</li>
<li>Third</li>
<li>Fourth</li>
</ul>
</body>
</html>
- main.js
// 导入外部模块
import $ from 'jquery'
// 设置列表的隔行变色效果
$(function(){
$('li:odd').css('backgroundColor', 'lightblue')
$('li:even').css('backgroundColor', 'yellow')
})
创建一个bundle文件
将源代码(/src)进行打包到输出目录(/dist),打包后生成的"bundle.js"文件,是构建过程产生的代码最小化和优化后的代码,最终将在浏览器中加载:
webpack .\src\main.js -o .\dist\bundle.js
运行结果
在浏览器打开我们的 index.html 网页,可以看到列表已经有了隔行变色的效果:
配置文件使用
webpack 也支持 配置文件,这比在终端(terminal)中手动输入大量命令要高效的多,在根目录下新建配置文件:
- webpack.config.js
const path = require('path')
// 向外暴露配置对象
module.exports = {
// 入口
entry: path.join(__dirname, './src/main.js'),
// 出口
output: {
// 输出目录
path: path.join(__dirname, './dist'),
// 输出文件名
filename: "bundle.js"
}
}
- 入口(entry):入口起点(entry point)指示 webpack 应该使用哪个模块,来作为构建其内部依赖图的开始。进入入口起点后,webpack 会找出有哪些模块和库是入口起点(直接和间接)依赖的。
- 出口(output):output 属性告诉 webpack 在哪里输出它所创建的 bundles,以及如何命名这些文件,默认值为 ./dist。
此时,我们可以直接在命令行输入 webpack 进行打包:
3、webpack-dev-server
webpack-dev-server 能够用于快速开发应用程序,它为你提供了一个简单的 web 服务器,并且能够实时重新加载(live reloading)。
安装
// 本地安装 webpack-dev-server
cnpm i webpack-dev-server -D
// 需要在本地项目安装 webpack webpack-cli
cnpm i webpack -D
cnpm i -D webpack-cli
配置
由于 webpack-dev-server 是本地安装的,所以我们不能直接在命令行使用 webpack-dev-server 指令,需要通过 npm 来运行:
- package.json
{
"name": "webpack",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
// 配置指令
"dev": "webpack-dev-server"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"jquery": "^3.4.1"
},
"devDependencies": {
"webpack-dev-server": "^3.9.0"
}
}
更改打包文件的引入位置:
<!-- <script src="../dist/bundle.js"></script> -->
<script src="/bundle.js"></script>
运行
npm run dev
自动打包生成的 “bundle.js” ,默认是在根目录下,且该文件实际上是存在于内存之中(为了更快地写读),并不存在于物理磁盘中。
点击链接 http://localhost:8081/ ,并进入 “src” 目录,可以看到网页 "index.html"的显示效果。
此时,修改 main.js 的内容并保存后,会自动进行打包,网页内容会实时更新。
// 修改内容
$('li:even').css('backgroundColor', 'orange')
网页更新结果:
常用命令参数
- open:自动打开浏览器;
- port [arg]:指定端口;
- contentBase [arg]:指定托管的根目录;
- hot:开启热更新;
方式一,在 "package.json"中,增加参数配置:
"dev": "webpack-dev-server --open --port 3000 --contentBase src --hot"
方式二,在 webpack 配置文件 "webpack.config.js"中,配置 webpack-dev-server:
const path = require('path')
// 启动热更新,需要引入 webpack
const webpack = require('webpack')
// 向外暴露配置对象
module.exports = {
// 入口
entry: path.join(__dirname, './src/main.js'),
// 出口
output: {
// 输出目录
path: path.join(__dirname, './dist'),
// 输出文件名
filename: "bundle.js"
},
// 配置 webpack-dev-server
devServer: {
open: true,
port: 3000,
contentBase: 'src',
hot: true
},
// 配置插件节点
plugins: [
// 创建热更新的模块对象
new webpack.HotModuleReplacementPlugin()
]
}
网页显示结果:
4、html-webpack-plugin
html-webpack-plugin 简化了HTML文件的创建,基本功能是为项目生成一个或多个HTML文件(HTML文件个数由插件实例的个数决定),并将webpack打包后输出的所有脚本文件自动添加到插件生成的HTML文件中。
安装
cnpm i html-webpack-plugin -D
配置
- webpack.config.js
// 导入 html-webpack-plugin
const htmlWebpackPlugin = require('html-webpack-plugin')
// 向外暴露配置对象
module.exports = {
...
// 配置插件节点
plugins: [
...
// 创建插件对象
new htmlWebpackPlugin({
// 本地模板文件的位置,支持加载器(如handlebars、ejs、undersore、html等)
template: path.join(__dirname, './src/index.html'),
// 输出文件的文件名称,默认为index.html
filename: 'index.html'
})
]
}
- index.html:
<!-- HTML文件会自动导入打包输出的脚本 -->
<!-- <script src="/bundle.js"></script> -->
结果
html-webpack-plugin 会自动在内存中根据指定页面生成一个虚拟页面,并自动导入打包输出的脚本,方便我们编译 Webpack 项目中的 html 类型的文件。
5、loaders
webpack 可以使用 loader 来预处理文件,这允许你打包除 JavaScript 之外的任何静态资源。
css文件打包
安装
css文件打包需要先使用 css-loader 进行处理,再使用 style-loader 进行处理。
cnpm i css-loader style-loader -D
配置
- webpack.config.js
module.exports = {
...
// 配置所有第三方模块加载器的节点
module: {
// 匹配规则
// test 匹配正则表达式,use 对应处理的加载器
rules: [
// 在调用 loader 时,如果有多个loader,会从后往前进行传递处理
{test: /\.css$/, use: ['style-loader','css-loader']},
]
}
}
css文件
- src/css/index.css
li {
list-style: none;
}
导入
- main.js
// 导入css文件
import "./css/index.css"
结果
总结
webpack只能对js文件进行打包,对于第三方文件,会到配置文件中查找匹配的 loader 规则,然后调用对应的 loader 处理这种文件类型,处理完毕后传递回 webpack 进行打包合并,最终输出到 bundle.js中。
less文件打包
安装
less文件打包需要先使用 less-loader 进行处理,区别在于 less-loader 内部隐式依赖于 less。
cnpm i less-loader less -D
配置
- webpack.config.js
module.exports = {
...
module: {
rules: [
...
{test: /\.less$/, use: ['style-loader','css-loader','less-loader']},
]
}
}
less文件
- src/css/index.less
ul {
padding: 0;
margin: 0;
}
导入
- main.js
// 导入less文件
import "./css/index.less"
结果
scss文件打包
安装
scss文件打包需要先使用 sass-loader 进行处理,同样,也内部依赖于 node-sass。
cnpm i sass-loader node-sass -D
配置
- webpack.config.js
module.exports = {
...
module: {
rules: [
...
{test: /\.scss$/, use: ['style-loader','css-loader','sass-loader']},
]
}
}
scss文件
- src/css/index.scss
html, body{
margin: 0;
padding: 0;
li{
font-size: 12px;
line-height: 30px;
}
}
导入
- main.js
// 导入scss文件
import "./css/index.scss"
结果
url地址打包
安装
url地址打包可以使用 url-loader 进行处理,其内部依赖于 file-loader。url-loader 功能类似于 file-loader,但是在文件大小(单位 byte)低于指定的限制时,可以返回一个 DataURL(base64编码)。
cnpm i url-loader file-loader -D
配置
- webpack.config.js
module.exports = {
...
module: {
rules: [
...
{test: /\.(jpg|png|gif|bmp|jpeg)$/, use: 'url-loader'},
]
}
}
配置参数:
- limit:Number,内联文件作为数据URL的字节数限制,单位是 byte;
- mimetype:String,指定文件的MIME类型(否则从文件扩展名推断);
- fallback:String,当文件大于限制时,指定的文件loader;
{
test: /\.(jpg|png|gif|bmp|jpeg)$/,
use: [
{
loader: 'url-loader',
options: {
limit: 8192,
mimetype: 'image/png',
fallback: 'responsive-loader'
}
}
]
}
样式文件
- src/css/index2.scss
html, body{
.box{
width: 220px;
height: 120px;
background-image: url('../image/image.jpg');
background-size: cover;
}
}
- index.html
<div class="box"></div>
导入
- main.js
import "./css/index2.scss"
结果
字体文件打包
安装
字体文件打包可以同样地使用 url-loader,这里我们安装 bootstrap ,用字体图标进行字体文件打包测试。
cnpm i bootstrap -D
// 4.x版本icon文件分离出去了,故需额外安装
npm i https://github.com/iconic/open-iconic.git -D
配置
- webpack.config.js
module.exports = {
...
module: {
rules: [
...
{test:/\.(ttf|eot|svg|woff|woff2|otf)$/, use: 'url-loader'},
]
}
}
HTML文件
- src/index.html
<!-- 引用 bootstrap 样式,其中引用到字体文件 -->
<span class="oi oi-account-login"></span>
<span class="oi oi-account-logout"></span>
导入
- main.js
// 导入bootstrap
import 'bootstrap/dist/css/bootstrap.css'
import 'open-iconic/font/css/open-iconic-bootstrap.css'
结果
参考链接: