likes
comments
collection
share

从0搭建webpack5+react18多页面模版

作者站长头像
站长
· 阅读数 58

一、初始化项目

在本地新创建一个文件夹w5-react-mpa-h5,在该文件夹内执行终端命令

npm init -y

从0搭建webpack5+react18多页面模版 初始化好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,启动所有页面

通过http://localhost:3001/home/index.html 查看

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
  • lessless核心
module.exports =  {
    //...
    module: {
       rules: [
           //..
           {
              test: /.(css|less)$/, //匹配 css和less 文件
              use: ['style-loader','css-loader', 'less-loader'] // 从右到左,从下到上的原则
            }
       ]   
    }
}

启动之后

从0搭建webpack5+react18多页面模版

三、基础功能配置

1.处理css3前缀兼容

yarn add postcss-loader autoprefixer -D

  • postcss-loader:处理css时自动加前缀
  • autoprefixer:决定添加哪些浏览器前缀到css

修改webpack.base.js, 在解析cssless的规则中添加配置 可以把postcss-loader提取出来,根目录新建postcss.config.js

module.exports = {
    plugins: ['autoprefixer']
}

2.使用css Module方式,避免css样式冲突

直接使用css

从0搭建webpack5+react18多页面模版

使用css Module,修改文件名index.module.less即可开启

从0搭建webpack5+react18多页面模版

从0搭建webpack5+react18多页面模版

也可以自己定义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

从0搭建webpack5+react18多页面模版

2.开启持久化存储缓存

module.exports =  {
    //...
    cache: {
        type: 'filesystem', // 使用文件缓存
    },
}

未开启

从0搭建webpack5+react18多页面模版

开启后

从0搭建webpack5+react18多页面模版

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

从0搭建webpack5+react18多页面模版

使用bable-loader

从0搭建webpack5+react18多页面模版

4.添加extensions

extensionswebpackresolve解析配置下的选项,在引入模块时不带文件后缀时,会来该配置数组里面依次添加后缀查找文件

   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市场搜索并安装 从0搭建webpack5+react18多页面模版 安装依赖yarn add eslint -D

执行npm init @esling/config,会在根目录下自动生成.eslintrc.js

从0搭建webpack5+react18多页面模版

完了之后看js代码eslint检测出的问题

从0搭建webpack5+react18多页面模版

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

从0搭建webpack5+react18多页面模版

执行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

从0搭建webpack5+react18多页面模版

#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

npm run lint-staged

修改package.josn,添加postinstall

"scripts": {
    "prepare": "husky install",
    "postinstall": "husky install"
 },

然后提交代码测试

从0搭建webpack5+react18多页面模版

修复完之后提交成功

从0搭建webpack5+react18多页面模版

5.安装prettier

yarn add eslint-plugin-prettier eslint-config-prettier eslint-plugin-react prettier -D

vscode搜索并安装

从0搭建webpack5+react18多页面模版

根目录新建.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并重启才会生效。

结语

至此就结束了,不够完善还多包涵。谢谢

遗留问题:热更新配置完了,无法保存状态,不知道为什么,希望看到的大神指点一下,谢谢。

源码地址:github.com/yjl122/webp…

转载自:https://juejin.cn/post/7281162206946869285
评论
请登录