文档
Webpack 用于编译JS模块,即俗称的“项目工程化”工具。
安装
如果你使用脚手架(vue-cli)等快速搭建工具,一般都集成了Webpack和一些基本配置。
版本信息
首先通过 npm 查看 Webpack 的版本信息。
$ npm info webpack
// webpack@4.41.2 | MIT | deps: 23 | versions: 625
// 可执行文件
// bin: webpack
// 所有版本
// dist-tags:
// latest: 4.41.2 legacy: 1.15.0 next: 5.0.0-beta.9
// webpack-2: 2.7.0 webpack-3: 3.12.0
我们使用默认的最新版本 webpack4。这里推荐使用 yarn 代替 npm。
启动 Webpack
使用本地路径
本地启动:
$ ./node_modules/.bin/webpack
使用 npx 命令
使用 npx 来启动 Webpack,会自动在当面目录寻找可执行的文件。
注意: 在 windows 系统中某些情况可能存在不稳定性,比如安装 node 时的路径有空格等。
$ npx webpack
Webpack 默认在当前目录的 dist 目录中输出结果。这是通过集成的加载器 babel-loader 实现的。
优化生成方式(build)
使用快速脚本,每次构建时清空 dist 目录并重新生成。
Mac/Linux
{
"script": {
"build": "rm -rf dist; webpack"
}
}
Windows
{
"script": {
"build": "rm -rf dist && webpack"
}
}
使用命令
$ yarn build
使用插件
使用插件 clean-webpack-plugin 来代替清理工作。
安装:
$ yarn add clean-webpack-plugin
配置插件:
const CleanWebpackPlugin = require('clean-webpack-plugin');
module.exports = {
entry: {
app: './src/index.js',
print: './src/main.js'
},
plugins: [
new CleanWebpackPlugin(['dist'])
]
};
}
常用配置
默认会警告设置配置文件中的转译模式。
路径和模式
创建配置文件。
$ touch webpack.config.js
配置:
const path = require("path");
module.exports = {
// 转译模式: development 开发者模式 / production 产品模式
mode: "development",
// 输入源
entry: "./src/index.js",
// 输出
output: {
// 文件名
filename: "main.js",
// 输出路径
path: path.resolve(__dirname, "dist")
}
};
缓存需求文件名
缓存需求文件名
可以设置为生成包含MD5哈希的字符串插入文件名用于 http 缓存。
module.exports = {
...
output: {
filename: "main.[contenthash].js"
}
};
自动生成 html
使用 html-webpack-plugin 插件。
$ yarn add html-webpack-plugin
配置:
module.exports = {
...
plugins: [
new HtmlWebpackPlugin({
title: 'Title',
favicon: require('./favicon.ico'),
template: 'src/assets/index.html'
})
],
};
对于使用自定义的 title,需要在 html 中配置:
<head>
<title><%= htmlWebpackPlugin.options.title %></title>
</head>
引入和自动生成 css
使用加载器
$ yarn add css-loader style-loader
作用
- css-loader 的作用是如果发现任何以 .css 结尾的文件,立即处理并读入 js 文件中。
- style-loader 的作用是把独到的内容变为 html 文件中的 style 标签插入页面。
配置
module.exports = {
entry: './src/index.js',
output: {
filename: 'main.js',
path: path.resolve(__dirname, 'dist')
},
module: {
rules: [
{
test: /\.css$/,
use: [
'style-loader',
'css-loader'
]
}
]
}
};
分离抽成 css 文件
使用插件 mini-css-extract-plugin 来打包 css 文件,把 css 样式从 js 文件中提取到单独的 css 文件。
安装
$ yarn add mini-css-extract-plugin
配置:
+ const MiniCssExtractPlugin = require('mini-css-extract-plugin')
module.exports = {
plugins: [
new MiniCssExtractPlugin({
// Options similar to the same options in webpackOptions.output
// all options are optional
filename: '[name].[contenthash].css',
chunkFilename: '[id].[contenthash].css',
ignoreOrder: false, // Enable to remove warnings about conflicting order
}),
],
module: {
rules: [
{
test: /\.css$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
// you can specify a publicPath here
// by default it uses publicPath in webpackOptions.output
publicPath: '../',
hmr: process.env.NODE_ENV === 'development',
},
},
'css-loader',
],
},
],
},
};
此插件会在 dist 目录重新生成 css 文件,并在 html 中以 link 标签的形式插入。且会把所有通过 import 方式引入的 css 文件全部整合为一个文件,根据引入顺序来排列内容。
高级配置
介绍一些 Webpack 的高级配置。首先,需要深入了解一些。
插件与加载器
Webpack 的使用和拓展主要通过两种方式来实现:加载插件或安装加载器。
两者的定义和区别
- 本意上的区别。
- 加载器主要用来加载资源文件,插件则用来加强、扩展功能。
- 当然 loader 也变相的扩展了 Webpack,但它更专注于转化文件。
- plugin 的功能更加丰富,不仅局限于资源的加载。
- loader 必定是一个文件加载另外一个文件,而 plugin 可能是综合多个文件合并为一个文件。
引入 scss
引入 .scss 文件。
注意:使用 dart-sass 代替 node-sass,因为后者已经过时且很难安装。
安装
$ yarn add sass-loader dart-sass
scss 语法示意:
$color: red;
body{
color: $color;
}
下面示意 sass-loader 和 css-loader 、 style-loader 的链式调用。
配置(sass-loader 默认使用 node-sass,你需要把它改成 dart-sass):
module.exports = {
...
module: {
rules: [
{
test: /\.scss$/,
use: [
"style-loader", // 将 JS 字符串生成为 style 节点
"css-loader", // 将 CSS 转化成 CommonJS 模块
//"sass-loader" 将 Sass 编译成 CSS,如果只写这一行,默认使用 Node Sass
{
loader: "sass-loader",
options: {
implementation: require('dart-sass')
}
},
]
}
]
}
}
引入 less
引入 .less 文件。
此模块需要 Node v6.9.0+ 和 Webpack v4.0.0+。
安装:
$ yarn add less-loader less
less 语法示意:
@color: red;
body{
color: @color;
}
下面示意 less-loader 和 css-loader 、 style-loader 的链式调用。配置:
module.exports = {
...
module: {
rules: [
{
test: /\.less$/,
use: [
"style-loader", // 将 JS 字符串生成为 style 节点
"css-loader", // 将 CSS 转化成 CommonJS 模块
"less-loader", // 将 Less 编译成 CSS
]
},
]
}
}
引入 stylus
引入 .styl 文件。
安装
$ yarn add stylus-loader stylus
stylus 语法示意:
setColor = red;
body{
color: setColor;
}
配置
module.exports = {
...
module: {
rules: [
{
test: /\.less$/,
use: [
"style-loader", // 将 JS 字符串生成为 style 节点
"css-loader", // 将 CSS 转化成 CommonJS 模块
"stylus-loader", // 将 Stylus 编译成 CSS
]
}
]
}
}
使用 file-loader
file-loader 加载器可以根据 require 路径来把文件变成文件路径,以达到加载目的。
安装
$ yarn add file-loader
配置
module.exports = {
module: {
rules: [
{
test: /\.(png|svg|jpg|gif)$/,
use: [
{
loader: 'file-loader',
options: {
context: 'project',
publicPath: 'assets',
},
},
],
},
],
},
}
浏览——快速开发
使用 webpack-dev-server 可以快速构建一个简单的 web 服务器,读取在 dist 目录下的文件,且会实时更新重载。
安装
$ yarn add webpack-dev-server
配置
module.exports = {
entry: {
app: './src/index.js',
print: './src/print.js'
},
devtool: 'inline-source-map',
devServer: {
contentBase: './dist'
}
};
添加脚本命令
{
"script": {
"start": "webpack-dev-server --open"
}
}
--open 表示自动打开浏览器。
懒加载
懒加载或按需加载,是一种很好的优化网页或应用的方式。
这种方式实际上是先把你的代码在一些逻辑点处分离开,然后完成某些操作后,立即引用或即将引用新的代码块。这样加快了应用的初始化加载速度,减轻了总体积,因为某些代码块可能永远不会被加载。
实现思路
用 import 将其当做一个函数去加载文件,得到一个 promise,成功或失败的回调。
示例
创建需要按需加载的文件。
$ touch src/lazy.js
html 中定义模块
<body>
<div id="lazy-load"></div>
</body>
index.js
onst div = document.getElementById('lazy-load')
const button = document.createElement('button')
button.innerText = 'I am Lazy-Load'
button.onclick = () => {
const promise = import('./lazy')
promise.then((module)=>{
module.default()
},()=>{
console.log('Error')
})
}
div.appendChild(button)
lazy.js
export default function lazyModule() {
console.log('This is a lazy loading module.')
alert('This is a lazy loading module.')
}