webpack总结
1. webpack简介
1.1webpack是什么
webpack是一种前端资源构建工具,一个静态模块打包器。在webpack看来前端的所有资源文件(js/json/css/img/less/…)都会被当作模块处理,它奖根据模块的依赖关系进行静态分析,打包生成对应的静态资源。
1.2webpack的5个核心概念
1. Entry:入口,指示webpack以哪个文件为入口起点开始打包,分析构建内部依赖图,可以设置多个入口
2. Output:输出(output)指示webpack打包后的资源bundles输出到哪里去,以及如何命名。
3. Loader:Loader可以让webpack去处理哪些非js文件(webpack自身只理解js文件和json文件)
4. Plugins:Loader让webpack可以用于执行范围更广的任务,插件的范围包括,打包优化,压缩,重新定义环境中的变量等
5.Mode:模式(Mode)指示webpack以那种模式对前端资源进行打包构建。
模式类型 | 描述 | 特点 |
---|---|---|
development | 该模式下webpack会将DefinePlugin中process.env.NODE_ENV的值设置为development.并启用NamedChunksPlugin和NamedModulesPlugin。 | 一种能让本地代码调试运行的环境。 |
production | 会将DeFinePlugin中的process.env.NODE_ENV的值设置为production。启用FlagDependencyUsagePlugin,FlagIncludedChunksPLugin,ModuleConcatenationPlugin,NoEmitOnErrorsPlugin,OccurrenceOrderPlugin,SideEffectsFlagPlugin和TerserPlugin: | 一种能够使代码打包,构建,压缩,优化上线并运行的环境。 |
2. webpack基本使用介绍
2.1 初始化配置
- 初始化package.json,使用指令npm init
- 下载并安装webpack,使用指令 npm install webpack webpack-cli -g(全局安装),npm install webpack webpack-cli -D(局部安装)。
2.2 编译打包应用
- 创建文件
- 运行指令,开发环境使用指令为:webpack src/js/index.js -o build/js/built.js --mode=development。功能为:能够编译打包js和json文件,并且能够将es6的模块化语法转换成浏览器能够识别的语法。生产环境使用指令为:webpack src/js/index.js -o build/js/built.js --mode=production。功能:在开发配置功能上多一个功能,压缩,优化代码。
注:webpack不能打包css,img等文件,不能将js的es6基本语法转化为es5语法。`
3. webpack开发环境的基本配置
const {resolve} = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
/*
项目运行:
webpack:将项目编译打包并输出
webpack-dev-server:只在内存中编译打包,不用输出
*/
module.exports = {
//入口
entry: './src/js/index.js',
//出口
output: {
filename: 'js/built.js',
path: resolve(__dirname,'build')
},
module:{
rules:[
//loader的配置
{
//处理less资源
test: /\.less$/,
use:[
'style-loader',
'css-loader',
'less-loader'
]
},
{
//处理css资源
test: /\.css$/,
use:[
'style-loader',
'css-loader'
]
},
{
//处理图片资源
test: /\.(png|jpg|gif)$/,
loader:'url-loader',
options:{
limit: 8 * 1024,
name: '[hash:10].[ext]',
//关闭es6模块化
esModule: false,
outputPath: 'images'
}
},
//将html文件中的图片资源引入交给url-loader处理
{
test: /\.html$/,
loader: 'html-loader'
},
{
//处理其它资源
exclude: /\.(html|js|css|less|jpg|png|gif)/,
loader: 'file-loader',
options:{
name: '[hash:10].[ext]',
outputPath: 'media'
}
}
]
},
//plugins配置
plugins:[
//以'./src/index.html'文件为模板生成一个相同的文件,并自动引入webpack打包构建好的所有资源
new HtmlWebpackPlugin({
template: './src/index.html'
})
],
mode: 'development',
AAdevtool: 'inline-source-map', // 添加打包后代码到源代码的映射,利于调试
//开发服务器:用来自动化(自动编译,自动打开浏览器,自动刷新浏览器)
//特定:没有输出,只会在内存中编译打包,
//启动devServer指令为:npx webpack-dev-server
devServer:{
contentBase: resolve(__dirname,'build'),
//启动gzip压缩
compress: true,
//端口号
port:3000,
//自动打开浏览器
open:true
}
}
4. webpack生产环境的基本配置
4.1提取css成单独的文件
- 下载插件mini-css-extract-plugin
- 具体配置如下;
const {resolve} = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
entry:'./src/js/index.js',
output:{
filename:'built.js',
path: resolve(__dirname, 'build')
},
module:{
rules:[
{
test: /\.css$/,
use:[
// 'style-loader',
//这个loader取代style-loader。作用:提取js中的css成单独的文件
MiniCssExtractPlugin.loader,
'css-loader'
]
}
]
},
plugins:[
new HtmlWebpackPlugin({
template: './src/index.html'
}),
new MiniCssExtractPlugin({
filename:'css/main.css'
})
],
mode: 'development'
}
4.2css样式兼容性处理
- 下载loader:npm install --save-dev postcss-loader postcss-preset-env
- 配置文件如下:
const {resolve} = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
//设置node.js环境变量
// process.env.NODE_ENV = 'development';
module.exports = {
entry:'./src/js/index.js',
output:{
filename:'built.js',
path: resolve(__dirname, 'build')
},
module:{
rules:[
{
test: /\.css$/,
use:[
// 'style-loader',
//这个loader取代style-loader。作用:提取js中的css成单独的文件
MiniCssExtractPlugin.loader,
'css-loader',
/*css兼容性处理:postcss-->postcss-loader postcss-preset-env
帮postcss 找到package.json中的browserslist里面的配置,通过配置加载指定的css兼容性样式
"browserslist":{
//开发环境--》设置node环境变量
"development":[
"last 1 chrome version",
"last 1 firfox version",
"last 1 safari version
],
//生产环境(默认生产环境)
"production":[
">0.2%",
"not dead",
"not op_mini all"
]
}
*/
//使用postcss-loader的默认配置
//'postcss-loader',
//修改loader配置
{
//css的兼容性处理
loader: 'postcss-loader',
options:{
ident: 'postcss',
plugins: ()=>[
//postcss的插件
require('postcss-preset-env')()
]
}
}
]
}
]
},
plugins:[
new HtmlWebpackPlugin({
template: './src/index.html'
}),
//将css提取成单独的文件
new MiniCssExtractPlugin({
filename:'css/main.css'
})
],
mode: 'development'
}
4.3css样式文件的压缩
- 安装插件 npm install optimize-css-assets-webpack-plugin
- 配置如下
const {resolve} = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin');
//设置node.js环境变量
// process.env.NODE_ENV = 'development';
module.exports = {
entry:'./src/js/index.js',
output:{
filename:'built.js',
path: resolve(__dirname, 'build')
},
module:{
rules:[
{
test: /\.css$/,
use:[
// 'style-loader',
//这个loader取代style-loader。作用:提取js中的css成单独的文件
MiniCssExtractPlugin.loader,
'css-loader',
/*css兼容性处理:postcss-->postcss-loader postcss-preset-env
帮postcss 找到package.json中的browserslist里面的配置,通过配置加载指定的css兼容性样式
"browserslist":{
//开发环境--》设置node环境变量
"development":[
"last 1 chrome version",
"last 1 firfox version",
"last 1 safari version
],
//生产环境(默认生产环境)
"production":[
">0.2%",
"not dead",
"not op_mini all"
]
}
*/
//使用postcss-loader的默认配置
//'postcss-loader',
//修改loader配置
{
loader: 'postcss-loader',
options:{
ident: 'postcss',
plugins: ()=>[
//postcss的插件
require('postcss-preset-env')()
]
}
}
]
}
]
},
plugins:[
new HtmlWebpackPlugin({
template: './src/index.html'
}),
new MiniCssExtractPlugin({
filename:'css/main.css'
}),
//压缩css的插件
new OptimizeCssAssetsWebpackPlugin()
],
mode: 'development'
}
4.4 js语法检查
- 下载安装包:npm install --save-dev eslint eslint-loader esling-config-airbnb-base eslint-plugin-import
- 修改配置文件
修改webpack.config.js:
const {resolve} = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin');
//设置node.js环境变量
// process.env.NODE_ENV = 'development';
module.exports = {
entry:'./src/js/index.js',
output:{
filename:'built.js',
path: resolve(__dirname, 'build')
},
module:{
rules:[
{
test: /\.css$/,
use:[
// 'style-loader',
//这个loader取代style-loader。作用:提取js中的css成单独的文件
MiniCssExtractPlugin.loader,
'css-loader',
/*css兼容性处理:postcss-->postcss-loader postcss-preset-env
帮postcss 找到package.json中的browserslist里面的配置,通过配置加载指定的css兼容性样式
"browserslist":{
//开发环境--》设置node环境变量
"development":[
"last 1 chrome version",
"last 1 firfox version",
"last 1 safari version
],
//生产环境(默认生产环境)
"production":[
">0.2%",
"not dead",
"not op_mini all"
]
}
*/
//使用postcss-loader的默认配置
//'postcss-loader',
//修改loader配置
{
loader: 'postcss-loader',
options:{
ident: 'postcss',
plugins: ()=>[
//postcss的插件
require('postcss-preset-env')()
]
}
}
]
},
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'eslint-loader',
options:{
//自动修复eslint错误
fix:true
}
}
]
},
plugins:[
new HtmlWebpackPlugin({
template: './src/index.html'
}),
new MiniCssExtractPlugin({
filename:'css/main.css'
}),
//压缩css的插件
new OptimizeCssAssetsWebpackPlugin()
],
mode: 'development'
}
修改package.json:
“eslintConfig”: {
“extends”: “airbnb-base”,,
env:{
browser:true
}
}
4.5 js兼容性处理
1 . 安装包和插件:npm install babel-loader @babel/core @babel/preset-env @babel/polyfill core-js
2.修改配置文件:
const {resolve} = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin');
//设置node.js环境变量
// process.env.NODE_ENV = 'development';
module.exports = {
entry:'./src/js/index.js',
output:{
filename:'built.js',
path: resolve(__dirname, 'build')
},
module:{
rules:[
{
test: /\.css$/,
use:[
// 'style-loader',
//这个loader取代style-loader。作用:提取js中的css成单独的文件
MiniCssExtractPlugin.loader,
'css-loader',
/*css兼容性处理:postcss-->postcss-loader postcss-preset-env
帮postcss 找到package.json中的browserslist里面的配置,通过配置加载指定的css兼容性样式
"browserslist":{
//开发环境--》设置node环境变量
"development":[
"last 1 chrome version",
"last 1 firfox version",
"last 1 safari version
],
//生产环境(默认生产环境)
"production":[
">0.2%",
"not dead",
"not op_mini all"
]
}
*/
//使用postcss-loader的默认配置
//'postcss-loader',
//修改loader配置
{
loader: 'postcss-loader',
options:{
ident: 'postcss',
plugins: ()=>[
//postcss的插件
require('postcss-preset-env')()
]
}
}
]
},
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'eslint-loader',
options:{
//自动修复eslint错误
fix:true
}
},
{
/*
js兼容性处理:babel-loader @babel/core
1. 基本js 兼容新处理--》@babel/preset-env
问题:只能转换基本语法,如promise不能转换
2.全部js兼容性处理--》@babel/polyfill(引入即可)
问题:我只要解决部分兼容性问题,但是将所有兼容性代码全部引入,代码体积太大
3.需要做兼容性处理的就做:按需加载,-->core-js
*/
test: /\.js$/,
exclude:/node_modules/,
loader: 'babel-loader',
options:{
presets:[
[
'@babel/preset-env',
{
useBuiltIns:'usage',
corejs:{
version: 3
},
targets:{
chrome: '60',
firefox: '60',
ie: '9',
safari: '10',
edge: '17'
},
},
]
],
}
}
]
},
plugins:[
new HtmlWebpackPlugin({
template: './src/index.html'
}),
new MiniCssExtractPlugin({
filename:'css/main.css'
}),
//压缩css的插件
new OptimizeCssAssetsWebpackPlugin()
],
mode: 'development',
//生产环境下会自动压缩代码
// mode: 'production'
}
4.6 js文件压缩
将配置文件中的mode修改为production后webpack就会对js文件进行压缩。
4.7 html文件压缩
html文件压缩直接在html-webpack-plugin内部多家一个属性minify,如下:
4.8 相对完整的生产环境配置如下:
const {resolve} = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
//定义node.js环境变量,决定使用browserslist的哪个环境
process.env.NODE_ENV = 'development';
let commonCssLoader = {
MiniCssExtractPlugin.loader,
'css-loader',
{
//还需要再package.json中定义browserslist
loader: 'postcss',
options:{
ident: 'postcss',
plugins:()=>[
require('postcss-preset-env')()
]
}
}
}
module.exports = {
entry:'./src/js/index.js',
output:{
filename: 'js/built.js',
path: resolve(__dirname,'build')
},
module:{
rules:[
/*
正常来讲,一个文件只能被一个loader处理,如果一个文件被多个loader处理,则一定注意loader的配置顺序
先执行eslint再执行babel
*/
{
/\.css$/,
use:[
// // 'style-loader',
// MiniCssExtractPlugin.loader,
// 'css-loader',
// {
// //还需要再package.json中定义browserslist
// loader: 'postcss',
// options:{
// ident: 'postcss',
// plugins:()=>[
// require('postcss-preset-env')()
// ]
// }
// }
...commonCssLoader
]
},
{
/\.less$/,
use:[
// // 'style-loader',
// MiniCssExtractPlugin.loader,
// 'css-loader',
// {
// //还需要再package.json中定义browserslist
// loader: 'postcss',
// options:{
// ident: 'postcss',
// plugins:()=>[
// require('postcss-preset-env')()
// ]
// }
// }
...commonCssLoader,
'less-loader'
]
},
{
//在package.json中要添加eslintConfig配置,来指示eslint做哪些检查-->airbnb规则
test: /\.js$/,
exclude:/node_modules/,
loader:'eslint-loader',
//优先处理
enforce: 'pre',
options:{
fix: true
}
},
{
test: /\.js$/,
exclude:/node_modules/,
loader:'babel-loader',
options:{
presets:[[
'@babel/preset-env',
{
//按需加载
useBuiltIns: 'usage',
corejs:{
version:3
},
targets:{
chrome: '60',
firefox: '60',
ie: '9',
safari: '10',
edge: '17'
}
}
]]
}
},
{
test: /\.(png/jpg/gif)$/,
loader: 'url-loader',
options:{
limit: 8*1024,
name: '[hash:10].[ext]',
outputPath: 'images',
esModule: false
}
},
{
test: /\.html$/,
loader: 'html-loader'
},
{
exclude: /\.(js|html|css|less|png|jpg|gif)/,
loader: 'file-loader',
options:{
outputPath: 'media',
name: '[hash:10].[ext]'
}
}
]
},
plugins:[
new MiniCssExtractPlugin({
filename: 'css/built.css'
}),
new OptimizeCssAssetsWebpackPlugin(),
new HtmlWebpackPlugin({
template:'./src/index.html',
minify:{
collapseWhitespace: true,
removeComments: true
}
})
]
}
5.webpack优化配置
5.1 热模块替换(HMR)
5.1.1 什么是HMR
HMR指代码更新时不用更新所有的模块只更新部分模块,可以增快构建速度,仅用于开发环境只要在devServer配置中设置hot为true即可。
5.1.2 如何实现HMR
- css文件实现HMR:对于css文件的处理需要style-loader,style-loader内部实现了css资源的HMR功能。
- html文件实现HMR:对于HTML文件往往比较少,通常只有一个,有无实现HMR功能并不影响。
- js文件实现HMR:webpack默认不能实现HMR功能,但是我们可以通过js代码实现一些模块的HMR功能,举例如下:
5.2sourceMap
5.2.1 sourceMap是什么
source-map:一种提供源代码到构建后代码映射的技术(如果构建后代码出错了,通过source-map可以定位到源代码中出现的错误)
5.2.2 各种sourceMap的简单介绍和比较
source-map 外部
inline-source-map//内联 更快
hidden-source-map 外部
eval-source-map 内联
nosources-source-map 外部
cheap-source-map 外部
cheap-module-source-map 外部
eval-source-map和inline-source-map的区别:
inline-source-map只会生成一个内联sourceMap,eval-source-map每个文件都会生成一个source-map放在eval()中
内联和外部区别:外部生成了文件,内联没有,内联构建速度会,体积会更大
5.2.2 开发环境下的sourceMap选择
开发环境下的选择应该是速度快,调试更友好的sourceMap
速度方面(eval>inline>cheap…)
eval-cheap-source-map
eval-source-map
调试更友好
source-map
cheap-module-source-map
cheap-source-map
推荐:
eval-source-map
eval-cheap-module-source-map
5.2.2 生产环境下的sourceMap选择
生成环境下,我们会考虑源代码要不要隐藏?调试要不要友好。
由于内联会让代码体积变大,所以生成环境不用内联
如果需要隐藏代码我们推荐使用:
nosources-source-map//全部隐藏
hidden-source-map//只隐藏源代码会提示构建后代码错误
希望调试更友好推荐:
source-map
cheap-module-source-map
cheap-source-map
综合推荐
不需要隐藏:source-map;cheap-module-source-Map ,需要隐藏就考虑nosources-source-map//全部隐藏;hidden-source-map//只隐藏源代码会提示构建后代码错误
5.3 oneOf
提取互不影响的loader到oneOf保证任何一个文件只被oneOf里面的一个loader处理,可以提高打包构建速度。
5.4 缓存
5.4.1 打包时生成的各个hash值,及其区别。
- hash: 每一次打包都生成一个唯一的hash值,每次打包都会变。
- chunkHash:来自同一个chunk的资源具有相同的hash值,一旦生成这个chunk的源文件中任何一个文件发生变化,再次打包时这个chunkHash的值就会发生变化。
- contentHash:根据文件内容生成的hash,一旦文件内容发生改变,那么hash值就会改变
5.5 treeshaking(树摇)
打包构建时去掉无用代码,无用代码包括哪些从未被任何模块引用的模块,未被任何模块使用的代码。
5.6 代码分割(codesplit)
代码分割方式:
- 多入口:设置多个入口,每一个入口都会打包成一个chrunk
- 配置optimization:它会将node_modules中的资源进行单独打包,并且如果一个模板(大于30kb )被多个chrunk引用,该模块也会被抽离出来单独进行打包。
- 通过es6的import语法:通过使用es6的import语法导入的模块能够被进行单独的打包实现按需加载
5.7 懒加载
前端在需要该资源时才进行该资源的加载解析,实现方式es6的import语法。
5.8 预加载
在浏览器空闲时,预先对某些资源进行加载。
5.9 PWA
实现PWA(渐进式web应用程序)功能,我们需要使用一个插件workbox-webpack-plugin该插件会帮助我们生成serviceWorker,因为该功能存在很大的兼容性问题,故我们要想使用还需添加一些js代码如:
5.9 多进程打包
webpack中实现多进程打包,我们需要使用thread-loader,使用thread-loader时,启动多线程大概需要600毫秒,线程之间通信也需要时间,在我们的项目比较大时,可以一定程度上提高打包构建速度,如果较小,未必能够加快构建速度,反而更慢。
5.10 externals
我们可以通过添加externals配置指定某些资源不打包,通过外联的方式引入比如通过CDN。如果我们添加如下配置:
就不会对jQuery进行打包,我们可以通过CDN来使用jQuery。
5.10 dll
通过使用dll,我们可以对某些基本不会变的资源进行单独打包,避免代码更新之后重复打包某些资源
6.webpack配置详情
6.1 entry
entry配置有三种方式,字符串,对象,数组,通常我们使用但入口的字符串形式。
6.2 output
output:{
//文件名称(指定名称+目录)
filename: 'js/[name].js',
//输出文件目录(将来所有资源输出的公共目录)
path: resolve(__dirname,'build),
//所有资源引入公共路径前缀: 'imgs/a.jpg' -->'/imgs/a.jpg'
publicPath: '/',
chunkFilename: 'js/[name]_chunk.js',//非入口chunk的名称
library: '[name]',//整个库向外暴露的变量名
libraryTarget: 'window',//变量名添加到哪个环境上:browser
libraryTarget: 'global',//变量名添加到哪个环境上:node
libraryTarget: 'commonjs'//将变量名添加到commonjs上
}
6.3 module
module中主要配置处理文件的loader,配置loader的主要字段包括这样一些。
- test:通过正则表达式指定需要处理的文件类型
- exclude:通过正则表达式指定不需要处理的文件范围
- include:通过正则表达式指定指处理的文件范围
- enforce:值未pre时优先执行该loader,值未post时延后执行该loader.
- loader::‘cssl-oader’//单个loader用loader,多个loader用use。
- optiions:修改loader的默认配置。
6.4 resolve
resolve用于配置模块的一些解析规则
- 配置模块的的路径别名我们可以使用alias属性,优点是配置以后我们可以简写路径,但是没有提示。如:
- 配置省略文件路径的后缀名我们可以使用 extensions。如下:
- 告诉webpack从哪个目录开始解析模块我们可以使用modules属性。如下:
6.4 devServer
devServer详细配置如下
devServer:{
//运行代码的目录
contentBase: resolve(__dirname,'build'),
//监视contentBase目录下的所有的文件,一旦文件变化就会reload
watchContentBase: true,
watchOptions:{
//忽略文件
ignored: /node_modules/
},
//启动gzip压缩
compress: true,
//端口号
port: 8000,
//域名
host: localhost,
//自动打开浏览器
open: true,
//开启HMR功能
hot: true,
//不要显示服务器日志信息
clientLogLevel: 'none',
//除了一些基本启动信息以外,其他内容都不显示
quite: true,
//如果出错了,不要全屏显示
overlay: false,
//服务器代理,解决开发环境跨域问题。
proxy:{
//一旦devServer(8000)服务器接收到/api/xxx的请求,就会把请求转发到另外一个服务器(3000)
'/api':{
target: 'http://localhost:3000',
//发起请求时请求路径重写:将/api/xxx -->/xxx(去掉/api)
pathRewrite: {
'^/api': ''
}
}
}
}
6.4 optimization
optimization{
splitChunks:{
chunks: 'all',
//以下取值均为默认值可以不写
minSize: 30*1024,//分割的chunk的最小为30kb
maxSize: 0,//没有最大限制
minChunks: 1,//要提取的chunk最少被引用一次
maxAsyncRequests: 5,//按需加载时并行加载的文件的最大数量
maxInitialRequests: 3,//入口js文件最大并行请求数量
automaticNameDelimiter: '~',//名称连接符
name: true,//可以使用命名规则
cacheGroups: {
//分割chunk的组
//node_modules文件会被打包到wendors组的chunk中。-->vendors~xxx.js
//满足上面的公共规则,如:大小超过30kb,至少被引用一次
vendors:{
test: /[\\/]node_modules[\\/]/,
//优先级
priority: -10
},
default:{
//要提取的chunk最少被引用两次
minChunks: 2,
//优先级
priority: -20,
//如果当前要打包的模块,和之前已经被提取的模块是同一个,就会复用,而不是重新打包模块
reuseExistingChunk: true
}
}
},
//将当前模块的记录其他模块的hash单独打包为一个文件 runtime
//解决修改a文件导致b文件的contenthash发生变化
runtimeChunk:{
name: entrypoint=> `runtime-$(entrypoint.name)`
},
minimizer:[
//配置生产环境的压缩方案:js和css
new TerserWebpackPlugin({
//开启缓存
cache: true,
//开启多进程打包
parallel: true,
//启动source-map
sourceMap: true
})
]
}