准备

1.需要安装node.js,当前教学版本为v12.22.12

2.一个IDE,这里使用vs code ,当前版本为v1.70.2

初始化一个项目

在一个位置,我们新建一个文件夹,并且进入该文件夹。

1
2
mkdir webpack_study
cd webpack_study

初始化一个node项目。

1
npm init -y

此时,在该目录下会有一个package.json文件

1
2
.
└── package.json

我们在根目录创建三个文件index.html,index.js,outside.js

1
2
3
4
5
.
├── index.html
├── index.js
├── outside.js
└── package.json

index.html内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>index</title>
</head>
<body>
<div id="app">

</div>
<!-- 引入两个js文件 -->
<script src="./outside.js"></script>
<script src="./index.js"></script>

</body>
</html>

index.js内容如下:

1
updateDom ('app','我是主页')

outside.js内容如下:

1
2
3
4
const updateDom = (id, content) => {
let div = window.document.getElementById(id);
div.innerText = content
};

我们打开这个index.html

思考问题

让我们思考几个问题。

如果在index.html中调换 index.htmloutside.html ,看看效果如何?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<!DOCTYPE html>
<html lang="zh">

<head>
<meta charset="UTF-8">
<title>index</title>
</head>

<body>
<div id="app">
</div>
<!-- 引入两个js文件 -->
<script src="./index.js"></script>
<script src="./outside.js"></script>
</body>

</html>

可见,如果不小心调换js的引用顺序,则会造成引用的函数没有先声明就使用了。

在本例子中,虽然文件只有两个,但是如果我们文件特别多,比如30个,50个,100个等等,那么就会存在一些声明重复,变量重复等等,这样会导致项目变得越来越臃肿,变得难以维护起来。所以,我们提出了一个新思路:模块化打包

因此,webpack应运而生。

安装webpack

在文件根目录下,我们执行安装命令:

1
npm i webpack webpack-cli -D

-D 是开发依赖

安装完成后,执行一下命令查看是否有输出:

1
npx webpack -v

可以看到输入如下:

npx是npm5.2之后提供的新功能。可以通过npx -v来检测它的版本。 在这里,我们通过它来调用项目安装的模块,它在运行时会在node_modules/.bin中去检查命令是否存在。webpack-dev-server我们稍后再讲。

模块化代码

在把代码按照模块分割改动之前,我们先复原index.html中的引用顺序,接着开始模块分割。即在outside.js导出,在index.js导入。下面我们来改造一下代码。这里使用commonjs规范。如果你还不太了解,可以点击这里去阅读学习。

outside.js

1
2
3
4
5
6
7
8
9
const updateDom = (id, content) => {
let div = window.document.getElementById(id);
div.innerText = content
};

module.exports={
updateDom
}

index.js

1
2
3
4
const {updateDom}=require('./outside')

updateDom ('app','我是主页')

现在,我们来打开浏览器看一下:

报错了,模块没有定义。因为require这种模块化的处理方式是无法在浏览器中运行的。这时,webpack就派上用场了。

对index.js打包

我们在终端输入:

1
npx webpack 

为了以后打包方便,我们可以在package.json配置好对应的启动脚本。可参考「这里

输出的结果如下图所示。

我们查看当前的文件目录,如上图标注2所示,你会发现多了一个dist文件夹,里面有main.js的一个js文件。

打开main.js看一下,发现代码已经压缩了:

我们把压缩后的main.js引入到index.html中,然后在浏览器中打开看看。

浏览器不再报错,页面正常加载。

从最后的结果可看出,webpack会分析入口文件中的引用关系,把相关的文件合成在一起,变成一个.js文件。

好啦,到了这里,我们已经开始入门了,接下来让我们深入了解一下webpack

webpack概念

webpack的核心概念如下所示,官网解释为

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

这里我们现在不用全部着急着去理解所有的内容,一切先从实践中开始。当然,你可以点击对应的链接去官方文档阅读。不妨我们先从配置文件入手吧。

1.模式(mode)

像所有的软件一样,webpack也有自己的默认配置目录,这个配置文件就是webpack.config.js

我们先在项目根目录下创建一个名为webpack.config.js。其内容如下:

1
2
3
module.exports={
mode: 'development',//打包方式
}

这个文件的意义是导出一个配置项:用来对webpack的打包行为做设置。在操作层面,就是学习如何去使用这个文件。

