认识
webpack是优秀的前端构建工具,静态资源打包器,可以根据模块依赖关系进行静态资源分析,快速打包生成相对应浏览器可以直接识别的静态资源!
环境
1)node环境
2)vs code编辑器
规约
1)入口文件:
开始打包第一个文件称为入口文件,通常经过在入口文件中引入其他资源,形成资源关系树状图。webpack根据依赖关系进行一次处理。
2)chunk代码块:
管理webpack内部的打包进程,chunk可以分为“入口”和“子代码块”,入口文件就是一个chunk,默认的webpack打包配置是一个入口文件是一个chunk,打包生成一个bundle。但是如果出现代码分割的情况下,有多个chunk打包生成一个bundle。
3)bundle:
通过处理入口文件中的关系依赖,最后打包输出成为浏览器可以直接识别的静态资源文件就是bundle。
安装webpack环境
1)项目根目录控制台执行指令:npm init,生成package.json文件,npm是新版本node自带的包管理工具,而package.json相当于清单,记录依赖库和项目信息的文件。
2)全局安装webpack指令: npm i webpack webpack-cli -g ,全局安装是指系统环境中,任何项目文件夹下都可以使用指令,其中mac电脑首次执行应该是需要管理员权限,sudo npm i webpack webpack-cli -g 如果网速太慢则建议切换为淘宝镜像源。
3)本地安装webpcak指令: sudo npm i webpack webpack-cli -D,下载的模块是注入于本项目下的./node_nodules文件夹中,不会影响其他项目,起到独立的作用!
概念核心:
Entry
入口文件指示,配置wepack以哪个入口文件进行打包分析等参数。
entry: "./src/main.js",
Output
出口文件指示,配置webpack打包后的资源bundle输出资源的路径及参数。
output: {
filename: "static/js/[name].js",
path: resolve(__dirname, "build"),
},
Loader
webpack本身仅能识别js、json代码,而Loader的作用就是将CSS、img、字体资源翻译成为webpack可以识别的资源,可以识别后才可以进行打包处理!loader通过npm安装依赖之后就可以配置,不用需要引入。
1)Es语法检查配置:
// eslint语法检查
{
test: /\.js$/, // 通过正则匹配后缀名为.js的文件
enforce: "pre", // 设置loader的执行顺序,pre(优先)| post(延后)。
exclude: /node_modules/, // 排除node_modules目录下js文件的语法检查
loader: "eslint-loader", // 指定eslint-loader执行处理js文件进行语法检查
options: {
fix: true, // 配置参、空格、缩进不规范的语法自动进行修复。
},
},
2)处理CSS文件并兼容:
{
// 处理css文件的规则所需loader安装指令:npm i style-loader -D 和 npm i css-loader -D
test: /\.css$/,
// 处理文件时使用到多个lorder时,执行顺序为从下到上。
use: [
// "style-loader", // 处理创建style标签,将js中处理的资源添加到style标签中,再添加到页面head中生效。
{
loader: MiniCssExtractPlugin.loader, // 因为css引入js文件中,会造成js代码文件过大,所以通过MiniCssExtractPlugin构造函数自带loader取代style-loader,作用为将css抽离成为单个文件通过link标签引入。
options: {
publicPath: "../../", // 资源引入html文件时的路径前缀,因为css文件以及被单独抽离至特定目录下,正确修改才能匹配到css中引用的静态资源。
},
},
// 翻译css使webpack能够识别css样式语法
"css-loader",
{
loader: "postcss-loader", // 使用postcss进行浏览器兼容,使用的方法是在package.json中定义browserslist属性规则进行浏览器兼容性语法补全。
options: {
ident: "postcss",
plugins: () => [require("postcss-preset-env")],
},
},
],
},
3)处理Less文件:
{
// 处理less文件的规则所需loader安装指令:npm i less-loader -D 和 npm i less -D
test: /\.less$/,
use: [
// "style-loader",
{
loader: MiniCssExtractPlugin.loader,
options: {
publicPath: "../../",
},
},
"css-loader",
"less-loader",
],
},
4)处理图片文件:
{
// 处理图片文件的规则安装指令:cnpm i url-loader file-loader -D
test: /\.(png|jpe?g|gif|gif|svg)(\?.*)?$/,
loader: "url-loader",
options: {
limit: 80 * 1024, // 当图片小于80kb时采用base64的方式打包,大于则以图片形式打包。
name: "[hash:10].[ext]", // 每次webpack构建打包会生成一串不重复的hash码,[hash:10]则是去hash的前十位,[ext]取源文件的后缀名。
outputPath: "static/img", // 输出目录,output定义了输出目录为build,此处图片输出目录为build/static/img/XXX文件。
esModule: false, // 默认使用es6语法解析,html-loader使用的是commonjs语法引入,但2020年09月24日不用关闭url-loader的es6解析方法。
},
},
5)处理html文件引入的图片:
{
// 处理html中img等标签引入的图片资源所需loader安装指令:npm i html-loader -D
test: /\.html$/,
loader: "html-loader", // 处理url-loader仅能处理打包图片而不能处理html中资源的遗留问题。
},
6)处理字体图标:
{
// 处理引入字体图标资源所需loader安装指令:npm install file-loader -D
test: /(\.(ttf|woff|eot)$|iconfont\.svg)/,
loader: "file-loader",
options: {
name: "[hash:10].[ext]",
outputPath: "static/font",
},
},
7)处理JS文件并兼容:
{
test: /\.js$/,
exclude: /node_modules/,
use: [
{
// ,
loader: "thread-loader", // 建议项目足够大时打开多进程打包,开启经常需要600ms,进程通信也有开销。
options: {
works: 4, // 核数
},
},
{
loader: "babel-loader",
options: {
presets: [
// "@babel/preset-env" // 把下面数组的注释掉不会适配Promise等高级技术了,仅仅会转换let、const、箭头函数。
[
"@babel/preset-env",
{
useBuiltIns: "usage",
corejs: {
version: 3,
},
// 兼容范围
targets: {
chrome: "50",
firefox: "50",
ie: "10",
safari: "10",
edge: "18",
},
},
],
],
// 开启JS代码缓存,当文件名不变时,浏览器强制缓存js文件,导致修改的项目不能实时更新,所以应该在output中输出文件名中包含hash值,采用的是[content:10]的根据内容生成hash值的形式。没有采用hash是因为css在js中引入属于同一个chunk,输出时带有同一个hash值。
cacheDirectory: true,
},
},
],
},
Plugins
插件(plugins)可以让webpack执行范围更广更为复杂的任务,配置打包优化等一下相关的作用功能,使用前需要单独引入对应的插件。
1)处理html文件插件:
// 无template属性时,默认在输出目录创建一个空的html文件,并将打包后的资源引入其中。template指明文件时,则复制文件,并引入打包后的资源。
new HtmlWebpackPlugin({
template: "./src/index.html",
minify: {
collapseWhitespace: true, // 清除空行缩进
removeAttributeQuotes: true, // 清除注释
},
}),
2)抽离CSS成单独文件插件:
// 处理CSS从js文件中抽离生成独立文件
new MiniCssExtractPlugin({
filename: "static/css/app.css", // 文件输出目录
}),
3)压缩CSS插件:
// Css压缩插件,需要在package.json中定义sideEffects属性防止它压缩去除掉一些css,less等文件。
new OptimizeCssAssetsWebpackPlugin(),
4)PWA离线访问技术插件:
// PWA离线缓存技术,优化使用体验,网络断开后刷新网页仍能够加载得到已经缓存的资源文件,依靠service Workers技术,插件执行后生成一个servicework配置文件,需要在入口文件中注册,兼容性判断。
new WorkboxWebpackPlugin.GenerateSW({
clientsClaim: true, // 帮助servicework快速启动
skipWaiting: true, // 删除旧版本使用最新的serviceworker技术
}),
5)忽略库并动态引入第三方库插件:
new webpack.DllReferencePlugin({
manifest: resolve(__dirname, "dll/manifest.json"),
}),
new addAssetHtmlWebpackPlugin({
filepath: resolve(__dirname, "dll/jquery.js"),
}),
Mode
配置webpack的工作方式,其中有开发(development)和生产(production)模式,开发环境配置简单,能够使代码能够跑在本地即可,生产模式相关复杂,需要处理网站运行上线时的优化等操作。
// mode: "development",
mode: "production", // 设置webpack的工作环境
开发环境优化
HMR热模块替换
webpack处于开发环境中时,默认是一个模块发生改变,全部模块均会重新加载,为了解决此问题,引入HMR热模块替换,资源发生改变时,仅会重新构建打包发生改变的模块。
1)样式文件会自动热模块替换,因为style-loader内部实现了这个功能。
2)开启HMR后html默认是不会自动更新,入口文件中引入html文件,但默认是不会对html做HMR。
entry: ["./src/main.js", "./index.html"],
3)js代码发生改变默认也不可以发生更新,入口文件中对此进行监听!
// 判断是否开启HRM热模块更新,如果开启则监听所需的js文件,则热模块替换发生作用。
if (module.hot) {
// 对入口文件中引入的依赖进行热部署替换监听
module.hot.accept("./utils/url.js", () => {
// 一旦监听到发生改变,立即执行该回调函数。
getUrl();
});
}
缓存方式提高构建速度
1)babel缓存:
配置处理js的loader设置cacheDirectory:
true,会强制js缓存一定时间,但是会造成开发环境代码改变后,生产环境下代码读取的是缓存中的代码,造成不能实时更新代码的问题。
2)文件资源缓存:
hash:webpack每次打包构建时会生成一个唯一的hash值,将打包输出的文件名字中带有hash值,则每次改动,刷新均要请求所有数据。不会读取缓存里的资源,造成了js,css缓存失效。
chunkhash:根据打包时引入的chunk生成hash值,如果打包资源来自同一个资源文件件中,hash值就一致,因为css是在js中引入,chunk一致,导致js,变化css也会跟着不会读取缓存。
contenthash: 根据文件内容生成hash值,不同引入文件的hash值就不一样。
output: {
filename: "static/js/[name][contenthash:5].js",
path: resolve(__dirname, "build"),
},
生产环境优化
Tree Shaking树摇
打包构架去除无用代码,必须是使用ES6模块化引入以及必须指定production环境,自动开启treeshaking模式,减少代码体积。package.json中配置sideEffects: false所有代码均开启树摇模式,但可能会干掉无辜的css等文件。 若标记为sideEffects: ["*.css"]时则不会干掉所匹配的文件。
JS代码懒加载
通过es6语法引入,延时加载,触发一定行为才进行请求加载,不是开局就全部加载进来,那样会增加首次加载的时间,也有着代码分隔的特性,会被单独分割成一个单独文件。
// 动态js引入,单独打包生成一个文件,并给定文件名。也会有懒加载的现象。添加预加载webpackPrefetch关键字。
import( "./test.js")
.then((res) => {
console.log("文件加载成功", res);
})
.catch((err) => {
console.log("文件加载失败", err);
});
预加载
等其他浏览器空闲了再偷偷加载,请求到文件数据了,触发行为的时候再去读取缓存中的数据,懒加载的方式上添加添加预加载webpackPrefetch关键字。
代码分割code split
1)多入口文件方式分隔,对象多入口形式,生成多个chunk,构建后形成多个js文件,用于代码分隔。
// entry: {
// index: "./src/index.js",
// test: ["./src/test.js"], // 特殊数组写法
// },
2)optimization配置分隔,将node_modules的库单独分割打包成vendors.js文件。
optimization: {
splitChunks: {
chunks: "all", // 所有配置均为默认
},
}
3)入口文件中动态js引入的方式,具有懒加载以及会镜像代码分割。
import( "assets/js/add.js")
.then((res) => {
console.log("文件加载成功", res);
})
.catch((err) => {
console.log("文件加载失败", err);
});
PWA渐进式网络开发应用技术(离线访问)
无网络时,刷新仍然可以访问到已经加载的网页,借助了workbox-webpack-plugin插件进行实现,安装指令:cnpm iworkbox-webpack-plugin -D,且必须运行在服务器中才可以看到结果。
安装静态资源服务器
1)npm install serve -g
2)项目根目录执行指令: serve -s,默认发布打包目录build下的index.html到静态资源服务器。
配置插件
new WorkboxWebpackPlugin.GenerateSW({
clientsClaim: true, // 帮助servicework快速启动
skipWaiting: true, // 删除旧版本使用最新的serviceworker技术
}),
入口文件作兼容性判断
// 注册serviceWork并处理兼容性问题
if ("serviceWorker" in navigator) {
window.addEventListener("load", () => {
navigator.serviceWorker
.register("/service-worker.js")
.then((res) => {
// eslint-disable-next-line
console.log("注册成功", res);
})
.catch((err) => {
// eslint-disable-next-line
console.log("注册失败", err);
});
});
}
Source-Map映射技术
构建后代码到源代码的有一种映射技术,如果构建代码出错了,通过映射关系能找到源代码的位置,非常利于调试代码,但是也会造成代码被盗用的安全性问题。详细参数移步webpack.config.js中查看。
直接打包构建项目
1)项目根目录的控制台执行指令:
webpack ./src/index.js -o ./build/built.js–mode=development,开发模式中打包src下的index.js入口文件;输出在build路径下文件名为built.js。
2)打包结果分析:
每次打包都会生成不重复且唯一的hash值,打包构建所用时间以及文件的大小等参数。
配置文件方式构建
项目跟目录下建立webpack.config,js文件,当我们控制台输入webpack打包指令时,默认会按webpack.config.js中的配置去打包构建,配置文件文件通过commomjs的方式暴露一个配置对象。这个就不再分析了,具体看webpack.config.js文件。
webpack.config.js详细配置
const { resolve } = require("path"); // 引入node.js的一个path路径模块,通过解构获取到一个resolve属性值,用于获得当前目录的绝对路径。
const HtmlWebpackPlugin = require("html-webpack-plugin"); // 处理html插件
const MiniCssExtractPlugin = require("mini-css-extract-plugin"); // 抽离css成单独文件插件
const OptimizeCssAssetsWebpackPlugin = require("optimize-css-assets-webpack-plugin"); // 引入压缩Css代码插件
const WorkboxWebpackPlugin = require("workbox-webpack-plugin"); // 引入实现PWA离线缓存技术插件
const TerserWebpackPlugin = require("terser-webpack-plugin"); // 压缩js代码插件
const webpack = require("webpack"); // 引入dll定义属性插件,通过.json映射文件实现忽略单独打包的第三库,在通过addAssetHtmlWebpackPlug进行单独引入。
const addAssetHtmlWebpackPlugin = require("add-asset-html-webpack-plugin"); // dll单独打包库自动引入html插件
// process.env.NODE_ENV = "production"; // 设置nodejs的进程环境为production生成环境,postcss默认工作于生产环境下。
module.exports = {
entry: "./src/main.js",
// entry: ["./src/index.js", "./src/test.js"]
// entry: {
// index: "./src/index.js",
// test: ["./src/test.js"], // 特殊数组写法
// },
output: {
filename: "static/js/[name].js",
path: resolve(__dirname, "build"),
chunkFilename: "js/[name]~[contenthash:10].js", // 通过懒加Es6懒加载方式和optimization插件进行分割形成的chunk遵循这个命名规则
library: "[name]Lib", // 构建打包向外暴露名,即调用名。
libraryTarget: "window", // 绑定到window对象中,很多属性对象。
},
module: {
rules: [
// eslint语法检查
{
test: /\.js$/, // 通过正则匹配后缀名为.js的文件
enforce: "pre", // 设置loader的执行顺序,pre(优先)| post(延后)。
exclude: /node_modules/, // 排除node_modules目录下js文件的语法检查
loader: "eslint-loader", // 指定eslint-loader执行处理js文件进行语法检查
options: {
fix: true, // 配置参、空格、缩进不规范的语法自动进行修复。
},
},
{
// 当文件流到这个对象时,匹配到一个规则之后就不再向下匹配,优化构建打包速度。
oneOf: [
{
// 处理css文件的规则所需loader安装指令:npm i style-loader -D 和 npm i css-loader -D
test: /\.css$/,
// 处理文件时使用到多个lorder时,执行顺序为从下到上。
use: [
// "style-loader", // 处理创建style标签,将js中处理的资源添加到style标签中,再添加到页面head中生效。
{
loader: MiniCssExtractPlugin.loader, // 因为css引入js文件中,会造成js代码文件过大,所以通过MiniCssExtractPlugin构造函数自带loader取代style-loader,作用为将css抽离成为单个文件通过link标签引入。
options: {
publicPath: "../../", // 资源引入html文件时的路径前缀,因为css文件以及被单独抽离至特定目录下,正确修改才能匹配到css中引用的静态资源。
},
},
// 翻译css使webpack能够识别css样式语法
"css-loader",
{
loader: "postcss-loader", // 使用postcss进行浏览器兼容,使用的方法是在package.json中定义browserslist属性规则进行浏览器兼容性语法补全。
options: {
ident: "postcss",
plugins: () => [require("postcss-preset-env")],
},
},
],
},
{
// 处理less文件的规则所需loader安装指令:npm i less-loader -D 和 npm i less -D
test: /\.less$/,
use: [
// "style-loader",
{
loader: MiniCssExtractPlugin.loader,
options: {
publicPath: "../../",
},
},
"css-loader",
"less-loader",
],
},
{
// 处理图片文件的规则安装指令:cnpm i url-loader file-loader -D
test: /\.(png|jpe?g|gif|gif|svg)(\?.*)?$/,
loader: "url-loader",
options: {
limit: 80 * 1024, // 当图片小于80kb时采用base64的方式打包,大于则以图片形式打包。
name: "[hash:10].[ext]", // 每次webpack构建打包会生成一串不重复的hash码,[hash:10]则是去hash的前十位,[ext]取源文件的后缀名。
outputPath: "static/img", // 输出目录,output定义了输出目录为build,此处图片输出目录为build/static/img/XXX文件。
esModule: false, // 默认使用es6语法解析,html-loader使用的是commonjs语法引入,但2020年09月24日不用关闭url-loader的es6解析方法。
},
},
{
// 处理html中img等标签引入的图片资源所需loader安装指令:npm i html-loader -D
test: /\.html$/,
loader: "html-loader", // 处理url-loader仅能处理打包图片而不能处理html中资源的遗留问题。
},
{
// 处理引入字体图标资源所需loader安装指令:npm install file-loader -D
test: /(\.(ttf|woff|eot)$|iconfont\.svg)/,
loader: "file-loader",
options: {
name: "[hash:10].[ext]",
outputPath: "static/font",
},
},
{
test: /\.js$/,
exclude: /node_modules/,
use: [
{
// ,
loader: "thread-loader", // 建议项目足够大时打开多进程打包,开启经常需要600ms,进程通信也有开销。
options: {
works: 4, // 核数
},
},
{
loader: "babel-loader",
options: {
presets: [
// "@babel/preset-env" // 把下面数组的注释掉不会适配Promise等高级技术了,仅仅会转换let、const、箭头函数。
[
"@babel/preset-env",
{
useBuiltIns: "usage",
corejs: {
version: 3,
},
// 兼容范围
targets: {
chrome: "50",
firefox: "50",
ie: "10",
safari: "10",
edge: "18",
},
},
],
],
// 开启JS代码缓存,当文件名不变时,浏览器强制缓存js文件,导致修改的项目不能实时更新,所以应该在output中输出文件名中包含hash值,采用的是[content:10]的根据内容生成hash值的形式。没有采用hash是因为css在js中引入属于同一个chunk,输出时带有同一个hash值。
cacheDirectory: true,
},
},
],
},
],
},
],
},
// 插件使用需要先引入在new生成实例
plugins: [
// 无template属性时,默认在输出目录创建一个空的html文件,并将打包后的资源引入其中。template指明文件时,则复制文件,并引入打包后的资源。
new HtmlWebpackPlugin({
template: "./src/index.html",
minify: {
collapseWhitespace: true, // 清除空行缩进
removeAttributeQuotes: true, // 清除注释
},
}),
// 处理CSS从js文件中抽离生成独立文件
new MiniCssExtractPlugin({
filename: "static/css/app.css", // 文件输出目录
}),
// Css压缩插件
new OptimizeCssAssetsWebpackPlugin(),
// PWA离线缓存技术,优化使用体验,网络断开后刷新网页仍能够加载得到已经缓存的资源文件,依靠service Workers技术,插件执行后生成一个servicework配置文件,需要在入口文件中注册,兼容性判断。
new WorkboxWebpackPlugin.GenerateSW({
clientsClaim: true, // 帮助servicework快速启动
skipWaiting: true, // 删除旧版本使用最新的serviceworker技术
}),
new webpack.DllReferencePlugin({
manifest: resolve(__dirname, "dll/manifest.json"),
}),
new addAssetHtmlWebpackPlugin({
filepath: resolve(__dirname, "dll/jquery.js"),
}),
],
// mode: "development",
mode: "production", // 设置webpack的工作环境
// 打包构建忽略打包的库,并通过手动外部CDN引入。
// externals: {
// jquery: "jquery",
// },
devServer: {
contentBase: resolve(__dirname, "build"), // 运行代码目录
watchContentBase: true, // 监视contentBase下文件目录,发现文件变化则reload。
watchOptions: {
ignored: /node_modules/, // 忽略文件
},
compress: true, // 采用gzip压缩代码体积会更小
port: 9527,
host: "localhost",
open: true, // 自动打开浏览器
hot: true, // 开启HMR功能,提高开发环境打包的效率。
clientLogLevel: "none", // 不需要开启webpack启动日志信息
quiet: true, // 仅仅显示基本信息
overlay: true, // 不要全屏显示报错
proxy: {
"/api": {
// 处于5000端口的devserver接收到/api的请求,会将请求代理转发到3000端口下的服务。
target: "http://localhost:3000/",
// 去掉/api,路径替换重写为http://localhost:3000/文件。
pathRewrite: {
"^/api": "",
},
},
},
},
// 解析模块
resolve: {
alias: {
assets: resolve(__dirname, "src/assets/"), // 设置路径别名
},
// extensions: ["js", "css", "vue", "json"], // 引入时可省略的后缀名
modules: ["node_modules"],
},
// 将node_modules里面的库单独打包成一个文件verdor.js,配置项太多了,官网自行查看。
optimization: {
splitChunks: {
chunks: "all", // 所有配置均为默认
},
// 入口文件打包的主构建文件(main)需要引用其他的chunk,打包生成后main会存有其他chunk打包的hash值(使用contenthash方式命名),一旦其他chunk发生改动,main也需要重新打包构建,会造成缓存失效,此配置将main文件中记录其他chunk的hash值打包成为一个单独的文件。再将此文件引入main,达到解耦的效果。
runtimeChunk: {
name: (entrypoint) => `runtime-${ entrypoint.name}`,
},
// 通过Terser压缩js代码
minimizer: [
new TerserWebpackPlugin({
// 开启缓存
cache: true,
// 开启多进程打包
parallel: true,
// 启用sourceMap,否则会被压缩掉。
sourceMap: true,
}),
],
},
devtool: "source-map", // 构建后代码到源代码的有一种映射技术,js输出目录下回多出一个xxx.js.map文件,如果构建代码出错了,通过映射关系能找到源代码的位置,非常利于调试代码,但是也会造成代码被盗用的安全性问题。
};
package.json详细配置
{
"name": "webpack",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"devDependencies": {
"@babel/core": "^7.11.6",
"@babel/polyfill": "^7.11.5",
"@babel/preset-env": "^7.11.5",
"add-asset-html-webpack-plugin": "^3.1.3",
"babel-loader": "^8.1.0",
"core-js": "^3.6.5",
"css-loader": "^4.3.0",
"eslint": "^7.9.0",
"eslint-config-airbnb-base": "^14.2.0",
"eslint-loader": "^4.0.2",
"eslint-plugin-import": "^2.22.0",
"file-loader": "^6.1.0",
"html-loader": "^1.3.1",
"html-webpack-plugin": "^4.5.0",
"jquery": "^3.5.1",
"less": "^3.12.2",
"less-loader": "^7.0.1",
"mini-css-extract-plugin": "^0.11.2",
"optimize-css-assets-webpack-plugin": "^5.0.4",
"postcss-loader": "^3.0.0",
"postcss-preset-env": "^6.7.0",
"style-loader": "^1.2.1",
"terser-webpack-plugin": "^4.2.2",
"thread-loader": "^3.0.0",
"url-loader": "^4.1.0",
"webpack": "^4.44.2",
"webpack-cli": "^3.3.12",
"webpack-dev-server": "^3.11.0",
"workbox-webpack-plugin": "^5.1.4"
},
"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": {
"brower": true
}
},
"sideEffects": [
"*.css"
]
}
寄语
一篇肝了好久的webpack,篇幅很长再加上个人理解可能会有瑕疵,希望大牛别喷,给出的详细webpack.config.js文件我也已经测试过了,我写了很详细的注释,希望能帮到大家!但是如果转载的话希望大家也能注明一下出处!
支持
个人开发了一个资源网址导航网站,很多资源分享,vue项目第一次进会慢一些些,但是过后就很快了,涵盖了生活的方方面面,认真逛逛绝对会有收获,无广告且有软件分享。希望大家支持一下!n.huasenjio.top,如果进不出意外的话我会把这个开源给大家!大家的访问也许对我就是一种鼓励了,谢谢大家!