webpack
课程笔记在线地址
配置代码实例分析
webpack 配置 最完整的[含大部分优化]
// nodejs核心模块,直接使用
const os = require("os");
// 而对 js 文件处理主要就是 eslint 、babel、Terser 三个工具,所以我们要提升它们的运行速度
// 我们可以开启多进程同时处理 js 文件,这样速度就比之前的单进程打包更快了
// cpu核数 多进程打包:开启电脑的多个进程同时干一件事,速度更快。
// 需要注意:请仅在特别耗时的操作中使用,因为每个进程启动就有大约为 600ms 左右开销
const threads = os.cpus().length;
const path = require("path")
//凡是插件 都要 new 一下子 凡是 loader 可以直接使用
// 处理 编译时候 Eslint 错误规则
const ESLintPlugin = require('eslint-webpack-plugin');
// 处理 编译后的 html 中 js css 的自动引入,少的时候 index.html 手动引入 dist/main.js 多了可并不行
// 需要指定模板 让它自动引入 需要的资源
const HtmlWebpackPlugin = require("html-webpack-plugin");
//把css的style标签 变为单文件 防止加载抖动 minicss 顾名思义 变成 mini小文件
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
//压缩main.css 里面的换行等格式和一些可以省略合并的格式
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
//压缩js代码[删除备注之类的 调试输出之类的]
const TerserPlugin = require("terser-webpack-plugin");
//处理 Preload / Prefetch 空闲时候的预加载机制 比如 点击的时候 import
const PreloadWebpackPlugin = require("@vue/preload-webpack-plugin");
/*
关于 babel 兼容问题 不彻底的情况
问题:
对于 es6 的 箭头函数 等等基本的可以兼容 对于 promise includes 等后期的 ES 无法兼容 原样输出
解决:
安装 npm i core-js 并在 需要使用 Promise 的页面 引入 import "core-js"; 可以解决 但是问题是 全部引入 没有使用的也引入了 能不能按需引入呢
可手动按路径到 node_modules 里 找到 core-js 下面对应的目录 引入 但是太过麻烦 能不能自动按需引入呢
3.更改 babel.config.js 的配置
presets: [
[
"@babel/preset-env",
// 按需加载core-js的polyfill
{ useBuiltIns: "usage", corejs: { version: "3", proposals: true } }
],
]
*/
function cssLoad(specialLoad) {
//use 的解析 从下到上 从右到左
//为什么呢 方便后面的补充 比如 less 解析为 css ,css 在解析为 style形式 插入进去
return [
//Css 文件目前被打包到 js 文件中,当 js 文件加载时,会创建一个 style 标签来生成样式 这样对于网站来说,会出现闪屏现象,用户体验不好
//我们应该是单独的 Css 文件,通过 link 标签加载性能才好 需要 mini-css-extract-plugin 来把style变成单文件 link 引入 替换掉下面的 "style-loader"
MiniCssExtractPlugin.loader,
//style-loader 编译到dist index.html 里面的时候 仍然是 只有一个 main.js 没有css样式 到客户端执行的时候 js才把css样式 解析为 style标签 所以会产生页面抖动
// "style-loader",//所以这个就退休了 因为它是将js的css样式 比如 div.style.borerColor = "red" 转换为 style <style>div{border-color:red}</style>
"css-loader",// 它 将在index.js 中 引入的 css 转换为 js 的 css样式 比如 div.style.borerColor = "red"
//css兼容处理 根据设置兼容到IE8 或者 IE9 css 的样式会夹 -ms- 之类的前缀 或者其他的变通模式 来适应需要兼容到的 浏览器版本
//需要配合 package.json 的设置
// "browserslist": [
// //css 兼容浏览器处理 该设置用于配合 postcss-loader
// "ie >= 8"
// // "last 2 version",
// // "> 1%",
// // "not dead"
// ]
{
loader: "postcss-loader",
options: {
postcssOptions: {
plugins: [
"postcss-preset-env", // 能解决大多数样式兼容性问题
],
},
},
},
specialLoad
].filter(Boolean)
}
module.exports = {
// 多入口文件的写法 输出的时候 filename: "js/[name].js", 中的name 就是这里的 main 和 app
// entry: {
// main: "./src/main.js",
// app: "./src/app.js",
// },
//enrty属性的值其相对的路径不是webpack.config.js文件所在路径,而是项目的根路径
entry: "./index.js",//相对路径 相对于项目根目录的路径 就是 相对于 package.json 的路径 很显然和 package.json 在同一层目录
output: {
path: path.resolve(__dirname, "../dist"),//绝对路径
// filename: "js/main.js",//编译的输出入口文件
// filename: "js/[name].js", //该 name 就是 多/单 entry 的 main app index
//注意 hash 分:hash:8 contenthash:8 如何是 hash 所有文件同一时间都一样 如果是 contenthash 每个文件都不同
// filename: "js/[name][hash:8].js", // 入口文件打包输出资源命名方式
filename: "js/[name].[contenthash:8].js", // 入口文件打包输出资源命名方式
//这里的 [name] 会显示什么 取决于 下面的设置
// webpackChunkName: "math-test":这是webpack动态导入模块命名的方式
// "math-test"将来就会作为[name]的值显示。
// 像注释一样的 魔法设置 真他妈的变态
// import(/* webpackChunkName: "abc_math" */ "./src/js/math-test.js").then(({ abc }) => {
// console.log(abc(1111))
// }).catch(err => {
// console.log(err)
// })
// 和上面 引入的模块名字没有半毛钱关系 只和 这个 魔法 设置有关 /* webpackChunkName: "abc_math" */ 哈哈 在代码中插入注释
// chunkFilename: "js/[name].chunk[hash:8].js", // 动态导入输出资源命名方式
chunkFilename: "js/[name].chunk.[contenthash:8].js", // 动态导入输出资源命名方式
assetModuleFilename: "media/[name].[hash:8][ext]", // 图片、字体等资源命名方式(注意用hash)
clean: true//每次编译删除之前的
},
module: {
rules: [
{
//默认情况下 如果匹配到css 仍然 继续往下面执行 效率很低 用 oneOf 一旦匹配到 就执行 并停止 rules 的向下面 匹配
oneOf: [
{
test: /\.css$/,
use: cssLoad()
},
{
test: /\.less$/,
use: cssLoad("less-loader")
},
{
test: /\.s[ac]ss$/,
use: cssLoad("sass-loader")
},
{
//匹配所有图片
test: /\.(jp?g|png|gif|webp|svg)$/,
type: "asset",
parser: {
dataUrlCondition: {
maxSize: 10 * 1024
}
},
//生成目录
generator: {
// // 将图片文件输出到 dist/images 目录中
// // 将图片文件命名 [hash:10][ext][query]
// // [hash:8]: hash值取8位
// // [ext]: 使用之前的文件扩展名
// // [query]: 添加之前的query参数
filename: "images/[hash:10][ext][query]"
}
},
{
//匹配所有字体 媒体
//注意这个地方尾部
test: /\.(ttf|woff|woff2|mp4|mp3|avi)$/,
//不解析图片 无论多小 必须生成资源 也就是原始输出 避免被解析成 data数据
type: "asset/resource",
//生成目录
generator: {
filename: "media/[hash:10][ext][query]"
}
},
{
test: /\.js$/,
// exclude: /node_modules/, // 排除node_modules代码不编译
include: path.resolve(__dirname, "../src"), // 也可以用包含
//处理js兼容问题
// start 单线程
// loader: "babel-loader", // 和 loader: "babel-loader" use: ["babel-loader"] 等价 但是后面这一种 无法加 options 缓存选项
// //对于修改的文件重新编译 对于没有修改的文件 不用重新编译 用缓存中的
// options: {
// cacheDirectory: true, // 开启babel编译缓存
// cacheCompression: false, // 缓存文件不要压缩
// }
// end 单线程
// start 多线程
use: [
{
loader: "thread-loader", // 开启多进程
options: {
//多线程数量 cpu 核数
workers: threads, // 数量
},
},
{
loader: "babel-loader",
options: {
cacheDirectory: true, // 开启babel编译缓存
cacheCompression: false, // 缓存文件不要压缩
//@babel/plugin-transform-runtime有三大作用:
// 1.自动移除语法转换后内联的辅助函数(inline Babel helpers),使用@babel/runtime/helpers里的辅助函数来替代;
// 2.当代码里使用了core-js的API,自动引入@babel/runtime-corejs3/core-js-stable/,以此来替代全局引入的core-js/stable;
// 3.当代码里使用了Generator/async函数,自动引入@babel/runtime/regenerator,以此来替代全局引入的regenerator-runtime/runtime;
plugins: ["@babel/plugin-transform-runtime"], // 减少代码体积
},
},
],
// end 多线程
// 这个等价于 在 babel.config.js 中 配置 预设
// use:{
// loader: "babel-loader",
//
// options: {
// presets: ["@babel/preset-env"]
// }
// }
}
]
}
]
},
plugins: [
new ESLintPlugin({
//检查js的语法 根据自己定制的要求 定制要求在 .relintrc.js
//指定检查文件的目录
context: path.resolve(__dirname, "../src"),
//然后在根目录创建 .eslintrc.js
exclude: "node_modules", // 默认值 这个src 目录下面 除了node_modules 目录不检查 其他都要检查
//开启缓存 如果文件没有改变 就不检查语法 维持上次的检查结果 就是缓存里面的
cache: true, // 开启缓存
// 缓存目录 把缓存缓存到哪里
cacheLocation: path.resolve(
__dirname,
"../node_modules/.cache/.eslintcache"
)
}),
new HtmlWebpackPlugin({
// 以 index.html 为模板创建文件
// 新的html文件有两个特点:1. 内容和源文件一致 2. 自动引入打包生成的js等资源
template: path.resolve(__dirname, "../src/template/index.html")
}),
//把 style 标签 css 转为 link 文件形式
new MiniCssExtractPlugin({
// 定义输出文件名和目录 这里必须是相对路径 相对于当前文件的路径
// filename: "../dist/css/main.css"
// 定义输出文件名和目录
// 这里的 [name] 和入口文件挂钩
filename: "../dist/css/[name].[contenthash:8].css",
chunkFilename: "../dist/css/[name].[contenthash:8].chunk.css",
}),
// 预加载的意义
// 我们前面已经做了代码分割,同时会使用 import 动态导入语法来进行代码按需加载(我们也叫懒加载,比如路由懒加载就是这样实现的)。
// 但是加载速度还不够好,比如:是用户点击按钮时才加载这个资源的,如果资源体积很大,那么用户会感觉到明显卡顿效果。
// 我们想在浏览器空闲时间,加载后续需要使用的资源。我们就需要用上 Preload 或 Prefetch 技术。
// Preload:告诉浏览器立即加载资源。
// Prefetch:告诉浏览器在空闲时才开始加载资源
// 它们共同点:
// 都只会加载资源,并不执行。
// 都有缓存。
// Preload加载优先级高,Prefetch加载优先级低
// Preload只能加载当前页面需要使用的资源,Prefetch可以加载当前页面资源,也可以加载下一个页面需要使用的资源
//preload 比 prefetch 兼容性好 但 prefetch 比 prrload 更科学
new PreloadWebpackPlugin({
rel: "preload", // preload兼容性更好
as: "script",
// rel: 'prefetch' // prefetch兼容性更差 如果设置 prefetch 不需要 as 配置项
}),
],
optimization: {
//优化有关的配置
minimize: true,
minimizer: [
//1.压缩图片没有配置
//2.css压缩也可以写到optimization.minimizer里面,效果一样的
//压缩丑化css 可以放在插件[plugins]里面
new CssMinimizerPlugin(),
//3.当生产模式会默认开启TerserPlugin,但是我们需要进行其他配置,就要重新写了
// 默认不开启多线程 但这里开启了多线程
new TerserPlugin({
//压缩js代码[删除备注之类的 调试输出之类的]
parallel: threads // 开启多进程
})
],
// 提取runtime文件
// 问题:
// 当我们修改 math.js 文件再重新打包的时候,因为 contenthash 原因,math.js 文件 hash 值发生了变化(这是正常的)。
// 但是 main.js 文件的 hash 值也发生了变化,这会导致 main.js 的缓存失效。明明我们只修改 math.js, 为什么 main.js 也会变身变化呢?
// 原因是:
// 更新前:math.xxx.js, main.js 引用的 math.xxx.js
// 更新后:math.yyy.js, main.js 引用的 math.yyy.js, 文件名发生了变化,间接导致 main.js 也发生了变化
// 怎么解决:
// 将 hash 值单独保管在一个 runtime 文件中。
// 我们最终输出三个文件:main、math、runtime。当 math 文件发送变化,变化的是 math 和 runtime 文件,main 不变。
// runtime 文件只保存文件的 hash 值和它们与文件关系,整个文件体积就比较小,所以变化重新请求的代价也小。
runtimeChunk: {
name: (entrypoint) => `runtime~${entrypoint.name}`, // runtime文件命名规则
},
splitChunks: {
//1.什么是 module chunk bundle:
// 1.要理解splitChunks,先要理解webpack的提出的几个概念,module、chunk和bundle。
// 2.module:每个import引入的文件就是一个模块(也就是直接手写的代码)
// 3.chunk:当module源文件传到webpack进行打包时,webpack会根据文件引用关系生成chunk(也就是module在webpack处理时是chunk)
// 4.bundle:是对chunk进行压缩等处理后的产出(也就是打包后可以直接运行的文件
//2.webapck拆分出的chunk有四种:
// 1.根据入口文件拆分
// 2.根据异步文件拆分(import(‘…’))
// 3.根据spliteChunk拆分
// 4.还有一些运行时runtimeChunk,负责
// 1.形如 import('abc').then(res=>{}) 这种异步加载的代码,在webpack中即为运行时代码
// 2.每次更改所谓的运行时代码文件时,打包构建时app.js的hash值是不会改变的。如果每次项目更新都会更改app.js的hash值,
//1. 那么用户端浏览器每次都需要重新加载变化的app.js,如果项目大切优化分包没做好的话会导致第一次加载很耗时,导致用户体验变差。
//2. 现在设置了runtimeChunk,就解决了这样的问题。所以 这样做的目的是避免文件的频繁变更导致浏览器缓存失效,所以其是更好的利用缓存。提升用户体验。
//代码分割配置 的意义:
// 1.mouduleA moduleB 都引入了 moduleMath 如果不分割出来 moduleMath 会被引入两次
// 2.import("./moduleA").then().catch() 的延迟加载 都需要独立的 js 文件 不访问 不加载
//chunks 有哪些数值
// 1.chunks:initial
// 1.当为initial时,只能分离初始化的模块,异步的模块无法分离
// 2.chunks:all
// 1.将初始化或者异步的模块都分离出来
// 3.当splitChunks.chunk为一个函数时,可以自行选择哪些chunk需要被分离
// 1.chunks: (chunk) => {return chunk.name !== 'test' && chunk.name !== 'math'}
chunks: "all", // 对所有模块都进行分割
//关于下面几个的优先级:maxInitialRequest/maxAsyncRequests < maxSize < minSize
// 以下是默认值
// minSize: 20000, // 分割代码最小的大小
// minRemainingSize: 0, // 类似于minSize,最后确保提取的文件大小不能为0
// minChunks: 1, // 至少被引用的次数,满足条件才会代码分割
// maxAsyncRequests: 30, // 按需加载时并行加载的文件的最大数量
// maxInitialRequests: 30, // 入口js文件最大并行请求数量
// enforceSizeThreshold: 50000, // 超过50kb一定会单独打包(此时会忽略minRemainingSize、maxAsyncRequests、maxInitialRequests)
// cacheGroups: { // 组,哪些模块要打包到一个组
// defaultVendors: { // 组名
// test: /[\\/]node_modules[\\/]/, // 需要打包到一起的模块
// priority: -10, // 权重(越大越高)
// reuseExistingChunk: true, // 如果当前 chunk 包含已从主 bundle 中拆分出的模块,则它将被重用,而不是生成新的模块
// },
// default: { // 其他没有写的配置会使用上面的默认值
// minChunks: 2, /最少被两个模块引入的 chunk 需要打包
// priority: -20,//权重 / 这里的minChunks权重更大
// reuseExistingChunk: true,
// },
// },
// 修改配置
cacheGroups: {
// 组,哪些模块要打包到一个组
// defaultVendors: { // 组名
// test: /[\\/]node_modules[\\/]/, // 需要打包到一起的模块
// priority: -10, // 权重(越大越高)
// reuseExistingChunk: true, // 如果当前 chunk 包含已从主 bundle 中拆分出的模块,则它将被重用,而不是生成新的模块
// },
//多入口设置 如果是 单入口文件 设置无效
// default: {
// // 其他没有写的配置会使用上面的默认值
// minSize: 0, // 我们定义的文件体积太小了,所以要改打包的最小文件体积
// minChunks: 2,///最少被两个模块引入的 chunk 需要打包
// priority: -20,//权重
// reuseExistingChunk: true,
// },
},
},
},
// 开发服务器
devServer: {
host: "127.0.0.1", // 启动服务器域名
port: "999", // 启动服务器端口号
open: true, // 是否自动打开浏览器
hot: true, // 开启HMR功能 热模块替换 无需刷新整个页面 (只能用于开发环境,生产环境不需要了)
watchFiles: ["./src/template/index.html"],
},
//当前的模式
mode: "production",
// mode: "development"
//如何生成 source map 下面这个配置 有行没有列 速度比 有行有列的快
// devtool: "cheap-module-source-map",
//source map 有行有列 很慢
devtool: "source-map"
}
webpack 配置 和 安装
安装
1.npm i webpack webpack-cli --save-dev
babel
1.npm i babel-loader @babel/core @babel/preset-env -D
1.webpack rules 中的配置
{
test: /\.js$/,
exclude: /node_modules/, // 排除node_modules代码不编译
loader: "babel-loader",
}
2.babel.config.js 配置预设
module.exports = {
presets: ["@babel/preset-env"] // 智能预设
};.
关于eslint的几种方式
1.安装 vscode 插件 eslint 直接代码提示报错 方便看出来
1.但是 编译后的 文件很多 不按常理出牌 所以要忽略掉检查 dist 文件夹
2.在根目录下新建 文件 .eslintignore 忽略文件 忽略的规则如下
3.它也会读取 .eslintrc.js 配置 也就是说 .eslintrc.js .eslintignore 同时作用于 vscode 的 Eslint 插件
4.修改 .eslintrc.js 立即生效 但是修改 eslintignore 无效 不知道为什么
2.在webpack中配置的方式 等到编译才会报错 报错的行不准
1.npm "eslint-webpack-plugin": "^4.0.1",
2.在webapck中引入 const ESLintPlugin = require('eslint-webpack-plugin'); 在 plungins 中 new 实例
new ESLintPlugin({
//检查cs的语法 根据自己定制的要求
//只检查
context:path.resolve(__dirname,"src")
//然后在根目录创建 .eslintrc.js
})
3.在根目录下新建 .eslintrc.js 简单配置如下
module.exports = {
root: true,
parserOptions: {
ecmaVersion: 6,
parser: 'babel-eslint',
sourceType: 'module'
},
env: {
browser: true,
node: true,
es6: true,
},
//继承自哪里
extends: [
// 'plugin:vue/recommended', //还需要引入 vue
'eslint:recommended'
],
// add your custom rules here
rules: {
"no-var": 0 //不能有 var 声明 否则报错 0 off 1 warn 2 error
}
}
4.几种简单的 配置 rules 说明
rules: {
semi: "error", // 禁止使用分号
'array-callback-return': 'warn', // 强制数组方法的回调函数中有 return 语句,否则警告
'default-case': [
'warn', // 要求 switch 语句中有 default 分支,否则警告
{ commentPattern: '^no default$' } // 允许在最后注释 no default, 就不会有警告了
],
eqeqeq: [
'warn', // 强制使用 === 和 !==,否则警告
'smart' // https://eslint.bootcss.com/docs/rules/eqeqeq#smart 除了少数情况下不会有警告
],
}
5.简单配置
// 例如在React项目中,我们可以这样写配置
module.exports = {
extends: ["react-app"],
rules: {
// 我们的规则会覆盖掉react-app的规则
// 所以想要修改规则直接改就是了
eqeqeq: ["warn", "smart"],
},
};
.eslintrc.js 详细配置如下 [多得吓人]
module.exports = {
root: true,
parserOptions: {
ecmaVersion: 6,
parser: 'babel-eslint',
sourceType: 'module'
},
env: {
browser: true,
node: true,
es6: true,
},
//继承自哪里
extends: [
// 'plugin:vue/recommended', //还需要引入 vue
'eslint:recommended'
],
// add your custom rules here
//it is base on https://github.com/vuejs/eslint-config-vue
rules: {
"no-var": 2 //不能有 var 声明 否则报错
"vue/max-attributes-per-line": [2, {
"singleline": 10,
"multiline": {
"max": 1,
"allowFirstLine": false
}
}],
"vue/singleline-html-element-content-newline": "off",
"vue/multiline-html-element-content-newline": "off",
"vue/name-property-casing": ["error", "PascalCase"],
"vue/no-v-html": "off",
'accessor-pairs': 2,
'arrow-spacing': [2, {
'before': true,
'after': true
}],
'block-spacing': [2, 'always'],
'brace-style': [2, '1tbs', {
'allowSingleLine': true
}],
'camelcase': [0, {
'properties': 'always'
}],
'comma-dangle': [2, 'never'],
'comma-spacing': [2, {
'before': false,
'after': true
}],
'comma-style': [2, 'last'],
'constructor-super': 2,
'curly': [2, 'multi-line'],
'dot-location': [2, 'property'],
'eol-last': 2,
'eqeqeq': ['off'],//"error", "always", {"null": "ignore"}
'generator-star-spacing': [2, {
'before': true,
'after': true
}],
'handle-callback-err': [2, '^(err|error)$'],
'indent': [2, 2, {
'SwitchCase': 1
}],
'jsx-quotes': [2, 'prefer-single'],
'key-spacing': [2, {
'beforeColon': false,
'afterColon': true
}],
'keyword-spacing': [2, {
'before': true,
'after': true
}],
'new-cap': [2, {
'newIsCap': true,
'capIsNew': false
}],
'new-parens': 2,
'no-array-constructor': 2,
'no-caller': 2,
'no-console': 'off',
'no-class-assign': 2,
'no-cond-assign': 2,
'no-const-assign': 2,
'no-control-regex': 0,
'no-delete-var': 2,
'no-dupe-args': 2,
'no-dupe-class-members': 2,
'no-dupe-keys': 2,
'no-duplicate-case': 2,
'no-empty-character-class': 2,
'no-empty-pattern': 2,
'no-eval': 2,
'no-ex-assign': 2,
'no-extend-native': 2,
'no-extra-bind': 2,
'no-extra-boolean-cast': 2,
'no-extra-parens': [2, 'functions'],
'no-fallthrough': 2,
'no-floating-decimal': 2,
'no-func-assign': 2,
'no-implied-eval': 2,
'no-inner-declarations': [2, 'functions'],
'no-invalid-regexp': 2,
'no-irregular-whitespace': 2,
'no-iterator': 2,
'no-label-var': 2,
'no-labels': [2, {
'allowLoop': false,
'allowSwitch': false
}],
'no-lone-blocks': 2,
'no-mixed-spaces-and-tabs': 2,
'no-multi-spaces': 2,
'no-multi-str': 2,
'no-multiple-empty-lines': [2, {
'max': 1
}],
'no-native-reassign': 2,
'no-negated-in-lhs': 2,
'no-new-object': 2,
'no-new-require': 2,
'no-new-symbol': 2,
'no-new-wrappers': 2,
'no-obj-calls': 2,
'no-octal': 2,
'no-octal-escape': 2,
'no-path-concat': 2,
'no-proto': 2,
'no-redeclare': 2,
'no-regex-spaces': 2,
'no-return-assign': [2, 'except-parens'],
'no-self-assign': 2,
'no-self-compare': 2,
'no-sequences': 2,
'no-shadow-restricted-names': 2,
'no-spaced-func': 2,
'no-sparse-arrays': 2,
'no-this-before-super': 2,
'no-throw-literal': 2,
'no-trailing-spaces': 2,
'no-undef': 2,
'no-undef-init': 2,
'no-unexpected-multiline': 2,
'no-unmodified-loop-condition': 2,
'no-unneeded-ternary': [2, {
'defaultAssignment': false
}],
'no-unreachable': 2,
'no-unsafe-finally': 2,
'no-unused-vars': [2, {
'vars': 'all',
'args': 'none'
}],
'no-useless-call': 2,
'no-useless-computed-key': 2,
'no-useless-constructor': 2,
'no-useless-escape': 0,
'no-whitespace-before-property': 2,
'no-with': 2,
'one-var': [2, {
'initialized': 'never'
}],
'operator-linebreak': [2, 'after', {
'overrides': {
'?': 'before',
':': 'before'
}
}],
'padded-blocks': [2, 'never'],
'quotes': [2, 'single', {
'avoidEscape': true,
'allowTemplateLiterals': true
}],
'semi': [2, 'never'],
'semi-spacing': [2, {
'before': false,
'after': true
}],
'space-before-blocks': [2, 'always'],
'space-before-function-paren': [2, 'never'],
'space-in-parens': [2, 'never'],
'space-infix-ops': 2,
'space-unary-ops': [2, {
'words': true,
'nonwords': false
}],
'spaced-comment': [2, 'always', {
'markers': ['global', 'globals', 'eslint', 'eslint-disable', '*package', '!', ',']
}],
'template-curly-spacing': [2, 'never'],
'use-isnan': 2,
'valid-typeof': 2,
'wrap-iife': [2, 'any'],
'yield-star-spacing': [2, 'both'],
'yoda': [2, 'never'],
'prefer-const': 2,
'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0,
'object-curly-spacing': [2, 'always', {
objectsInObjects: false
}],
'array-bracket-spacing': [2, 'never']
}
}
杂项
1.webpack-dev-server 仅仅用于开发的时候 网页同步刷新 编译不写出代码 在内存中运行
1.npx webpack serve
2.如何解决 webpack-dev-server 不会自动刷新的问题 有两个方法:
1.方法1
devServer: {
watchFiles: [./src/index.html],
}
2.方法2(入口处添加)
entry: ["./src/index.js", "./src/index.html"]
webpack相关资源网站
1.https://webpack.docschina.org/
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通