上面的代码中,配置了打包方式,现在试着再打包一下,看看main.js有什么变化。

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
/*
* ATTENTION: The "eval" devtool has been used (maybe by default in mode: "development").
* This devtool is neither made for production nor for readable output files.
* It uses "eval()" calls to create a separate source file in the browser devtools.
* If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
* or disable the default devtool with "devtool: false".
* If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
*/
/******/ (() => { // webpackBootstrap
/******/ var __webpack_modules__ = ({

/***/ "./index.js":
/*!******************!*\
!*** ./index.js ***!
\******************/
/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => {

eval("const {updateDom}=__webpack_require__(/*! ./outside */ \"./outside.js\")\n\nupdateDom ('app','我是主页')\n\n\n//# sourceURL=webpack://webpack_study/./index.js?");

/***/ }),

/***/ "./outside.js":
/*!********************!*\
!*** ./outside.js ***!
\********************/
/***/ ((module) => {

eval("const updateDom = (id, content) => {\n let div = window.document.getElementById(id);\n div.innerText = content\n};\n\n module.exports={\n updateDom\n }\n \n\n//# sourceURL=webpack://webpack_study/./outside.js?");

/***/ })

/******/ });
/************************************************************************/
/******/ // The module cache
/******/ var __webpack_module_cache__ = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/ // Check if module is in cache
/******/ var cachedModule = __webpack_module_cache__[moduleId];
/******/ if (cachedModule !== undefined) {
/******/ return cachedModule.exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = __webpack_module_cache__[moduleId] = {
/******/ // no module.id needed
/******/ // no module.loaded needed
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/************************************************************************/
/******/
/******/ // startup
/******/ // Load entry module and return exports
/******/ // This entry module can't be inlined because the eval devtool is used.
/******/ var __webpack_exports__ = __webpack_require__("./index.js");
/******/
/******/ })()
;

明显可以看到,main.js比之前多出了很多内容,我们能够清晰的看到打包之前到源码。没错,这个是开发模式,不妨现在把mode调整成production,再看看main.js

1
(()=>{var e={810:e=>{e.exports={updateDom:(e,t)=>{window.document.getElementById(e).innerText=t}}}},t={};function r(o){var n=t[o];if(void 0!==n)return n.exports;var p=t[o]={exports:{}};return e[o](p,p.exports,r),p.exports}(()=>{const{updateDom:e}=r(810);e("app","我是主页")})()})();

很明显,main.js变得简洁起来,去掉了提示,同时也压缩了一些不必要的换行,加入了一定的混淆变量。

我们再换成**none**试试:

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
/******/ (() => { // webpackBootstrap
/******/ var __webpack_modules__ = ([
/* 0 */,
/* 1 */
/***/ ((module) => {

const updateDom = (id, content) => {
let div = window.document.getElementById(id);
div.innerText = content
};

module.exports={
updateDom
}


/***/ })
/******/ ]);
/************************************************************************/
/******/ // The module cache
/******/ var __webpack_module_cache__ = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/ // Check if module is in cache
/******/ var cachedModule = __webpack_module_cache__[moduleId];
/******/ if (cachedModule !== undefined) {
/******/ return cachedModule.exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = __webpack_module_cache__[moduleId] = {
/******/ // no module.id needed
/******/ // no module.loaded needed
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/************************************************************************/
var __webpack_exports__ = {};
// This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk.
(() => {
const {updateDom}=__webpack_require__(1)

updateDom ('app','我是主页')

})();

/******/ })()
;

看来,webpack并没有把文件给压缩起来,他只是把两个文件放在了一起,没有像development那样详细。

好啦,到这里,我们搞清楚了webpack中的一个配置点mode,它有以下属性值:

  • production. <– 默认值
  • none.
  • development.

2.入口(entry)

在webpack中,默认的入口和出口分别是:

  • 默认入口是:./src/index.js
  • 默认输出是:./dist/main.js

也就是说,如果直接在根目录下运行webpack,它会直接去找.src下的index.js,并把打包之后的代码放在dist/main.js下。没有dist目录则会生成dist目录。

我们在根目录新建一个src文件夹,并且把index.jsoutside.js移动到它目录中:

1
2
3
src
├── index.js
└── outside.js

在配置文件webpack.config.js我们先不给它一个入口,保持默认:

1
2
3
module.exports={
mode: 'development',
}

运行npx webpack打包一下看看。

1
2
3
4
5
 npx webpack       
asset main.js 2.65 KiB [emitted] (name: main)
./src/index.js 73 bytes [built] [code generated]
./src/outside.js 158 bytes [built] [code generated]
webpack 5.74.0 compiled successfully in 85 ms

看来还是可以成功打包的。

但是,在实际的项目中,这种直接在默认目录的情况比较少。例如,js全部都放在一个文件夹里,css也是如此。

src目录下,我们新建一个js文件夹,把两个js文件丢进去,并且把index.js改名为main.js

1
2
3
4
src
└── js
├── main.js
└── outside.js

接着,在webpack.config.js的配置项中添加entry项。

1
2
3
4
module.exports = {
mode: 'development',
entry: './src/js/main.js' //入口文件
}

重新打包试试看?🤓。

当然,entry可以配置多个文件多个入口等,不过此笔记不做展开,等你读完这篇入门笔记之后,你可以去挑对应官方文档章节去阅读。

3.输出(output)

我们在webpack.config.js中设置output项:

1
2
3
4
5
6
7
module.exports = {
mode: 'development',
entry: './src/js/main.js',
output: {
filename: 'bundle.js',
},
}

此配置将一个单独的 bundle.js 文件输出到 dist 目录中。

运行看看?

1
2
3
main
├── bundle.js
└── main.js // 这个是webpack默认的配置

现在,我们制定一个输出位置:把出口文件设置为在build目录下的bundle.js。为此,webpack就得这样配置:

1
2
3
4
5
6
7
8
9
10
//引入nodejs中的核心模块
const path = require('path')
module.exports = {
mode: 'development',
entry: './src/js/main.js',
output: {
path: path.join(__dirname, '/build'), // 决定出口文件在哪里
filename: 'bundle.js' // 设置出口文件的名字。默认情况下,它叫main.js
},
}

运行看看?

1
2
build
└── bundle.js

看来已经有啦。这里对路径说明一下,output中的path用来指定打包后的路径。注意:它必须是绝对路径。所以,这里引用path模块中的join和__dirname来生成绝对路径。

如果path中的路径不存在,它会自动创建。

4.loader

webpack看来 一切皆模块,图片,样式文件,js文件。 但是webpack默认只能处理js模块,对于非js的内容,例如css, less文件,图片文件等等,它就需要一些帮手来处理了。这些帮手就是loader。webpack 可以使用 loader 来预处理文件。这允许你打包除 JavaScript 之外的任何静态资源。你可以使用 Node.js 来很简单地编写自己的 loader。

例如,用css-loader来处理css引入的问题。

css-loader

在src文件下,创建src/css/public.css 文件。

1
2
3
4
body,html{
padding:0;
font-size:14px;
}

在src文件下,创建src/css/style.css 文件。

1
2
3
4
5
6
7
8
9
10
@import "public.css";
div {
border: 4px solid #ccc;
width: 50%;
height: 200px;
margin: 30px auto;
box-shadow: -9px 9px 7px 0px #ccc;
background-color: #f387d8;
text-align: center;
}

css的@import语句用来导入另一个css文件。

最后,在src/js/main.js中导入css

1
2
3
const {updateDom}=require('./outside')
import "../css/style.css"
updateDom ('app','我是主页')

假如,我们没有加css-loader,我们打包看看,结果会得到如下报错:

image-20220906105028891

上面报错的原因是:webpack把.css文件内容当作了js代码来运行,那当然会报错了。所以,解决方法是安装相应的loader来处理。

1
npm i css-loader -D 

修改webpack.config.js文件,添加module。语法如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//引入nodejs中的核心模块
const path = require('path')
module.exports = {
mode: 'development',
entry: './src/js/main.js',
output: {
path: path.join(__dirname, '/build'), // 决定出口文件在哪里
filename: 'bundle.js' // 设置出口文件的名字。默认情况下,它叫main.js
},
module: { // 处理非js模块
rules: [ // 规则
{
test: /\.css$/, // 正则测试
use: ['css-loader'] // loader
}
]
}
}

更改一下html中引入的js代码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<!DOCTYPE html>
<html lang="zh">

<head>
<meta charset="UTF-8">
<title>index</title>
</head>

<body>
<div id="app">
</div>
<!-- 引入新的bundle.js文件 -->
<script src="./build/bundle.js"></script>
</body>

</html>

运行一下,它不会报错。但是,页面上也并没有出现样式的效果。打包之后的文件中并没有包含css代码。

css样式生效会有两种条件,通过<link><style>标签引用,而css-loader只是能让你在.js中通过import来引入.css,如果你希望引入的css代码最终以style标签的方式插入到html页面中,则还需要安装一个style-loader

style-loader
1
npm i style-loader -D

安装好后,修改配置webpack.config.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//引入nodejs中的核心模块
const path = require('path')
module.exports = {
mode: 'development',
entry: './src/js/main.js',
output: {
path: path.join(__dirname, '/build'), // 决定出口文件在哪里
filename: 'bundle.js' // 设置出口文件的名字。默认情况下,它叫main.js
},
module: { // 处理非js模块
rules: [ // 规则
{
test: /\.css$/, // 正则测试
use: ['style-loader','css-loader'] // loader
}
]
}
}

在有多个loader的情况下,use数组中的loader执行顺序是从右到左的过程。即:

  • 先用css-loader来处理css
  • 再用style-loader把css代码插入到html中的style标签中。

打包好之后,我们来看一下效果:

image-20220908204634463

如图,css已经生效了。

Less-loader

假如,我们有less文件在项目中,如果需要解析,我们需要安装less-loader

我们在src目录的less目录下创建 index.less。

1
2
3
src
└── less
└── index.less

内容如下:

1
2
3
4
5
6
7
@import "../css/style.css";

body{
div {
color: rgb(255, 255, 255); // 改变字体颜色
}
}

因为我们直接把css给引入了,所以就在src/js/main.js中引入index.less

1
2
3
4
const {updateDom}=require('./outside')
// import "../css/style.css"
import '../less/index.less'
updateDom ('app','我是主页')

接着,我们引入less-loader

1
npm i less less-loader -D

安装好后,在webpack.config.js配置中添加对应的loader。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
//引入nodejs中的核心模块
const path = require('path')
module.exports = {
mode: 'development',
entry: './src/js/main.js',
output: {
path: path.join(__dirname, '/build'), // 决定出口文件在哪里
filename: 'bundle.js' // 设置出口文件的名字。默认情况下,它叫main.js
},
module: { // 处理非js模块
rules: [ // 规则
{
test: /\.css$/, // 正则测试
use: ['style-loader','css-loader'] // loader
},
{
test: /\.less$/, // 正则测试
use: ['style-loader', 'css-loader', 'less-loader'] // loader
}
]
}
}

在配置中,对于less文件的处理涉及三个loader,其处理顺序是less-loader => css-loader => style-loader。

less-loader:用来加载less文件,并处理成css
css-loader:用来加载css文件
style-loader:用来将css代码以style标签的格式插入到html文件中

好了,现在我们打个包,试一下效果如何。

image-20220913175301558

less-loader生效了。

url-loader(可跳过)

我们处理完成了css,js,但是还差一个,文件。这里以图片为例,说明一下在 webpack 中图片的处理方法。

src文件下创建一个img文件夹,并且引入一张图片:

1
2
3
4
5
6
7
8
9
10
11
src
├── css
│ ├── public.css
│ └── style.css
├── img
│ └── dog.jpg <-----------------引入的图片
├── js
│ ├── main.js
│ └── outside.js
└── less
└── index.less

接着,在less/index.less中引入该图片。

1
2
3
4
5
6
7
8
9
10
@import "../css/style.css";
body{
div {
color: #ffffff;
text-shadow: 1px 1px 2px black;
background: url('../img/dog.jpg');
background-size: cover;
background-repeat: no-repeat;
}
}

执行一下打包,我们可以看到,在设置好的输出目录下有图片了。

假如我们想对该图片进行优化,例如压缩,重命名等等,我们可以引入url-loaderfile-loader.

在当前文件根目录下执行:

1
npm i url-loader file-loader -D

webpack.config.js配置文件中设置如下:

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
//引入nodejs中的核心模块
const path = require('path')
module.exports = {
mode: 'development',
entry: './src/js/main.js',
output: {
path: path.join(__dirname, '/build'), // 决定出口文件在哪里
filename: 'bundle.js' // 设置出口文件的名字。默认情况下,它叫main.js
},
module: { // 处理非js模块
rules: [ // 规则
{
test: /\.css$/, // 正则测试
use: ['style-loader', 'css-loader'] // loader
},
{
test: /\.less$/, // 正则测试
use: ['style-loader', 'css-loader', 'less-loader'] // loader
},
{
test:/\.(png|jpe?g|gif|svg)$/,
use:[
{
loader:'url-loader',
options:{
name:"img/[name].[hash:6].[ext]", //打包之后的命名格式
limit: 15 * 1024 //单位:B 小于15KB的会用base64转换,大于15KB的就复制图片到dist目录,用http请求
}
}
]
}

]
}
}

5.插件(plugin)

loader 用于转换某些类型的模块,而插件则可以用于执行范围更广的任务。包括:打包优化,资源管理,注入环境变量等等。plugin是⽤于扩展webpack的功能,各种各样的plugin⼏乎可以让webpack做任何与构建相关关的事情。plugin的配置很简单,plugins配置项接收⼀个数组,数组⾥的每⼀项都是⼀个要使⽤的plugin的实例,plugin需要的参数通过构造函数传⼊。使⽤plugin的难点在于plugin本身的配置项,⽽不是如何在webpack中引⼊plugin,⼏乎所有webpack⽆法直接实现的功能,都能找到开源的plugin去解决,我们要做的就是去找更据⾃⼰的需要找出相应的plugin。

接下来我们就介绍一下常用的插件:

html-webpack-plugin

该插件能把我们⾃已写的.html⽂件复制到指定打包出⼝⽬录下,并引⼊相关的资源代码。为html⽂件中引⼊的外部资源如script、link动态添加每次compile后的hash,防⽌引⽤缓存的外部⽂件问题。可以⽣成创建html⼊⼝⽂件。

我们先安装它:

1
npm i html-webpack-plugin -D

之后,在webpack.config.js中引入配置:

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
//引入nodejs中的核心模块
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin') <---------引入的插件
module.exports = {
mode: 'development',
entry: './src/js/main.js',
output: {
path: path.join(__dirname, '/build'), // 决定出口文件在哪里
filename: 'bundle.js' // 设置出口文件的名字。默认情况下,它叫main.js
},
module: { // 处理非js模块
rules: [ // 规则
{
test: /\.css$/, // 正则测试
use: ['style-loader', 'css-loader'] // loader
},
{
test: /\.less$/, // 正则测试
use: ['style-loader', 'css-loader', 'less-loader'] // loader
}
]
},
plugins: [
new HtmlWebpackPlugin()
]
}

配置好后,我们可以在输出目录中看到index文件啦。

1
2
3
4
build
├── 8ee1b44315556d16ca2b.jpg
├── bundle.js
└── index.html <----------
1
2
3
4
5
6
7
8
9
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Webpack App</title>
<meta name="viewport" content="width=device-width, initial-scale=1"><script defer src="bundle.js"></script></head>
<body>
</body>
</html>

到这里大家也发现了,在title位置它自己默认为Webpack App,假如我们有自己想要的名字,能够配置嘛?答案是可以的。我们可以这样修改配置文件:

1
2
3
4
5
6
7
plugins: [
new HtmlWebpackPlugin({
title: 'My App',
template: 'index.html', // 以当前目录下的index.html 作为模板
filename: 'admin.html' // 在 output.path 目录下生成 admin.html 文件
})
]

当然,该插件的功能不仅仅只有这些,具体情况可以点击这里查看GitHub官方文档或者自行搜索对应的插件教程。

clean-webpack-plugin

clean-webpack-plugin是一个清除文件的插件。在每次打包后,磁盘空间会存有打包后的资源,在再次打包的时候,我们需要先把本地已有的打包后的资源清空,来减少它们对磁盘空间的占用。插件clean-webpack-plugin就可以帮我们做这个事情。

安装先:

1
npm i clean-webpack-plugin -D

配置一下webpack.config.js

1
2
3
4
5
6
7
8
9
10
const path = require('path');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
module.exports = {
...
...
...
plugins:[
new CleanWebpackPlugin() <------ 直接引入进来
]
};

我们可以在打包目录下新建一些不需要的文件:

1
2
3
4
5
6
7
build
├── 8ee1b44315556d16ca2b.jpg
├── a.txt <-----
├── admin.html
├── b.txt <-----
├── bundle.js
└── index.html <-----

然后运行打包命令看看。

1
2
3
4
5
build
├── 8ee1b44315556d16ca2b.jpg
├── admin.html
└── bundle.js

不要的文件已经清空了。

6.实时预览

我们使用vue-cli脚手架的时候,当我们更新一下代码,脚手架会自动帮我们重新渲染,这个是因为脚手架自动帮我们重新发布并且更新。当然,核心离不开webpack-dev-server

我们来安装一下它:

1
npm i webpack-dev-server -D

接下来,在配置文件中添加如下信息配置:

1
2
3
4
5
6
7
8
9
10
module.exports = {
// 其他省略....
// 配置 webpack-dev-server的选项
devServer: {
host: '127.0.0.1', // 配置启动ip地址
port: 10088, // 配置端⼝
open: true // 配置是否⾃动打开浏览器
}
}

此外,我们配置一个专属脚本,用来启动该功能。找到packge.json文件,加入脚本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
{
"name": "webpack_study",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"bulid": "webpack",
"serve": "webpack-dev-server" <----------
}
...
...
}

启动一下康康👀。

1
npm run serve