webpack单页应用打包
# 1.webpack的作用
- 将浏览器不能够识别的前端静态资源 打包成浏览器能够识别的资源文件
- 压缩代码
- 加密代码/混淆
# 2.webpack 5大概念【重点掌握】
entry 入口文件设置
entry:"a.js",
1output 出口文件 (打包完成之后的文件)
output:{ path:'', //bundle.js 打包完成之后放置的位置 (必须是绝对路径) finename:'bundle.js' //打包完成之后的文件名 }
1
2
3
4loader (解释器)
module:{ rules:[ { test:正则, // css文件 /\.css$/ /\.png$/ 匹配文件 use:'' [] //使用什么loader进行解释 } ] }
1
2
3
4
5
6
7
8plugin (插件)
plugins:[ ]
1
2
3mode (环境)
mode:'development' //development 开发环境 production 生产环境
1
# 3.配置webpack步骤
# 3.1 全局安装webpack及初始化项目
npm install webpack@5.11.0 webpack-cli@4.10.0 -g #全局安装webpack@5.11.0 webpack-cli
1
yarn init -y #初始化项目
yarn add webpack@5.11.0 webpack-cli@4.10.0 -D #项目本地安装webpack@5.11.0 webpack-cli
1
2
2
# 3.2 创建 webpack.config.js 配置文件
/**
* webpack 打包配置文件
*/
module.exports={
//入口
entry:'',
//出口
output:{
path:'', //绝对路径
filename:''
},
//loader
module:{
rules:[
]
},
//plugin 插件
plugins:[
],
//mode 环境 development:开发环境 production:生产环境(线上环境)
mode:'development'
}
1
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
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
# 3.3配置webpack.config.js文件 打包index.js文件
/**
* webpack 打包配置文件
*/
//引入nodejs内置模块,可以拿到当前文件的跟目录
const path = require('path');
module.exports={
//入口
entry:'./src/js/index.js', //相对路径
//出口
output:{
path:path.resolve(__dirname,'dist'), //绝对路径 所有的打包完成之后的文件都放在这个
filename:'bundle.js' //资源打包完成之后生成的js文件
},
//loader
module:{
rules:[
]
},
//plugin 插件
plugins:[
],
//mode 环境 development:开发环境 production:生产环境(线上环境)
mode:'development'
}
1
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
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
<!-- index.html -->
<p>啊啊啊啊</p>
<script src="../dist/bundle.js"></script>
1
2
3
2
3
# 3.4 打包完成之后的文件目录
# 4.webpack打包css文件
多个css文件相互引入
最高层级的css文件引入到js入口文件
添加loader css-loader style-loader
yarn add css-loader@5.2.0 style-loader@2.0.0 -D
1写webpack.config.js文件的loader配置
//loader module: { rules: [ { test: /\.css$/, //正则表达式 匹配需要应用这个规则的所有文件是哪些 use: ['style-loader', 'css-loader'] //使用哪些三方包去处理匹配出来的这些文件 //css-loader:将css文件能够让webpack识别 //style-loader: 将js中的css代码提取到页面上 写到style标签里面 } ] },
1
2
3
4
5
6
7
8
9
10
11
# 4.1 css预处理 less
下载 less-loader
写配置
yarn add less-loader@8.0.0 less@4.1.1 -D
1module: { rules: [ { test: /\.css$/, use: ['style-loader', 'css-loader'] }, { //打包less文件 test:/\.less$/, use:['style-loader', 'css-loader','less-loader'] } ] },
1
2
3
4
5
6
7
8
9
10
11
12
13
# 5.webpack打包img
# 5.1打包css中的图片
下载loader
yarn add url-loader@4.1.1 file-loader@6.2.0 -D
1写配置-loader
{ test:/\.(png|jpg|gif)$/, //配置css中的图片打包 loader:'url-loader', //只有一个处理的loader的写法 //可以通过url-loader 将图片压缩为 base64编码格式的图片 //大图就不压缩 小图可以压缩 options:{ name: '[hash:16].[ext]', // 图片输出的名字hash长度16位 默认32位 limit: 30 * 1024, // 限制 小于30kb base64处理 } }
1
2
3
4
5
6
7
8
9
10
# 5.2 打包html中的图片
下载loader plugin html-loader html-webpack-plugin
配置loader
配置插件
优化/修复
yarn add html-loader@1.3.2 html-webpack-plugin@5.0.0-beta.1 -D
1{ test:/\.html$/, //配置html文件打包 loader:'html-loader' }
1
2
3
4
//引入html打包的插件
const HtmlWebpackPlugin = require('html-webpack-plugin');
// 4. 插件
plugins: [
// new 插件名({
// 配置 key:value
// })
new HtmlWebpackPlugin({ //配置html打包的插件
template:'./src/index.html' //以哪个html文件作为打包的模板
})
],
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
注意:一共要优化及修复两个位置
- 设置publicPath='./'
//出口
output: {
path: path.resolve(__dirname, 'dist'), //绝对路径 所有的打包完成之后的文件都放在这个
filename: 'bundle.js', //资源打包完成之后生成的js文件
publicPath:'./' //打包完成之后的html文件引入其他资源的基础路径(相对路径)
},
1
2
3
4
5
6
2
3
4
5
6
设置图片打包的兼容冲突 (在css中图片打包的地方设置) esModule=false
{ test: /\.(png|jpg|gif)$/, //配置css中的图片打包 loader: 'url-loader', //只有一个处理的loader的写法 //可以通过url-loader 将图片压缩为 base64编码格式的图片 //大图就不压缩 小图可以压缩 options: { name: '[hash:16].[ext]', // 图片输出的名字hash长度16位 默认32位 limit: 30 * 1024, // 限制 小于30kb base64处理 esModule: false, //默认css中的图片以ES6的模块进行打包,但是html中图片只能以node下的commonjs规范进行打包 //有可能存在图片打包的冲突,要求直接将css打包模块设置为node的模块打包 }, },
1
2
3
4
5
6
7
8
9
10
11
12
# 5.3 打包js中的图片
let imgBox = document.querySelector('.imgBox');
let img = document.createElement('img');
img.src = require('../img/zxy.jpg');
imgBox.appendChild(img);
1
2
3
4
2
3
4
# 6.打包iconfont 字体图标
下载loader file-loader
配置loader
yarn add file-loader -D
1{ test:/\.(eot|svg|ttf|woff|woff2)$/, //配置iconfont文件打包 loader:'file-loader' }
1
2
3
4
注意:iconfont.css文件要当成模块进入到 入口js文件(index.js)
//引入字体图标 index.js
require('../fonts/iconfont.css');
1
2
2
<!-- 使用iconfont -->
<i class="iconfont icon-user"></i>
1
2
2
# 7.打包ES6代码为ES5
下载loader 和插件
配置loader
新建并配置.babelrc文件
yarn add babel-core babel-loader@7.1.5 babel-preset-es2015 -D #安装loader和插件
1{ test: /\.js$/, loader: 'babel-loader', // loader 编译es6为es5 exclude: /node_modules/ // 排除 }
1
2
3
4
5{ "presets": [ "es2015" ] }
1
2
3
4
5
# 8.文件目录整理
# 8.1 整理css目录
提取js中的css 压缩css
yarn add mini-css-extract-plugin@1.4.1 optimize-css-assets-webpack-plugin@5.0.4 -D
1
//引入 提取js中的css代码的插件
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
//将css文件及代码进行极致压缩s
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin');
1
2
3
4
2
3
4
new MiniCssExtractPlugin({
filename: 'css/[name].css' // 输出到css文件夹里
}),
new OptimizeCssAssetsWebpackPlugin()
1
2
3
4
2
3
4
注意1:配置了 提取js中的css 形成单独的css文件 需要更改 css的loader 及less的loader的配置
注意2:修复css文件中 导入的资源路径出错问题
{
test: /\.css$/, //正则表达式 匹配需要应用这个规则的所有文件是哪些
// use: ['style-loader', 'css-loader'] //使用哪些三方包去处理匹配出来的这些文件
//css-loader:将css文件能够让webpack识别
//style-loader: 将js中的css代码提取到页面上 写到style标签里面
//提取js中的css形成独立的css文件 不将css通过style的方式写入页面
use:[{
loader: MiniCssExtractPlugin.loader,
options: {
publicPath: '../'
}
},'css-loader']
},
{
test: /\.less$/, //配置less处理器
// use: ['style-loader', 'css-loader', 'less-loader']
use: [{
loader: MiniCssExtractPlugin.loader,
options: {
publicPath: '../'
}
}, 'css-loader', 'less-loader']
},
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 8.2 整理 js目录
//出口
output: {
path: path.resolve(__dirname, 'dist'), /
filename: 'js/[name].js', //资源打包完成之后生成的js文件
publicPath: './'
},
1
2
3
4
5
6
2
3
4
5
6
# 8.3 整理img 目录
{
test: /.(jpg|png|gif)$/,
loader: 'url-loader',
options: {
name: '[hash:16].[ext]',
limit: 70 * 1024,
esModule: false,
outputPath:'img' //输出目录
}
},
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
# 8.4 整理fonts 目录
{
test: /.(eot|svg|ttf|woff|woff2)$/,
loader: 'file-loader',
options:{
outputPath:'fonts' //输出的目录
}
}
1
2
3
4
5
6
7
2
3
4
5
6
7
# 9.开发服务器配置
生产环境与开发环境的打包命令的配置
yarn add webpack-dev-server@3.11.2 -D #局部安装 webpack-dev-server
1
//webpack.config.js
// 开发服务器 配置【】
devServer: {
contentBase: path.resolve(__dirname, 'dist'), // 启动服务器目录
compress: true, // 启动gzip
port: 8080, // 端口 8080 80 8081 8082
open: true, // 自动打开服务
publicPath: '/', // 静态资源查找路径
openPage: 'index.html', // 打开的页面
},
target: 'web', // 目标是浏览器
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
//package.json
"scripts": {
"serve":"webpack serve", #启动本地开发服务 自带热更新(不用每次更改代码在进行打包)
"build":"webpack" #构建线上项目
},
1
2
3
4
5
6
2
3
4
5
6
通过npm命令 打包
npm run serve #打本地开发环境的包 npm run build #打线上生成环境的包
1
2通过yarn 命令打包
yarn serve #打本地开发环境的包
yarn build #打线上生成环境的包
1
2
2
# 10.开发环境和生产环境的区分
通过插件可以拿到 打包命令对应的开发环境和生产环境的变量,将变量可以写入到webpack.config.js配置文件中 ,mode的值就可以动态加载
安装插件
配置 package.json 文件 scripts
mode的值 获取
yarn add cross-env@7.0.3 -D #安装插件
1
#配置scripts
"scripts": {
"serve": "cross-env NODE_ENV=development webpack serve",
"build": "cross-env NODE_ENV=production webpack"
},
1
2
3
4
5
2
3
4
5
//修改webpack.config.js 中的mode 获取当前环境的变量
mode: process.env.NODE_ENV,
1
2
2
# 11.小结:webpack单页打包 完整配置
# 11.1 webpack.config.js
/**
* webpack.config.js 打包配置文件
*/
const path = require('path');
//引入html打包的插件
const HtmlWebpackPlugin = require('html-webpack-plugin');
//引入 提取js中的css代码的插件
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
//将css文件及代码进行极致压缩s
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin');
module.exports = {
entry: './src/js/index.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'js/[name].js',
publicPath: './'
},
module: {
rules: [
{
test: /.css$/,
use: [{
loader: MiniCssExtractPlugin.loader,
options: {
publicPath: '../'
}
}, 'css-loader']
},
{
test: /.less$/,
use: [{
loader: MiniCssExtractPlugin.loader,
options: {
publicPath: '../'
}
}, 'css-loader', 'less-loader']
},
{
test: /.(jpg|png|gif)$/,
loader: 'url-loader',
options: {
name: '[hash:16].[ext]',
limit: 70 * 1024,
esModule: false,
outputPath: 'img'
}
},
{
test: /.html$/,
loader: 'html-loader'
},
{
test: /.(eot|svg|ttf|woff|woff2)$/,
loader: 'file-loader',
options: {
outputPath: 'fonts' //输出的目录
}
},
{
test: /\.js$/,
loader: 'babel-loader', // loader 编译es6为es5
exclude: /node_modules/ // 排除
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html',
filename: 'index.html'
}),
new MiniCssExtractPlugin({
filename: 'css/[name].css' // 输出到css文件夹里
}),
new OptimizeCssAssetsWebpackPlugin()
],
mode: process.env.NODE_ENV,
devServer: {
contentBase: path.resolve(__dirname, 'dist'),// 启动服务器目录
compress: true,// 启动gzip
port: 8080, // 端口 8080 80 8081 8082
open: true, // 自动打开服务
publicPath: '/', // 静态资源查找路径
openPage: 'index.html', // 打开的页面
},
target: 'web', // 目标是浏览器
}
1
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
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
# 11.2 package.json
{
"name": "webpack-demo",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"devDependencies": {
"babel-core": "^6.26.3",
"babel-loader": "7.1.5",
"babel-preset-es2015": "^6.24.1",
"cross-env": "7.0.3",
"css-loader": "5.2.0",
"file-loader": "6.2.0",
"html-loader": "1.3.2",
"html-webpack-plugin": "5.0.0-beta.1",
"less": "4.1.1",
"less-loader": "8.0.0",
"mini-css-extract-plugin": "1.4.1",
"optimize-css-assets-webpack-plugin": "5.0.4",
"style-loader": "2.0.0",
"url-loader": "4.1.1",
"webpack": "5.11.0",
"webpack-cli": "4.10.0",
"webpack-dev-server": "3.11.2"
},
"scripts": {
"serve": "cross-env NODE_ENV=development webpack serve",
"build": "cross-env NODE_ENV=production webpack"
}
}
1
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
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
# 11.3 .babelrc
{
"presets": [
"es2015"
]
}
1
2
3
4
5
2
3
4
5
# 11.4 完整的目录结构
编辑 (opens new window)
上次更新: 2022/09/20, 00:36:06