什么是webpack?

本质上,webpack 是一个用于现代 JavaScript 应用程序的 静态模块打包工具。当 webpack 处理应用程序时,它会在内部从一个或多个入口点构建一个 依赖图(dependency graph),然后将你项目中所需的每一个模块组合成一个或多个 bundles,它们均为静态资源,用于展示你的内容。

主要功能

兼容问题

解决Javascript高级语法低版本浏览器的兼容问题。

我们可以放心使用高级的语法,webpack会在运行时自动转换成兼容的语法。

性能优化

规范化代码

代码压缩混淆

基本使用

安装和配置

安装至devDependencies节点中,仅在开发阶段中使用。

1
npm i webpack webpack-cli -D

在项目根目录创建webpack.config.js配置文件。

1
2
3
module.exports={
mode:'development' //用于指定构建模式,可选值:development、production
}

package.json中的scripts节点,新增dev脚本

1
2
3
"scripts":{
"dev":"webpack" //script节点下的脚本,可以通过npm run执行,如:npm run dev
}

webpack中的默认约定

webpack 4.x和5.x的版本中,有如下的默认约定:

  1. 默认的打包入口文件为src->index.js
  2. 默认的输出文件路径为dist->main.js 默认约定可以在webpack.config.js中进行修改。

创建列表隔行变色项目

js

1
2
3
4
5
6
import $ from 'jquery'

$(()=>{
$('li:odd').css('background-color','red');
$('li:even').css('background-color','blue');
})

html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>奇偶行变色</title>
<script src="index.js"></script>
</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>
</ul>
</body>
</html>

第一个报错:

Uncaught SyntaxError: Cannot use import statement outside a module

问题出在js第一行import $ from 'jquery'

解决方案:

1
npm run webpack

修改导入文件

1
<script src="../dist/main.js"></script>

使用代码压缩混淆

将配置文件webpack.config.js中的mode修改为production

1
2
3
module.exports={
mode:'production' //用于指定构建模式,可选值:development、production
}

压缩时间较长,一般不会在开发阶段使用。

修改默认约定

webpack.config.js中进行修改。

entry:设置入口文件。

output:设置输出文件的目录和文件名。

1
2
3
4
5
6
7
8
9
const path=require('path');
module.exports={
entry:path.join(__dirname,'./src/index1.js'),
output:{
path:path.join(__dirname,'./dist'),
filename:'main1.js'
},
mode:'development' //用于指定构建模式,可选值:development、production
}

webpack插件

插件的作用

第三方插件能够拓展webpack的能力。

webpack-dev-server

1
npm i webpack-dev-server
  • 类似node.js节点使用nodemon工具
  • 每当修改源代码,webpack会自动进行项目的打包和构建

webpack-dev-server打包的js文件存储在内存中。

html-webpack-plugin

1
npm i html-webpack-plugin
  • webpack中的HTML插件(类似于一个模板引擎插件)
  • 可以通过该插件自定义index.html页面的内容
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
const path=require('path');
//1.导入HTML插件
const HtmlPlugin=require('html-webpack-plugin');
//2.创建HTML对象
const htmlPlugin=new HtmlPlugin({
template:'./src/index.html', //指定源文件的位置
filename:'./index.html' //指定目标文件的位置
});
//3.通过plugins节点,使htmlPlugin实例生效

module.exports={
entry:path.join(__dirname,'./src/index1.js'),
output:{
path:path.join(__dirname,'./dist'),
filename:'main1.js'
},
mode:'development', //用于指定构建模式,可选值:development、production
plugins:[htmlPlugin],//加载并调用插件
}

devServer节点

webpack.config.js中配置。

可以配置自动打开浏览器、设置端口号、IP地址等。

1
2
3
4
5
devServer:{
open:true,
port:8081,
host:'127.0.0.1'
}

webpack loader

webpack默认只能处理js文件。

webpack处理不了的,需要调用loader加载器才能正常打包。

loader用于协助webpack打包处理特定的文件模块。

  • css-loader
  • less-loader
  • babel-loader

使用和配置css-loader

1
npm i style-loader css-loader -D

配置webpack.config.js文件。新增module节点。

1
2
3
4
5
6
module: {//所有使用第三方文件模块的匹配规则
rules: [ //文件后缀名匹配规则
{ test: /\.css$/,use:['style-loader','css-loader']}
//test表示文件类型,use表示要调用的loader。
]
}

