webbpack导图
构建工具的诞生
- 实际的工作场景中我们往往会确定一个入口文件,例如叫做
index.js文件
,该文件会引入所有依赖文件,例如.less样式文件
、.sass样式文件
、Jquery等第三方文件
,有的这些文件是无法被浏览器解析直接呈现出来的,如果我们一个一个的手动去调整文件在大型项目中是十分繁琐易错的,所以我们借助构建工具来帮我们完成这些事情。
- webpack是构建工具的一种。它可以将浏览器不能识别的文件或者语法魔法般巧妙的让浏览器能够读懂并识别显示出来
- webpack基本工作流程:
-
- 确定入口文件,webpack会去分析该入口文件的所有依赖,确定好所需的依赖关系后将它们捆绑为代码块(chuck)
-
- 在通过各项处理将chuck解析成浏览器能够识别并读懂的文件例如.less转为.css,.js转为.js(向下兼容)等等打包过程,最后输出出去(输出文件叫做bundle)。
-
- 本质上,webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler)。当 webpack 处理应用程序时,它会递归地构建一个依赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个 bundle。
webpack的五个核心概念和基本模板
- Entry:入口(Entry)指示 webpack 以哪个文件为入口起点开始打包,分析构建内部依赖图。
- Ouput:输出(Output)指示 webpack 打包后的资源 bundles 输出到哪里去,以及如何命名。
- Loader:Loader 让 webpack 能 够去处理那些
非 JavaScript文件
(webpack 自 身 只 理 解 JavaScript)。___Loader使用方式:先下载再使用
- Plugins:插件(Plugins)可以用于执行范围更广的任务。插件的范围包括,从打包优化和压缩, 一直到重新定义环境中的变量等。___Plugins使用方式:先下载再引入再使用
- Mode:模式(Mode)指示 webpack 使用相应模式的配置。
选项 |
描述 |
特点 |
development |
会将 DefinePlugin 中 process.env.NODE_ENV 的值设置 为 development。启用 NamedChunksPlugin 和 NamedModulesPlugin |
能让代码本地调试 运行的环境 |
production |
会将 DefinePlugin 中 process.env.NODE_ENV 的值设置 为 production。启用 FlagDependencyUsagePlugin, FlagIncludedChunksPlugin, ModuleConcatenationPlugin, NoEmitOnErrorsPlugin, OccurrenceOrderPlugin, SideEffectsFlagPlugin 和 TerserPlugin和UglifyJsPlugin |
能让代码优化上线 运行的环境 |
module.exports = {
//入口
entry: '',
//出口
output: {
},
// loader的配置
module: {
rules: [
// 详细loader配置
// 不同文件处理配置不同loader处理
// 一个loader配置写在一个对象{}里
{},
{}
]
},
// plugins的配置
plugins: [
// 详细plugins的配置
],
// 模式
mode: 'development||production' //开发模式或者生产模式
}
webpack的初体验
- 初始化配置webpack:
-
-
cnpm i webpack webpack-cli -g
全局安装webpack和webpack-cli
-
- 全局安装遇到之前有安装过的包会发生新的安装包覆盖旧的安装包(也可以不选择全局安装)
-
cnpm i webpack webpack-cli --save-dev
安装全局依赖之后再在本地开发环境中安装这两个依赖包
-
- 遇到的第一个问题:终端显示:webpack : 无法加载文件
C:\Program Files\nodejs\webpack.ps1,因为在此系统上禁止运行脚本。
第一个问题的解决方案:先以管理员的身份运行vscode在打开终端执行输入: get-ExecutionPolicy
显示Restricted
,表示状态是禁止的然后在执行:set-ExecutionPolicy RemoteSigned
这时再执行get-ExecutionPolicy就显示RemoteSigned
,此时在进行打包就没有问题了
- 编译打包应用:
-
- 构建目录创建文件:通常确定一个入口文件,在这个文件中去引入整个文件所需要的所有资源
-
- 使用开发环境可以运行指令:
webpack ./src/index.js -o ./build/built.js --mode=development
。webpack会以 ./src/index.js
为入口文件开始打包,打包后输出到 ./build/built.js
。整体打包环境是开发环境
-
- 使用生产环境以运行指令:
webpack ./src/index.js -o ./build/built.js --mode=production
。webpack会以 ./src/index.js
为入口文件开始打包,打包后输出到 ./build/built.js
。整体打包环境是生产环境
- 结论:
-
- webpack能处理js/json资源,不能处理css/img等其他资源
-
- 生产环境和开发环境将ES6模块化编译成浏览器能识别的模块化
-
-
- 不能将 js 的 es6 基本语法转化为 es5 以下语法(向下兼容)。
webpack开发环境的配置
- 构建目录并创建webpack的配置文件:webpack.config.js,该配置文件的作用是作用: 指示 webpack 干哪些活(当你运行 webpack 指令时,会加载里面的配置)
- webpack构建工具都是基于nodejs平台运行的,采用的模块化标准是CommonJs
- 当执行webpack指令时,会在
当前目录中的node_modules
去寻找下载包资源,如果在当前目录中没有node_modules会
依次往上级去寻找。
需求一:打包样式资源
- 该构造目录中src目录下的.css和.less是需要一同打包的资源,统一由入口文件index.js一起引入,执行webpack指令后,自动构建生成build/built.js。我们再自己创建一个build/index.html文件自己引入build/built.js文件,验证打包样式资源是否成功(下图是验证打包成功)。
- 该
webpack.config.js
的配置代码如下:
// resolve用来拼接绝对路径的方法
const { resolve } = require('path');
module.exports = {
// 入口起点
entry: './src/index.js',
// 输出
output: {
// 输出文件名
filename: 'built.js',
// 输出路径
// __dirname是nodejs的变量,代表当前文件(webpack.config.js)的目录绝对路径
path: resolve(__dirname, 'build')
},
// loader的配置
module: {
rules: [
// 详细loader配置
// 不同文件处理配置不同loader处理
{
// 匹配哪些文件
test: /\.css$/,
// 使用哪些loader进行处理
use: [
// use数组中loader执行顺序:从右到左,从下到上 依次执行
// 创建style标签,将js中的样式资源插入进行,添加到head中生效
'style-loader',
// 将css文件变成commonjs模块加载到输出的js文件中,里面内容是样式字符串
'css-loader'
]
},
{
test: /\.less$/,
use: [
'style-loader',
'css-loader',
// 将less文件编译成css文件
// 需要下载 less-loader和less
'less-loader'
]
}
]
},
// plugins的配置
plugins: [
// 详细plugins的配置
],
// 模式
mode: 'development', // 开发模式
// mode: 'production' //生产模式
}
- webpack的打包样式资源的大致流程:确定入口文件(
即index.js
),分析该入口文件的所有依赖(import './index.css';和import './index.less';
),确定好所需的依赖关系后将它们捆绑为代码块(chuck),在通过各项处理(即style-loader、css-loader、less-loader
)将chuck解析成浏览器能够识别并读懂的文件最后输出出去(输出文件叫做build/built.js
)。
css-loader会将css文件
以字符串的形式被打包进输出的build/built.js
中,下面是自动被构建的build/built.js
文件的内容:
- 在自己创建的
build/index.html文件
自己引入build/built.js文件时,style-loader配合css-loader使用
会将需要打包的样式资源以创建<style></style>标签
的方式自动添加到自己创建的html页面的<head></head>内
。
- 缺点是打包后的样式资源文件没有生成单独的一个个文件,而是被统一以字符串的形式被打包进build/built.js文件内。
- 自己创建的
build/index.html文件
的代码内容:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
//该文件是自己创建的
//但是只需要引入webpack帮我们自动构建的build/built.js
//这样就可以由其帮我们引入打包后的所有样式资源
//缺点是打包后的样式资源没有生成单独的一个个文件
<script src="./built.js"></script>
</body>
</html>
- 总结打包样式资源的方式:
-
- 不能单独的生成css文件然后通过
<link href="css/built.css" rel="stylesheet">
的方式去引入css文件,而是让构建工具自动帮我们在生成的build/index.html文件中以<style></style>
的方式插入到HTML页面的<head></head>
中。
需求二:打包HTML资源
- 在需求一打包样式资源中,
我们需要手动创建build/index.html文件并且自己引入build/built.js文件
,这是十分麻烦的,我们可以借助plugins的配置使用html-webpack-plugin
来帮我们自动打包HTML资源并自动引入打包后的资源。
- 该构造目录中,我们需要一个
模板HTML页面
,好让我们使用插件html-webpack-plugin
后复制这个HTML页面,并自动引入
打包输出的所有资源(JS/CSS等)。
- 并
自动引入
打包输出的所有资源(JS/CSS等)!!!!!
- 在终端执行
webpack命令
后,build目录会自动生成两个文件,其中的index.html
自动引入了./built.js
文件。
- 我们自己写的模板
src/index.html文件
的代码内容:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>webpack</title>
</head>
<body>
//根本没有自己引入script
<h1 id="title">hello html</h1>
</body>
</html>
- 执行webpack命令后自动创建的
build/index.html文件
的代码内容:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>webpack</title>
</head>
<body>
<h1 id="title">hello html</h1>
<script type="text/javascript" src="built.js"></script></body>
</html>
- 该
webpack.config.js
的配置代码如下:
/*
loader: 1. 下载 2. 使用(配置loader)
plugins: 1. 下载 2. 引入 3. 使用
*/
const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: './src/index.js',
output: {
filename: 'built.js',
path: resolve(__dirname, 'build')
},
module: {
rules: [
// loader的配置
]
},
plugins: [
// plugins的配置
// html-webpack-plugin
// 功能:默认会创建一个空的HTML,自动引入打包输出的所有资源(JS/CSS)
// 需求:需要有结构的HTML文件
new HtmlWebpackPlugin({
// 复制 './src/index.html' 文件,并自动引入打包输出的所有资源(JS/CSS)
template: './src/index.html'
})
],
mode: 'development'
};
需求三:打包图片资源
- 场景重现:我们在目录结构中的
src/index.html文件
中写上三个div块,通过src/index.less文件
以背景图的方式为三个div块
分别添加背景图片(例如background-image: url('./react.png')
),然后通过入口文件src/index.js
引入依赖(即import './index.less'
),此时我们执行webpack命令
后发现报错信息:
- 此时的
webpack.config.js
的配置为(尚不能处理图片资源):
const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: './src/index.js',
output: {
filename: 'built.js',
path: resolve(__dirname, 'build')
},
module: {
rules: [
{
test: /\.less$/,
// 要使用多个loader处理用use
use: ['style-loader', 'css-loader', 'less-loader']
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html'
})
],
mode: 'development'
};
- 解决通过
.less样式文件
来引入图片资源(例如使用background-image: url('./angular.jpg')
)的打包图片问题只需要使用url-loader和file-loader
- 此时的
webpack.config.js
的配置为(已经能处理通过.less样式文件
来引入图片资源的打包问题):
const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: './src/index.js',
output: {
filename: 'built.js',
path: resolve(__dirname, 'build')
},
module: {
rules: [
{
test: /\.less$/,
// 要使用多个loader处理用use
use: ['style-loader', 'css-loader', 'less-loader']
},
{
// 问题:默认处理不了html中img图片
// 处理图片资源
test: /\.(jpg|png|gif)$/,
// 使用一个loader
// 下载 url-loader file-loader
// url-loader依赖于file-loader
loader: 'url-loader',
options: {
// 图片大小小于8kb,就会被base64处理
// base64处理打包后不会单独生成一张图片
// base64处理后只存在于打包后的文件内(这里是存在build/built.js中)
// HTML页面会以base64的方式引入这张图片
// 优点: 减少请求数量(减轻服务器压力,服务器不会存着那么多张图片在)
// 缺点:图片体积会更大(文件请求速度更慢)
limit: 8 * 1024,
}
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html'
})
],
mode: 'development'
};
- 我们会发现在
src/index.html文件里
采用<img src="./angular.jpg" >
的方式引入图片时,在执行webpack指令打包后,自动构建的built/index.html文件
还是原封不动的显示<img src="./angular.jpg" >
,这样子打开页面时是显示不出来图片的,因为此时的目录结构为:
- 因为打包构建后的目录中的
build/index.html的文件
应该要去引入打包构建后目录中的图片文件(红色框)
(引入的路径和文件名要发生改变)。
- 所以我们需要在处理html文件的img图片的打包问题,只需要配合使用
'html-loader'
即可。
- 此时的
webpack.config.js
的配置为(已经能处理通过.less样式文件和在HTML页面上通过img标签引入图片资源的打包问题)
:
const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: './src/index.js',
output: {
filename: 'built.js',
path: resolve(__dirname, 'build')
},
module: {
rules: [
{
test: /\.less$/,
// 要使用多个loader处理用use
use: ['style-loader', 'css-loader', 'less-loader']
},
{
// 问题:默认处理不了html中img图片
// 处理图片资源
test: /\.(jpg|png|gif)$/,
// 使用一个loader
// 下载 url-loader file-loader
// url-loader依赖于file-loader
loader: 'url-loader',
options: {
limit: 8 * 1024,
// 问题:因为url-loader默认使用es6模块化解析
//'html-loader'引入图片是commonjs
// 打包后解析时会出问题:<img src="[object Module]" alt=''/>
// 解决:关闭url-loader的es6模块化,使用commonjs解析
esModule: false,
// 给图片进行重命名
// (打包后单独生成重命名后的图片文件并存放在目录(这里是存放在build目录下)下)
// [hash:10]取图片的hash的前10位
// [ext]取文件原来扩展名
name: '[hash:10].[ext]'
}
},
{
test: /\.html$/,
// 处理html文件的img图片
// 负责引入img,从而能被url-loader进行处理
loader: 'html-loader'
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html'
})
],
mode: 'development'
};
- 打包构建后的
build/index.html
的文件内容:
- 总结打包图片资源的方式:
-
- 解决了通过样式文件(例如.less、.css文件)引入图片资源打包的问题
-
需求四:打包其他资源
- 场景重现:我们在
src/index.html
中使用了iconfont样式资源,然后通过入口文件src/index.js
引入依赖(即import './iconfont.css'
)的iconfont样式文件,再然后我们在webpack.config.js
利用'file-loader'
帮助我们打包其他资源(这里是帮我们打包iconfont样式资源
),此时我们在终端执行webpack命令后
- 执行webpack命令后,会自动生成一个
build/index.html
页面,并自动引入build/built.js
文件,这个build/built.js
文件内已经处理好了iconfont样式资源
,我们打开build/index.html
页面时可以发现,iconfont样式资源已经完美的呈现在页面之上了。
- 打包构建后的
build/index.html
的文件内容:
- 此时的
webpack.config.js
的配置为:
const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: './src/index.js',
output: {
filename: 'built.js',
path: resolve(__dirname, 'build')
},
module: {
rules: [
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
},
// 打包其他资源(除了html/js/css资源以外的资源)
{
// 排除css/js/html资源
// (这些资源不用这个来处理)
exclude: /\.(css|js|html|less)$/,
loader: 'file-loader',
options: {
name: '[hash:10].[ext]'
}
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html'
})
],
mode: 'development'
};
devServer的运用
- 场景需求:每一次更改源目录结构的文件时(
例如更改源目录结构的src/index.html的代码或者更改src/index.js的代码等等
),都需要重新执行webpack命令来重新覆盖之前生成的构建后的目录。然后在打开构建后的目录的build/index.html文件
才能看到更新后的HTML页面。
- 开启服务器devServer:用来实现自动编译,自动打开浏览器,自动刷新浏览器,该服务器devServer的特点是:会在内存中编译打包,不会有任何输出(单独运行devServer时不会生成构建目录,关闭后自动释放内存)。
- 开启服务器devServer:在改变源目录中的文件时,在按下ctrl+s保存后,会自动更新开启的服务器页面,但是不会更改构建后的目录文件结构(
即你需要在执行webpack命令才能修改构建后目录文件结构
)
- 下载
webpack-dev-server
至本地:cnpm i install webpack-dev-server -D
;
- 启动服务器devServer的指令为:
npx webpack-dev-server
- 正常步骤:先在终端
执行webpack命令
自动构造出打包的目录,在启动服务器devServer
。(如果不先执行webpack命令直接启动服务器devServer也是可以的)
- 此时的
webpack.config.js
的配置为:
const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: './src/index.js',
output: {
filename: 'built.js',
path: resolve(__dirname, 'build')
},
module: {
rules: [
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
},
// 打包其他资源(除了html/js/css资源以外的资源)
{
// 排除css/js/html资源
exclude: /\.(css|js|html|less)$/,
loader: 'file-loader',
options: {
name: '[hash:10].[ext]'
}
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html'
})
],
mode: 'development',
devServer: {
// 项目构建后路径
// 这里要和 ouput中的path: resolve(__dirname, 'build')保持一致
contentBase: resolve(__dirname, 'build'),
// 启动gzip压缩
compress: true,
// 端口号
port: 3000,
// 自动打开浏览器
open: true
}
};
-
- 执行的效果图如下:在改变源目录中的文件时,在按下ctrl+s保存后,会自动更新开启的服务器页面,但是不会更改构建后的目录文件结构(即你需要在执行webpack命令才能修改构建后目录文件结构)
综合案例:开发环境的基本总配置
- 需求四:打包其他其他资源(这里指的是打包iconfont样式资源)
-
- 注意点:
注意路径的引入问题
:在不同的目录结构中要使用正确的路径引用对应的资源
-
- 技巧一:先使用devServer执行命令
npx webpack-dev-server
预先查看HTML页面的情况(devServer只会在内存中编译打包,没有输出),在去执行webpack命令
生成构建后的目录(webpack会将打包结果输出出去),更加高效
-
- 思路分析:以
src/js/index.js
做为入口文件,分析基于入口文件的依赖(这里有import '../css/iconfont.css'和import '../css/index.less'
),然后构建一个依赖关系图,经过处理打包输出为build/js/index.js
(其他资源的处理同理),又因为我们使用了插件'html-webpack-plugin'
,它会自动帮我们在自动生成的build/index.html文件中
引入打包后输出的所有资源(JS/CSS/icon Font/图片)
-
-
- 此时的
webpack.config.js
的配置为:
// resolve用来拼接绝对路径的方法
const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
// 入口起点--分析内部依赖
entry: './src/js/index.js',
// 输出
output: {
//输出文件名
//输出到js目录下的built.js
filename: 'js/built.js',
// 输出总目录
// __dirname nodejs的变量,代表当前文件(webpack.config.js)的目录绝对路径
path: resolve(__dirname, 'build')
},
module: {
rules: [
// loader的配置
// 详细loader配置
// 不同文件必须配置不同loader处理
{
// 处理less资源
//use数组中loader执行顺序:从右到左,从下到上 依次执行
// 'style-loader'作用:创建style标签,将js中的样式资源插入进行,添加到head中生效
// 'css-loader'作用:将css文件变成commonjs模块加载js中,里面内容是样式字符串
//'less-loader'将less文件编译成css文件,需要下载 less-loader和less
// 所以在这里的配置下css文件打包后是不会单独生成一个css文件的
test: /\.less$/,
use: ['style-loader', 'css-loader', 'less-loader']
},
{
// 处理css资源
test: /\.css$/,
use: ['style-loader', 'css-loader']
},
{
// 处理图片资源
test: /\.(jpg|png|gif)$/,
// 下载 url-loader file-loader才能使用'url-loader'处理img图片
//'url-loader' 是在 'file-loader'的功能基础上做的优化
// 如果单单使用“url-loader”默认是处理不了html中的img图片的
// 可以在多用一个"html-loader"(负责引入img,从而能被url-loader进行处理)
loader: 'url-loader',
options: {
// 图片大小小于8kb,就会被base64处理
limit: 8 * 1024,
// 给图片进行重命名
// [hash:10]取图片的hash的前10位
// [ext]取文件原来扩展名
name: '[hash:10].[ext]',
// 关闭es6模块化开启commonJs
esModule: false,
//输出到imgs目录下
outputPath: 'imgs'
}
},
{
// 处理html中img资源
test: /\.html$/,
loader: 'html-loader'
},
{
// 处理其他资源
exclude: /\.(html|js|css|less|jpg|png|gif)/,
//原封不动的输出资源
loader: 'file-loader',
options: {
name: '[hash:10].[ext]',
//输出到media目录下
outputPath: 'media'
}
}
]
},
plugins: [
// plugins的配置
// 'html-webpack-plugin'的功能:默认会创建一个空的HTML,自动引入打包输出的所有资源(JS/CSS)
// 'html-webpack-plugin'的需求:需要有结构的HTML文件
new HtmlWebpackPlugin({
// 以谁为模板
// 复制 './src/index.html' 文件
// 并自动引入 打包输出的所有资源(JS/CSS/IMG/iconFont)
template: './src/index.html'
})
],
mode: 'development',
// 可以单独设置开发服务器 devServer:
// 用来自动化(自动编译,自动打开浏览器,自动刷新浏览器~~)
// 特点:只会在内存中编译打包,不会有任何输出
devServer: {
// 项目构建后路径与 Output下的path: resolve(__dirname, 'build')保持一致
contentBase: resolve(__dirname, 'build'),
// 启动gzip压缩
compress: true,
port: 3000,
// 自动打开浏览器
open: true
}
};
{
"name": "webpack_code",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"devDependencies": {
"@babel/core": "^7.8.4",
"@babel/polyfill": "^7.8.3",
"@babel/preset-env": "^7.8.4",
"add-asset-html-webpack-plugin": "^3.1.3",
"babel": "^6.23.0",
"babel-loader": "^8.0.6",
"core-js": "^3.6.4",
"css-loader": "^3.4.2",
"eslint": "^6.8.0",
"eslint-config-airbnb-base": "^14.0.0",
"eslint-loader": "^3.0.3",
"eslint-plugin-import": "^2.20.1",
"file-loader": "^5.0.2",
"html-loader": "^0.5.5",
"html-webpack-plugin": "^3.2.0",
"less": "^3.11.1",
"less-loader": "^5.0.0",
"mini-css-extract-plugin": "^0.9.0",
"optimize-css-assets-webpack-plugin": "^5.0.3",
"postcss-loader": "^3.0.0",
"postcss-preset-env": "^6.7.0",
"style-loader": "^1.1.3",
"terser-webpack-plugin": "^2.3.5",
"thread-loader": "^2.1.3",
"url-loader": "^3.0.0",
"webpack": "^4.41.6",
"webpack-cli": "^3.3.11",
"webpack-dev-server": "^3.10.3",
"workbox-webpack-plugin": "^5.0.0"
},
"dependencies": {
"jquery": "^3.4.1"
},
"browserslist": {
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
],
"production": [
">0.2%",
"not dead",
"not op_mini all"
]
},
"eslintConfig": {
"extends": "airbnb-base",
"env": {
"browser": true
}
},
"sideEffects": [
"*.css"
]
}
发表评论
还没有评论,快来抢沙发吧!