webpack之基础篇
在日常工作中的使用:
- 构建我们发布需要的 HTML、CSS、JS 文件, 主要用的plugin和loader:mini-css-extract-plugin、html-webpack-plugin
- 使用 CSS 预处理器来编写样式
- 压缩JS
- 处理和压缩图片
- 使用 Babel 来支持 ES 新特性
- 本地提供静态服务以方便开发调试
关联HTML(html-webpack-plugin)
简化了HTML文件的创建,以便为你的webpack包提供服务。这对于在文件名中包含每次会随着编译而发生变化哈希的 webpack bundle 尤其有用。 你可以让插件为你生成一个HTML文件,使用lodash模板提供你自己的模板,或使用你自己的loader。
主要有三个作用:
- 为html文件中引入的外部资源如script、link动态添加每次compile后的hash,防止引用缓存的外部文件问题。
- 可以生成创建html入口文件,比如单页面可以生成一个html文件入口,配置N个html-webpack-plugin可以生成N个页面入口。
- 将HTML引用路径和我们的构建结果关联起来。
先安装html-webpack-plugin
npm install --save-dev html-webpack-plugin
然后加入webpack配置中:
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
plugins: [
new HtmlWebpackPlugin({
filename: 'index.html', // 配置输出文件名和路径
template: 'dist/index.html', // 配置文件模板
})
]
}
2
3
4
5
6
7
8
9
10
通过 html-webpack-plugin 就可以将我们的页面和构建 JS 关联起来
构建CSS环境
上一章说明过,webpack 会默认把所有依赖打包成 js 文件。需要借助loader对文件进行源代码进行转换。
需要用到的loader是:
- css-loader
- mini-css-extract-plugin,将css单独剥离出来
安装:
npm i css-loader mini-css-extract-plugin --save-dev
module.exports = {
module: {
rules: [
{
test: /\.css/,
include: [
path.resolve(__dirname, 'style'),
],
use: [
{
loader: MiniCssExtractPlugin.loader
},
'css-loader'
]
},
],
plugins: [
new MiniCssExtractPlugin()
]
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
不用extract-text-webpack-plugin的原因:extract-text-webpack-plugin默认安装的版本是3.x.x,还不支持webpack的4.x版本
增加CSS预处理(sass,less,style)
预处理器功能强大,开发中经常使用以下特性:变量(variables),代码混合( mixins),嵌套(nested rules)以及 代码模块化(Modules)。
module.exports = {
...
module: {
rules: [
{
test: /\.scss$/,
use: [
{
loader: MiniCssExtractPlugin.loader
},
'css-loader',
'sass-loader'
]
}
]
},
plugins: [
new MiniCssExtractPlugin()
]
};
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
处理JS文件
安装npm i uglifyjs-webpack-plugin --save-dev
module.exports = {
module: {}
plugins: [
// 压缩js代码
new UglifyPlugin()
]
}
2
3
4
5
6
7
uglifyjs-webpack-plugin不支持ES6,可以用terser-webpack-plugin
替代
处理图片文件
前边已经对css进行处理了,但是对于样式文件url()中的jpg/png/gig等是无法处理的,这里时候就需要用到另外的loader处理了。
url-loader 功能类似于 file-loader,但是在文件大小(单位 byte)低于指定的限制时,可以返回一个 DataURL
module.exports = {
module: {
rules: [
{
test: /\.(png|jpg|gif)$/,
use: [
{
loader: 'url-loader',
options: {
limit: 8192 // 在文件大小(单位 byte)低于指定的限制时,可以返回一个 DataURL。
}
}
]
}
]
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
loader将图片处理成base64的格式
Babel支持JavaScript新特性
module.exports = {
// ...
module: {
rules: [
{
test: /\.js?/, // 支持 js 和 jsx
include: [
path.resolve(__dirname, 'js'), // js 目录下的才需要经过 babel-loader 处理
],
loader: 'babel-loader',
},
],
},
}
2
3
4
5
6
7
8
9
10
11
12
13
14
webpack-dev-server构建本地静态服务
配置scripts脚本
// package.json
"scripts": {
"start": "webpack-dev-server --inline --progress --mode development", // 这里会涉及很多配置参数,具体的可以看官网文档
"build": "webpack --mode production"
}
2
3
4
5
最后webpack的配置
// 路径解析
const path = require('path')
// 压缩JavaScript文件, uglifyjs-webpack-plugin不支持ES6语法
const terserWebpackPlugin = require('terser-webpack-plugin')
// 简化了HTML文件的创建,以便为你的webpack包提供服务。这对于在文件名中包含每次会随着编译而发生变化哈希的 webpack bundle 尤其有用。
// 你可以让插件为你生成一个HTML文件,使用lodash模板提供你自己的模板,或使用你自己的loader。
const HtmlWebpackPlugin = require('html-webpack-plugin')
// - css-loader 负责解析 CSS 代码,主要是为了处理 CSS 中的依赖,例如 `@import` 和 `url()` 等引用外部文件的声明;
// - style-loader 会将 css-loader 解析的结果转变成 JS 代码,运行时动态插入 `style` 标签来让 CSS 代码生效。
// extract-text-webpack-plugin将css单独剥离出来,替换插件(optimize-css-assets-webpack-plugin,mini-css-extract-plugin)
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
module.exports = {
entry: {
index: ['./src/js/index.js'],
vendors: ["./src/js/vendors.js"]
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.[name].[hash].js'
},
module: {
rules: [
{
test: /\.css/,
use: [
{
loader: MiniCssExtractPlugin.loader
},
'css-loader'
]
},
{
test: /\.scss$/,
use: [
{
loader: MiniCssExtractPlugin.loader
},
'css-loader',
'sass-loader'
]
},
{
test: /\.js$/, // 支持 js 和 jsx
include: [
path.resolve(__dirname, './src/js'), // js 目录下的才需要经过 babel-loader 处理
],
use: {
loader: 'babel-loader'
// options: {
// // babel-preset-env 会是一个更好的选择,babel-preset-env 可以根据配置的目标浏览器或者运行环境来自动将ES2015+的代码转换为es5。
// presets: ['@babel/preset-env']
// }
}
},
{
test: /\.(png|jpg|gif)$/,
use: [
{
loader: 'url-loader',
options: {
limit: 8192 // 在文件大小(单位 byte)低于指定的限制时,可以返回一个 DataURL。
}
}
]
}
]
},
plugins: [
new HtmlWebpackPlugin({
filename: 'index.html', // 配置输出文件名和路径
template: 'index.html', // 配置文件模板
}),
// 压缩js代码
new terserWebpackPlugin({
cache: true,
parallel: true
}),
// extract css into its own file
// Error contenthash not implemented with webpack > 4.3.0
// 1. yarn upgrade extract-text-webpack-plugin@next
// 2. 采用 mini-css-extract-plugin
new MiniCssExtractPlugin({
// 因为webpack4.3包含了contenthash这个关键字,所以ExtractTextPlugin中不能使用contenthash
// 使用md5:contenthash:hex:8代替contenthash
// github issue https://github.com/webpack-contrib/extract-text-webpack-plugin/issues/765
filename: 'css/[name].[contenthash].css',
// Setting the following option to `false` will not extract CSS from codesplit chunks.
// Their CSS will instead be inserted dynamically with style-loader when the codesplit chunk has been loaded by webpack.
// It's currently set to `true` because we are seeing that sourcemaps are included in the codesplit bundle as well when it's `false`,
// increasing file size: https://github.com/vuejs-templates/webpack/issues/1110
allChunks: true,
})
]
}
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99