使用和配置url-loader、file-loader

用于处理样式表中与url路径相关的文件。

1
npm i url-loader file-loader -D

webpack.config.js中配置rules

1
2
3
4
5
6
module: {//所有使用第三方文件模块的匹配规则
rules: [ //文件后缀名匹配规则
{ test: /\.css$/,use:['style-loader','css-loader']},
{test:/\.jpg|png|gif$/,use:'url-loader?limit=114'}
]
}

?为loader的参数项:limit用于指定图片的大小,单位是字节。当图片小于等于limit时,url会被转换为base64格式。

使用和配置babel-loader

应用于webpack都处理不了的js文件。

1
npm i babel-loader @babel/core @babel/plugin-proposal-decorators -D

配置webpack.config.js文件。

1
2
3
4
5
6
module: {//所有使用第三方文件模块的匹配规则
rules: [ //文件后缀名匹配规则
{ test: /\.css$/,use:['style-loader','css-loader']},
{test:/\.js$/,use:['babel-loader'],exclude:/node_modules/}//注意必须排除node_modules目录。
]
}

创建babel.config.js配置一些插件,如:用于处理修饰器的@babel/plugin-proposal-decorators插件。

1
2
3
4
module.exports={
//声明babel可用的插件
plugins:[['@babel/plugin-proposal-decorators',{legacy:true}]]
}

js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import $ from 'jquery'
import './css/index.css'

///////////babel-loader////////////
//定义修饰器
function info(target) {
target.info = 'Person info';
}
//定义普通类
@info
class Person {}
//打印普通类中的属性info的值
console.log(Person.info);
////////////////////////////////////
$(function () {
$('li:even').css('background-color', 'pink');
$('li:odd').css('background-color', '');
})

clean-webpack-plugin

用于自动删除旧的dist文件。

1
npm install --save-dev clean-webpack-plugin

修改webpack.config.js文件。

1
2
3
4
5
6
7
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const webpackConfig = {
plugins: [
new CleanWebpackPlugin(),
],
};
module.exports = webpackConfig;

打包发布

将原本在内存中的文件保存到磁盘中。

package.json文件中的scripts脚本中,新增build命令。

1
2
3
4
5
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"dev": "webpack serve",
"build":"webpack --mode production"
},

不添加mode参数也能实现打包,加上后可实现压缩混淆。

分类存放

将所有js文件放在js目录

修改webpack.config.js配置文件。在filename中添加目录js/

1
2
3
4
output: {
path: path.join(__dirname, './dist'),
filename: 'js/main1.js'
},

将所有的图片资源放在images目录

修改webpack.config.js文件。添加outputPath参数,使用&进行连接。

1
2
3
4
5
6
7
module: {//所有使用第三方文件模块的匹配规则
rules: [ //文件后缀名匹配规则
{ test: /\.css$/,use:['style-loader','css-loader']},
{test:/\.jpg|png|gif$/,use:'url-loader?limit=8890&outputPath=images'},
{test:/\.js$/,use:['babel-loader'],exclude:/node_modules/}//注意必须排除node_modules目录。
]
}

Source Map

SourceMap存储着错误在源文件的位置信息。

修改webpack.config.js配置文件,开启SourceMap。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
module.exports = {
entry: path.join(__dirname, './src/index1.js'),
output: {
path: path.join(__dirname, './dist'),
filename: 'js/main1.js'
},
mode: 'development', //用于指定构建模式,可选值:development、production
plugins: [htmlPlugin, cleanWebpackPlugin],//加载并调用插件
devServer: {
open: true,
port: 8081,
host: '127.0.0.1'
},
module: {//所有使用第三方文件模块的匹配规则
rules: [ //文件后缀名匹配规则
{ test: /\.css$/, use: ['style-loader', 'css-loader'] },
{ test: /\.jpg|png|gif$/, use: 'url-loader?limit=889&outputPath=images' },
{ test: /\.js$/, use: ['babel-loader'], exclude: /node_modules/ }//注意必须排除node_modules目录。
]
},
devtool:'eval-source-map',
}

devtool:'eval-source-map'

在生成环境下,为了安全建议关闭SourceMap,也可以设置成只定位行号,不暴露源码。

1
devtool:'nosources-source-map',

image-20230727151657456

@在webpack中的使用

@表示src目录,如:import xxx from @/css/index.css

一键生成webpack项目

如何自动生成?