从0搭建webpack5+react18多页面模版
一、初始化项目
在本地新创建一个文件夹w5-react-mpa-h5,在该文件夹内执行终端命令
npm init -y
初始化好package.json后,在项目下新增以下所示目录结构和文件
|-config
| |- bin.js
| |- getPages.js
| |- webpack.base.js
| |- webpack.dev.js
| |- webpack.prod.js
|-public
| |-index.html
| |-normalize.css
|-src
| |-pages
| | |-home
| | | |-index.js
| | |-main
| | | |-index.js
| | | |-index.ejs
| | | |-setting.json
|-index.ejs
|-package.json
|-yarn.lock
1.安装webpack等相关插件
yarn add webpack webpack-cli webpack-dev-server html-webpack-plugin -D
2.安装react,react-dom
yarn add react react-dom -S
3.添加index.ejs模版文件
<!DOCTYPE html>
<html style="font-size: 75px">
<head>
<title><%= title %></title>
<meta charset="utf-8" />
<meta http-equiv="Expires" content="0" />
<meta http-equiv="Pragma" content="no-cache" />
<meta http-equiv="Cache-control" content="no-cache" />
<meta http-equiv="Cache" content="no-cache" />
<meta
name="viewport"
content="width=device-width, initial-scale=1.0"
/>
<link rel="stylesheet" href="public/normalize.css" />
<% styles.forEach(function(href){ %>
<link rel="stylesheet" href="<%=href%>" />
<% }) %>
</head>
<body>
<div id="root"></div>
<% scripts.forEach(function(src){ %>
<script src="<%=src%>"></script>
<% }) %>
</body>
</html>
4.添加home/index.js页面内容
import React from 'react';
import { createRoot } from 'react-dom/client';
const App = ()=> {
return <div>111</div>
}
const root = document.getElementById('root');
if(root) {
createRoot(root).render(<App />)
}
二、基础配置
1.添加webpack.base基础配置
const path = require('path');
const webpack = require('webpack');
const getPages = require('./getPages');
const [n, b, page] = process.argv; // 获取文件路径
const {entry, htmlPlugin} = getPages(page); // 获取入口文件
module.exports = {
context: process.cwd(),
entry,
output: {
path: path.resolve(__dirname, '..', 'dist'),
clean: true,
filename: '[name]/index.js'
}
}
const fs = require('fs');
const path = require('path');
const getEntry = (page) => {
const pages = path.resolve(process.cwd(), 'src/pages');
if (page) {
return {
[page]: [path.resolve(pages, page, './index')],
};
}
const files = fs.readdirSync(pages);
const entry = files.reduce((a, b) => {
return {
...a,
[b]: [path.resolve(pages, b, "./index")]
};
}, {});
return entry;
};
const getHtmlPlugins = (entry)=> {
const htmlPlugins = [];
return htmlPlugins;
}
const getPages = (page)=> {
const entry = getEntry(page);
const htmlPlugin = getHtmlPlugins(entry);
return {
entry,
htmlPlugin
}
}
module.exports = getPages;
2.安装babel核心模块和babel预设
npm i babel-loader @babel/core @babel/preset-react @babel/preset-env core-js -D
3.编辑webpack.base.js的loader配置
module: {
...
rules: [{
test: /\.jsx?$|tsx?$/, // 匹配.js, jsx文件
use: {
loader: 'babel-loader',
options: {
presets: [
[
'@babel/preset-env', // babel 编译的预设,可以转换目前最新的js标准语法
{
"targets": '> 0.25%, not dead', // 设置兼容目标浏览器版本
"useBuiltIns": 'usage', // 根据配置的浏览器兼容,以及代码中使用到的api进行引入polyfill按需添加
"corejs": 3, // 配置使用core-js低版本
"modules": false, // 是否将 ESM 转化为其他模块化标准将此设置为 false 将保留 ESM 不受转换
},
],
'@babel/preset-react',
]
}
},
exclude: /node_modules/ // 先过滤掉不然启动会报错
}],
},
4.添加plugin插件
用到的插件:
html-webpack-plugin,webpack需要把最终构建好的静态资源都插入到html文件中,这样才能在浏览器中运行
webpack.DefinePlugin,webpack内置的插件,可以为业务代码注入环境变量.
yarn add copy-webpack-plugin -D
const {entry, htmlPlugin} = getPages(page);
module.exports = {
//...
//...
plugins: [
...htmlPlugin,
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV),
'process.env.RUNTIME_ENV': JSON.stringify(process.env.RUNTIME_ENV),
}),
new CopyPlugin({
patterns: Object.keys(entry).map((key) => ({
from: 'public',
to: `${key}/public`,
}))
}),
]
}
5.生成htmlPlugin
const fs = require('fs');
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const getEntry = (page) => {
const pages = path.resolve(process.cwd(), 'src/pages');
if (page) {
return {
[page]: [path.resolve(pages, page, './index')],
};
}
const files = fs.readdirSync(pages);
const entry = files.reduce((a, b) => {
return {
...a,
[b]: [path.resolve(pages, b, "./index")]
};
}, {});
return entry;
};
const getHtmlPlugins = (entry)=> {
const htmlPlugins = [];
Object.keys(entry).forEach((key) => {
// 页面目录
const pageRoot = path.resolve(process.cwd(), `src/pages/${key}`);
// 默认配置
const params = {
filename: `${key}/index.html`,
template: path.resolve(process.cwd(), `index.ejs`),
templateParameters: {
title: '',
scripts: [],
styles: [],
},
chunks: [key],
};
// 读取页面配置
const existsSetting = fs.existsSync(`${pageRoot}/setting.json`);
if (existsSetting) {
params.templateParameters = Object.assign(
params.templateParameters,
require(`${pageRoot}/setting.json`),
);
}
// 自定义页面是否存在
const existsEjs = fs.existsSync(`${pageRoot}/index.ejs`);
if (existsEjs) {
params.template = path.resolve(process.cwd(),`${pageRoot}/index.ejs`)
}
htmlPlugins.push(new HtmlWebpackPlugin(params));
});
return htmlPlugins;
}
const getPages = (page)=> {
const entry = getEntry(page);
const htmlPlugin = getHtmlPlugins(entry);
return {
entry,
htmlPlugin
}
}
module.exports = getPages;
6.开发环境配置:
合并基础配置,安装webpack-merge
yarn add webpack-merge -D
const baseConfig = require('./webpack.base.js');
const path = require('path');
const { merge } = require('webpack-merge')
module.exports = merge(baseConfig, {
mode: 'development',
devtool: 'inline-source-map',
devServer: {
port: 3001, // 服务端口号
compress: false, // gzip压缩,开发环境不开启,提升热更新速度
hot: true, // 开启热更新
static: {
directory: path.resolve(process.cwd(), '../public'), //托管静态资源public文件夹
publicPath: '/',
}
}
});
7.添加执行命令和环境变量
在package.json里配置npm scripts 命令
安装cross-env兼容各系统的设置环境变量的包
yarn add cross-env -D
"scripts": {
"start": "cross-env NODE_ENV=development RUNTIME_ENV=development node config/bin.js",
},
8.执行bin文件
在bin.js内配置执行环境,安装colors,在控制台输出时可以添加颜色
yarn add colors -D
const webpack = require('webpack');
const WebpackDevServer = require('webpack-dev-server'); // 版本4.0以上
const colors = require('colors');
const [n, s, page] = process.argv;
const env = process.env.NODE_ENV;
const RUNTIME_ENV = process.env.RUNTIME_ENV;
// 开发环境
const serve = async () => {
const devConfig = require('./webpack.dev');
const compiler = webpack(devConfig);
const devServerOptions = { ...devConfig.devServer, host: "localhost"};
const server = new WebpackDevServer(devServerOptions, compiler);
await server.start();
const host = `http://localhost:${devConfig.devServer.port}`;
console.log(`服务启动:${host}/${page || '目录名'}/index.html`.yellow);
};
// 生产环境
const build = () => {
const prodConfig = RUNTIME_ENV === 'analyzer' ? require('./webpack.analyzer') : require('./webpack.prod');
webpack(prodConfig, (err, stats) => {
if (err) {
console.error(err.stack || err);
if (err.details) {
console.error(err.details);
}
return;
}
const info = stats.toJson();
if (stats.hasErrors()) {
console.error(info.errors);
}
if (stats.hasWarnings()) {
console.warn(info.warnings);
}
console.info(stats.toString({ colors: true }));
});
};
if (env === 'development') {
serve();
} else if (env === 'production') {
build();
}
自定义setting.json
{
"title": "测试",
"styles": [],
"scripts": ["https://res.wx.qq.com/open/js/jweixin-1.3.2.js"]
}
到这里就可以启动项目了
yarn start 页面名(home) ,启动某一个页面
yarn start,启动所有页面
9.打包环境配置
const baseConfig = require('./webpack.base.js');
const path = require('path');
const { merge } = require('webpack-merge')
module.exports = merge(baseConfig, {
mode: 'production', // 生产模式,会开启tree-shaking和压缩代码,以及其他优化
devtool: false,
});
package.json添加build打包命令脚本
"scripts": {
"start": "cross-env NODE_ENV=development RUNTIME_ENV=development node config/bin.js",
"build": "cross-env NODE_ENV=production RUNTIME_ENV=production node config/bin.js",
"build:analyzer": "cross-env NODE_ENV=production RUNTIME_ENV=analyzer node config/bin.js",
"build:production": "cross-env NODE_ENV=production npm run build",
"test": "echo \"Error: no test specified\" && exit 1"
},
10.处理css和less文件
因为webpack只能识别js模块,所以要添加css-loader
yarn add css-loader style-loader less less-loader -D
- style-loader: 把解析后的css代码从js中抽离,放到头部的style标签中
- css-loader: 解析css文件代码
- less-loader: 解析less文件代码,把less编译为css
- less: less核心
module.exports = {
//...
module: {
rules: [
//..
{
test: /.(css|less)$/, //匹配 css和less 文件
use: ['style-loader','css-loader', 'less-loader'] // 从右到左,从下到上的原则
}
]
}
}
启动之后
三、基础功能配置
1.处理css3前缀兼容
yarn add postcss-loader autoprefixer -D
- postcss-loader:处理css时自动加前缀
- autoprefixer:决定添加哪些浏览器前缀到css中
修改webpack.base.js, 在解析css和less的规则中添加配置 可以把postcss-loader提取出来,根目录新建postcss.config.js
module.exports = {
plugins: ['autoprefixer']
}
2.使用css Module方式,避免css样式冲突
直接使用css
使用css Module,修改文件名index.module.less即可开启
也可以自己定义css名称,修改css-loader
use: [
'style-loader',
{
loader: 'css-loader',
options: {
modules: {
localIdentName: '[local]_[hash:base64:8]'
}
}
},
'postcss-loader',
'less-loader'] // 从右到左,从下到上的原则
3.添加postcss-loader
修改webpack.base.js, 添加postcss-loader
use: ['style-loader','css-loader', 'postcss-loader','less-loader'] // 从右到左,从下到上的原则
在根目录创建 .browserslistrc文件,让postcss-loader知道要加哪些浏览器的前缀
> 0.01%
last 2 version
not dead
4.优化babel-loader,添加插件
在根目录下创建babel.config.js
安装@babel/plugin-transform-optional-chaining,@babel/plugin-transform-nullish-coalescing-operator方便开发
yarn add @babel/plugin-transform-nullish-coalescing-operator @babel/plugin-transform-optional-chaining -D
const isDEV = process.env.NODE_ENV === "development";
module.exports = {
presets: [
[
"@babel/preset-env", // babel 编译的预设,可以转换目前最新的js标准语法
{
useBuiltIns: "usage", // 根据配置的浏览器兼容,以及代码中使用到的api进行引入polyfill按需添加
corejs: 3, // 配置使用core-js低版本
modules: false // 是否将 ESM 转化为其他模块化标准将此设置为 false 将保留 ESM 不受转换
}
],
"@babel/preset-react"
],
plugins: [
"@babel/plugin-transform-optional-chaining", // 可选链 ?.
"@babel/plugin-transform-nullish-coalescing-operator", // 双问号操作符
]
};
修改webpack.base.js
module: {
rules: [
{
test: /\.jsx?$|tsx?$/, // 匹配.js, jsx文件
use: ["babel-loader"],
exclude: /node_modules/
},
]
}
4.处理图片资源
module.exports = {
// ...
module: {
rules: [
//...
{
test:/.(png|jpg|jpeg|gif|svg)$/, // 匹配图片文件
type: "asset", // type选择asset
parser: {
dataUrlCondition: {
maxSize: 10 * 1024, // 小于10kb转base64位
}
},
generator: {
filename: obj=>{
return `${obj.runtime}/static/images/[name][ext]`, // 文件输出目录和命名
}
},
},
]
}
}
四、 优化构建速度
1.添加分析打包插件
yarn add speed-measure-webpack-plugin webpack-bundle-analyzer -D
创建webpack.analyzer.js
const prodConfig = require('./webpack.prod.js');
const { merge } = require('webpack-merge')
const SpeedMeasurePlugin = require('speed-measure-webpack-plugin'); // 引入webpack打包速度分析插件
const smp = new SpeedMeasurePlugin(); // 实例化分析插件
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer') // 引入分析打包结果插件
module.exports = smp.wrap(merge(prodConfig, {
plugins: [
new BundleAnalyzerPlugin() // 配置分析打包结果插件
]
}));
执行yarn build:analyzer home
2.开启持久化存储缓存
module.exports = {
//...
cache: {
type: 'filesystem', // 使用文件缓存
},
}
未开启
开启后
3.使用swc-loader代替bable-loader
yarn add @swc/core @swc/helpers swc-loader -D
// {
// test: /\.jsx?$|tsx?$/, // 匹配.js, jsx文件
// use:['babel-loader'],
// exclude: /node_modules/
// },
{
test: /\.jsx?$|tsx?$/,
exclude: /node_modules/,
use: {
loader: "swc-loader",
},
},
根目录新增.swcrc文件
{
"jsc": {
"parser": {
"syntax": "ecmascript", // "ecmascript" | "typescript"
"decorators": false, // 装饰器 等同于 @babel/plugin-syntax-decorators
"dynamicImport": true, // 动态加载 等同于 @babel/plugin-syntax-dynamic-import
"jsx": true // 是否解析jsx,对应插件 @babel/plugin-transform-react-jsx
},
"transform": {
"legacyDecorator": true,
"decoratorMetadata": true
},
"externalHelpers": true, // 输出代码可能依赖于辅助函数来支持目标环境。
"target": "es5",
"keepClassNames": true,
"loose": true // 等同babel-preset-env的松散配置
},
"minify": false // 压缩代码
}
使用swc-loader
使用bable-loader
4.添加extensions
extensions是webpack的resolve解析配置下的选项,在引入模块时不带文件后缀时,会来该配置数组里面依次添加后缀查找文件
resolve: {
extensions: ['.js', '.jsx', '.json'],
},
5.缩小loader作用范围
- include:只解析该选项配置的模块
- exclude:不解该选项配置的模块,优先级更高
module: {
rules: [
{
test: /\.jsx?$|tsx?$/, // 匹配.js, jsx文件
use:['babel-loader'],
exclude: /node_modules/
}]
}
6.精确使用loader
{
test: /.(css|less)$/, //匹配 css和less 文件
include: [path.resolve(process.cwd(), 'src')],
use: [
'style-loader',
{
loader: 'css-loader',
options: {
modules: {
localIdentName: '[local]_[hash:base64:8]'
}
}
},
'postcss-loader',
'less-loader'] // 从右到左,从下到上的原则
}
7.其他优化
1.devtool 配置开发环境 devtool: 'inline-source-map',生产环境 devtool: 'none'
2.module.noParse,可以用于配置哪些模块文件的内容不需要进行解析,以提高整体的构建速度,用 noParse 进行忽略的模块文件中不能使用 import、require、define 等导入机制,有不少 npm 包默认提供了提前打包好,不需要做二次编译的资源版本,如Vue 包的 node_modules/vue/dist/vue.runtime.esm.js 文件,React 包的 node_modules/react/umd/react.production.min.js 文件,noParse: /vue|lodash|react/
3.externals 想引用一个库,但是又不想让webpack打包,并且又不影响我们在程序中以CMD、AMD或者window/global全局等方式进行使用,那就可以通过配置externals
4.IgnorePlugin用于忽略某些特定的模块,让webpack不把这些指定的模块打包进去。new webpack.IgnorePlugin(/^./locale/,/moment/, /moment/,/moment/)
五、打包构建之后优化
1.抽取css样式文件
开发环境时css写在style标签里,方便热替换,但是生产环境要单独提取出来,更好的利用缓存策略。
yarn add mini-css-extract-plugin -D
修改webpack.base.js, 根据环境变量设置开发环境使用style-looader,生产环境模式抽离css
{
test: /.(css|less)$/, //匹配 css和less 文件
include: [path.resolve(process.cwd(), 'src')],
use: [
isProd ? MiniCssExtractPlugin.loader : 'style-loader',
{
loader: 'css-loader',
options: {
modules: {
localIdentName: '[local]_[hash:base64:8]'
}
}
},
'postcss-loader',
'less-loader'] // 从右到左,从下到上的原则
}
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = merge(baseConfig, {
//...
plugins: [
new MiniCssExtractPlugin({
filename: '[name]/static/[contenthash:8].css' // 抽离css的输出目录和名称
}),
]
});
2.压缩css,js
yarn add css-minimizer-webpack-plugin -D
const baseConfig = require('./webpack.base.js');
const { merge } = require('webpack-merge');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
module.exports = merge(baseConfig, {
mode: 'production', // 生产模式,会开启tree-shaking和压缩代码
devtool: false,
plugins: [
],
optimization: {
minimizer: [
new CssMinimizerPlugin(), // 压缩css
],
},
});
压缩js文件
yarn add terser-webpack-plugin -D
const TerserPlugin = require('terser-webpack-plugin');
module.exports = merge(baseConfig, {
//...
optimization: {
minimizer: [
new CssMinimizerPlugin(), // 压缩css
new TerserPlugin({ // 压缩js
parallel: true, // 开启多线程压缩
terserOptions: {
compress: {
drop_console: true, // 删除所有console
}
}
}),
],
},
});
3.打包时生成gzip文件
现在大部分浏览器和服务器都支持gzip,可以有效减少静态资源文件大小,压缩率在 70% 左右。nginx可以配置gzip: on来开启压缩,但是只在nginx层面开启,会在每次请求资源时都对资源进行压缩,压缩文件会需要时间和占用服务器cpu资源,更好的方式是前端在打包的时候直接生成gzip资源,服务器接收到请求,可以直接把对应压缩好的gzip文件返回给浏览器,节省时间和cpu。
//...
const CompressionPlugin = require('compression-webpack-plugin');
module.exports = merge(baseConfig, {
//...
plugins: [
//...
new CompressionPlugin({
test: /.(js|css)$/, // 只生成css,js压缩文件
filename: '[path][base].gz', // 文件命名
algorithm: 'gzip', // 压缩格式,默认是gzip
test: /.(js|css)$/, // 只生成css,js压缩文件
threshold: 10240, // 只有大小大于该值的资源会被处理。默认值是 10k
minRatio: 0.8 // 压缩率,默认值是 0.8
})
],
}
六、统一规范
使用工具 eslint,prettier,,husky,Lint-staged
1.安装vscode插件EditorConfig
因为每个人的vsocde编辑器默认配置可能不一样,所以需要在项目中为编辑器配置下格式,保证每个人的配置都是一样的,打开vsocde插件商店,搜索EditorConfig for VS Code,然后进行安装。在根目录新增 .editorconfig配置文件:
root = true # 控制配置文件 .editorconfig 是否生效的字段
[**] # 匹配全部文件
indent_style = tab # 缩进风格,可选space|tab
indent_size = 2 # 缩进的空格数
charset = utf-8 # 设置字符集
trim_trailing_whitespace = true # 删除一行中的前后空格
insert_final_newline = true # 设为true表示使文件以一个空白行结尾
end_of_line = lf
[**.md] # 匹配md文件
trim_trailing_whitespace = false
2.安装eslint插件,用来规范或者约束代码
在vscode市场搜索并安装
安装依赖
yarn add eslint -D
执行npm init @esling/config,会在根目录下自动生成.eslintrc.js
完了之后看js代码eslint检测出的问题
3.安装lint-staged
yarn add lint-staged -D
当我们运行ESlint或Stylelint命令时,可以通过设置指定只检查我们通过git add添加到暂存区的文件,可以避免我们每次检查都把整个项目的代码都检查一遍,从而提高效率。
"scripts": {
//...
"lint-staged": "lint-staged",
"lint-staged:js": "eslint --ext .js,.jsx,.ts,.tsx ",
},
"lint-staged": {
"**/*.{js,jsx,ts,tsx}": "npm run lint-staged:js",
},
4.安装husky
是常见的git hook工具,使用husky可以挂载Git钩子,当我们本地进行git commit或git push等操作前,能够执行其它一些操作,比如进行ESLint检查,如果不通过,就不允许commit或push。git hook钩子pre-commit和commit-msg,post-commit,使用hook钩子可以在提交等重要操作指令执行对应的操作,如git commit 会触发pre-commit如果没通过就会禁止提交,可以使用git commit --no-verify跳过检查
yarn add husky -D
执行npx husky-init && npm install
这条命令做了四件事
- 安装了husky,
npm install husky -D
- 在
package.json
的添加了命令"prepare": "husky install"
- 项目根目录下创建了
.husky
文件夹,pre-commit
文件里默认执行的命令是npm test
- 配置了git钩子的路径
prepare": "husky install
命令的含义:当我们执行npm install
安装完项目依赖后会执行husky install
命令创建.husky
目录
yarn不支持prepare,但是提供了postinstall替换prepare
修改.husky/pre-commit
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
npm run lint-staged
修改package.josn,添加postinstall
"scripts": {
"prepare": "husky install",
"postinstall": "husky install"
},
然后提交代码测试
修复完之后提交成功
5.安装prettier
yarn add eslint-plugin-prettier eslint-config-prettier eslint-plugin-react prettier -D
vscode搜索并安装
根目录新建.prettierrc.js
module.exports = {
printWidth: 100, // 一行的字符数,如果超过会进行换行
tabWidth: 2, // 一个tab代表几个空格数,默认就是2
useTabs: false, // 是否启用tab取代空格符缩进,.editorconfig设置空格缩进,所以设置为false
semi: true, // 行尾是否使用分号,默认为true
singleQuote: false, // 字符串是否使用单引号
trailingComma: "none", // 对象或数组末尾是否添加逗号 none| es5| all
jsxSingleQuote: false, // 在jsx里是否使用单引号
bracketSpacing: true, // 对象大括号直接是否有空格,默认为true,效果:{ foo: bar }
arrowParens: "avoid" // 箭头函数如果只有一个参数则省略括号
};
根目录新建.vscode/settings.json
{
"search.exclude": {
"/node_modules": true,
"dist": true,
"pnpm-lock.sh": true
},
"editor.formatOnSave": true, // 开启保存文件自动格式化代码
"prettier.requireConfig": true, // 需要Prettier的配置文件,它会覆盖Prettier扩展中的默认配置
"eslint.enable": true, // 开启eslint检查
"editor.codeActionsOnSave": { // eslint保存时检测
"source.fixAll": false,
"source.fixAll.eslint": true
},
"[javascript]": { // 为指定语音设置默认格式化器:
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[javascriptreact]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[typescript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[typescriptreact]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[json]": {
"editor.defaultFormatter": "vscode.json-language-features"
},
"[html]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[markdown]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[css]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[less]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[scss]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"liveServer.settings.port": 5502
}
根目录下新建.eslintignore
config/*
dist/*
.DS_Store
public/*
Prettier`插件获取配置文件有一个优先级:.prettierrc > .editorconfig > vscode默认配置。
eslint-plugin-prettier eslint-config-prettier eslint,prettier都可以进行代码格式化方面,若二者同时出现下面的情况就会出现冲突,它们用来解决eslint和prettier的冲突
eslint-plugin-react 处理jsx语法
修改.eslintrc.js
module.exports = {
env: {
browser: true,
es2021: true,
node: true
},
extends: ["eslint:recommended", "plugin:react/recommended", "plugin:prettier/recommended"],
overrides: [
{
env: {
node: true
},
files: [".eslintrc.{js,cjs}"],
parserOptions: {
sourceType: "script"
}
}
],
parserOptions: {
ecmaVersion: "latest",
sourceType: "module"
},
plugins: ["react"],
rules: {
quotes: 2,
semi: 1, // 无分号就警告
"no-console": 0, // 有console.log就警告
"space-before-function-paren": 0 // 函数前空格忽略
}
};
然后关闭vscode并重启才会生效。
结语
至此就结束了,不够完善还多包涵。谢谢
遗留问题:热更新配置完了,无法保存状态,不知道为什么,希望看到的大神指点一下,谢谢。
转载自:https://juejin.cn/post/7281162206946869285