Project technology stack

  • Build tool: [email protected]
  • Programming language: TypeScript @4.4.4
  • Front-end framework: [email protected]
  • CSS precompilation: sASS
  • Request tool: Axios
  • Eslint +prettier+stylelint

Project structures,

Initialize the project

First create an empty folder and execute in that folder

npm init -y
Copy the code

Webpack dependency installation

npm i webpack webpack-cli webpack-merge webpack-dev-server -D
Copy the code

Vue dependent installation

npm i vue@next vue-router@next vuex@next
Copy the code

The versions completed by the author are as follows:

  • Vue: “3.2.23”
  • Vue – the router: “4.0.12”
  • Vuex: “4.0.2”

TS dependent installation

npm i typescript -D
Copy the code

And create tsconfig. Json

{
  "compilerOptions": {
    "target": "es5".// Specify the compiled ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'
    "module": "esnext".// Specify the module standard to use: 'none', 'commonJS ',' AMD ', 'system', 'umD ',' ES2015 ', or 'ESNext'
    "strict": true.// Enable all strict type checking options.
    "jsx": "preserve".// Specify the development environment for JSX code: 'preserve', 'react-native', or 'react'
    "importHelpers": true.// Import helper functions from tslib (such as __extends, __rest, etc.)
    "moduleResolution": "node".// Select the module resolution strategy, there are two types 'node' and 'classic'.
    "experimentalDecorators": true.// List of module names to baseUrl pathmaps.
    "skipLibCheck": true.// Ignore type checking for all declaration files (*.d.ts).
    "esModuleInterop": true.// Support the use of import D from 'CJS' in CommonJs modules to address TypeScript processing of CommonJs/AMD/UMD modules in the same way as ES6 modules
    "allowSyntheticDefaultImports": true.// Allow default imports from modules that do not have default exports set. This does not affect the output of the code, just for type checking.
    "sourceMap": true.// Generate the corresponding.map file.
    "baseUrl": ".".// Resolve the base directory of non-relative module names. Relative modules are not affected by baseUrl
    "paths": {
      // Used to set the module name to baseUrl based path mapping
      "@ / *": ["src/*"]},"lib": ["esnext"."dom"."dom.iterable"."scripthost"] // lib is used to specify the library files to be included in the compilation
  },
  "include": [
    "src/**/*.ts"."src/**/*.tsx"."src/**/*.vue"."tests/**/*.ts"."tests/**/*.tsx"."types/**/*.d.ts"."types/*.d.ts"].// Specify a list of paths to compile, but the difference with files is that the paths can be folders or files, relative or absolute paths can be used, and wildcards can be used, such as "./ SRC "to compile all files in the SRC folder and files in subfolders
  "exclude": ["node_modules"] // exclude specifies the files to exclude and not compile. It also specifies a list. Like include, it can be a file or folder, a relative path or an absolute path
}
Copy the code

HTML integration depends on installation

npm i html-webpack-plugin -D
Copy the code

Create entry file

1. Create a public directory under this folder and create index.html under this directory

<! DOCTYPEhtml>
<html>
  <head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
    <meta name="viewport" content="Width = device - width, initial - scale = 1.0" />
    <link rel="shortcut icon" href="/favicon.ico" />
    <title>webpack5+ts+vue3</title>
    <meta
      name="description"
      content=Webpack5 + TS + VUE3 Construction Project
    />
    <meta
      name="keyword"
      content="vue3 kai"
    />
  </head>
  <body>
    <div id="app"></div>
  </body>
</html>
Copy the code

2. Create a SRC directory under the file

Create the app.vue file

<template>
  <router-view />
</template>

<script lang="ts">
import { defineComponent } from "vue";
export default defineComponent({
  name: "App",
});
</script>
Copy the code

And create the index.ts file

import { createApp } from 'vue'
import App from './App.vue'

const app = createApp(App)

app.mount('#app')
Copy the code

Create the WebPack configuration file

Create a build folder in the build folder, and create three files webpack.base.conf.js, webpack.dev.js, and webpack.prod.js in the build folder, write the basic configuration file, and gradually improve later

  • Webpack. Base. Conf. Js file

    const path = require("path");
    
    function resolve(dir) {
      return path.join(__dirname, "..", dir);
    }
    
    const HtmlWebpackPlugin = require("html-webpack-plugin");
    
    module.exports = {
      entry: {
        app: resolve("src/index.ts"),},resolve: {
        extensions: [".js".".vue".".json".".ts".".tsx".".mjs"].alias: {
          "@": resolve("src"),}},module: {
        rules: [{test: /\.vue$/,
            use: [
              {
                loader: "vue-loader"],},include: /(src)/,}]},plugins: [
        / / the vue - loader plug-in
        new vueLoader.VueLoaderPlugin(),
        new HtmlWebpackPlugin({
          filename: "index.html".template: resolve("public/index.html"),
          favicon: resolve("public/favicon.ico"),
          inject: true,})]};Copy the code
  • webpack.dev.js

    const { merge } = require("webpack-merge");
    const webpack = require("webpack");
    const common = require("./webpack.base.conf");
    const path = require("path");
    function resolve(dir) {
      return path.join(__dirname, "..", dir);
    }
    
    const devWebpackConfig = merge(common, {
      mode: "development".devtool: "eval-cheap-module-source-map".module: {
        rules: []},output: {
        path: resolve("dist"),
        filename: "js/[name].[hash].js".chunkFilename: "js/[name].[hash].js".publicPath: "/",},// Log printing only prints errors and warnings
      stats: "errors-warnings".devServer: {
        host: "0.0.0.0".historyApiFallback: {
          rewrites: [{from: /.*/g,
              to: "/index.html",}]},allowedHosts: "all".port: 8080./ / the port number
        open: false.// Automatically open
        hot: true./ / hot update
        client: {
          progress: true.// Outputs the running progress to the console.
          overlay: { warnings: false.errors: true }, // Display error messages in full screen
        },
        compress: true.// Enable gzip compression for all services
        proxy: {
          "/api": {
            target: "...".changeOrigin: true.// Whether the request is cross-domain
            pathRewrite: {
              "^/api": "",},},},},plugins: [
        new webpack.DefinePlugin({
          "process.env.NODE_ENV": "'development'".__VUE_OPTIONS_API__: true.__VUE_PROD_DEVTOOLS__: false,})]});module.exports = devWebpackConfig;
    Copy the code
  • webpack.prod.js

    const { merge } = require("webpack-merge");
    const webpack = require("webpack");
    const common = require("./webpack.base.conf");
    const path = require("path");
    function resolve(dir) {
      return path.join(__dirname, "..", dir);
    }
    module.exports = function (env, argv) {
      const nodeEnv = env.dev ? "development" : env.test ? "test" : "production";
      return merge(common, {
        mode: "production".devtool: "source-map".module: {
          rules: []},plugins: [
          new webpack.DefinePlugin({
            "process.env.NODE_ENV": JSON.stringify(nodeEnv),
            __VUE_OPTIONS_API__: true.__VUE_PROD_DEVTOOLS__: false,})],output: {
          path: resolve("dist"),
          filename: "js/[name].[hash].js".chunkFilename: "js/[name].[hash].js",}}); };Copy the code

Then modify the scripts configuration in the package.json file

  "scripts": {
	"dev": "webpack serve --config build/webpack.dev.js"."build:dev": "webpack --env dev --config build/webpack.prod.js"."build:test": "webpack --env test --config build/webpack.prod.js"."build:prod": "webpack --env prod --config build/webpack.prod.js"
  },
Copy the code

Style specific configuration

npm i css-loader sass-loader sass postcss postcss-loader postcss-preset-env vue-style-loader -D
Copy the code

Corresponding to webPack configuration

module: {
  rules: [{test: /\.(sa|sc|c)ss$/,
      use: [
        'vue-style-loader',
        {
          loader: 'css-loader'.options: {
            sourceMap: false,}}, {loader: 'postcss-loader'.options: {
            postcssOptions: {
              // postCSs-preset -env integrates autoprefixer to add CSS third-party prefixes
              plugins: ['postcss-preset-env'],},},}, {loader: 'sass-loader'.options: {
            additionalData: ` @use "@/styles/variables.scss" as *; // Import the sass variable @use "@/styles/mixin. SCSS "as *; // Global import sass mixed with ',},},],}Copy the code

File configuration, such as images and fonts

Webpack5 has a built-in asset module that can handle static resources instead of file-loader, url-loader, and raw-loader, much simpler than before

rules: [
  {
    test: /\.(png|jpe? g|gif|svg)(\? . *)? $/,
    type: 'asset'.parser: {
      dataUrlCondition: {
        maxSize: 10 * 1024,}},generator: {
      filename: 'images/[base]',},exclude: [resolve('src/assets/svg')]}, {test: /\.(woff2? |eot|ttf|otf)(\? . *)? $/,
    type: 'asset'.generator: {
      filename: 'files/[base]',}}, {test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\? . *)? $/,
    type: 'asset'.generator: {
      filename: 'media/[base]',}},],Copy the code

Babel configuration

npm i @babel/cli @babel/core @babel/plugin-transform-runtime @babel/preset-env @babel/preset-typescript babel-loader -D
Copy the code
npm i @babel/runtime-corejs3 core-js
Copy the code
  • @babel/cli: Babel comes with a built-in CLI command line tool, which can be compiled through the command line (such as NPX Babel script.js) file, debugging, can be installed or not installed

  • @babel/core: Bable core NPM package for transcoding

  • @ Babel/plugin – transform – runtime and @ Babel/runtime – corejs3:

    The js file is transcoded by Babel to generate many helper functions (possibly a lot of duplicate functions). Polyfill will mount the missing function of the target browser on the global variable. The plugin will import both helper and Polyfill from one unified place instead. And the introduced objects and global variables are completely isolated

    The @babel/plugin-transform-runtime package is used to translate code, which may import modules from @babel/runtime-corejs3, so the former runs at compile time and the latter at runtime.

  • @babel/preset-env: Preset kit, which contains every possible translation tool.

  • @babel/preset-typescript: Parses typescript’s Babel preset

  • Babel-loader: // Webpack loader, which relies on @babel/core, is an intermediate bridge that calls apis in Babel /core to tell Webpack what to do with JS

  • Core-js: The JavaScript standard library’s polyfill, @babel/preset-env reference package

let babelLoaderConf = {
  loader: 'babel-loader'.options: {
    presets: [['@babel/preset-env',
        {
          targets: {
            browsers: ['ie>=8'.'chrome>=62'].node: '8.9.0',},// Switch the target
          debug: false.// Whether to print which plug-ins prese-env uses for the current configuration and the collection of browsers we support
          useBuiltIns: 'usage'.// Import on demand
          corejs: '3.0'./ / corejs version},], ['@babel/preset-typescript',
        {
          allExtensions: true.All file extensions are supported, otherwise using ts in vue files will cause an error},]].plugins: [['@babel/plugin-transform-runtime',
        {
          corejs: 3,},],],},};// webpack
rules: [
	{
        test: /\.(ts|js)x? $/,
        use: [babelLoaderConf],
        exclude: /node_modules/],},Copy the code

Babel7 now has the ability to parse typescript, eliminating the need for TS-Loader

Vue file Webpack configuration

Since it is a vue3 project, vuE-Loader needs to install the latest version, and the version installed by the author is 16.8.3

npm i vue-loader@next @vue/compiler-sfc -D
Copy the code

Webpack configuration

const vueLoader = require('vue-loader')...module.exports = {
  ...
  module: {
    rules: [{test: /\.vue$/,
        use: [
          {
            loader: 'vue-loader'],},include: /(src)/,}]},plugins: [
    / / the vue - loader plug-in
    new vueLoader.VueLoaderPlugin(),
  ],
}

Copy the code

Add the corresponding vUE type declaration to prevent type errors

Create a new Types folder and add the shims-vue.d.ts file

declare module '*.vue' {
  import { DefineComponent } from 'vue'
  const component: DefineComponent<{}, {}, any>
  export default component
}
Copy the code

Code specification

Eslint + prettier + stylelint, plus.EditorConfig file

.editorconfig

The.editorConfig file can unify the specification for editing, such as indentation Spaces and so on

/ /. Editorconfig file
root = true[*. {js, JSX, ts, the TSX, vue, json, HTML, CSS, SCSS}] indent_style = space # indented style (TAB | space) indent_size =2# # the indentation size end_of_line = CRLF control line type (lf | cr | CRLF) insert_final_newline =trueAlways insert a new line at the end of the fileCopy the code

eslint

Used to check whether the code conforms to the code specification, code syntax logic, code format and so on

npm i -D eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin eslint-plugin-prettier eslint-config-prettier  eslint-plugin-vueCopy the code
  • Eslint: The core code for ESLint
  • @typescript-eslint/parser: A parser for ESLint that parses typescript to check and standardize typescript code
  • @typescript-eslint/eslint-plugin: This is an ESLint plugin that contains various specifications for checking typescript code
  • Eslint-plugin-prettier, eslint-config-prettier: EsLint is compatible with prettier
  • Eslint-plugin-vue: VUE rules are provided for vUE, including vue-eslint-parser, so there is no need to install vue-eslint-parser manually

. Eslintrc. Js file

module.exports = {
  root: true.env: {
    node: true.browser: true,},parserOptions: {
    parser: "@typescript-eslint/parser".// Parse the script tag in the.vue file
    sourceType: "module".ecmaVersion: 12,},plugins: ["vue"."@typescript-eslint"].extends: [
    "plugin:vue/recommended"."plugin:prettier/recommended"."prettier/@typescript-eslint"."plugin:@typescript-eslint/recommended",].rules: {
    indent: ["warn".2].// Indent style}};Copy the code

prettier

Beautify the code

npm i prettier -D
Copy the code

. Prettierrc. Js file

module.exports = {
  singleQuote: true.// Use single quotes
  tabWidth: 2.// The length of the Tab indent
  endOfLine: 'auto'.// The form of a newline at the end of the file
  semi: false.// No semicolons
};
Copy the code

stylelint

npm i stylelint stylelint-config-prettier stylelint-config-recess-order stylelint-config-standard stylelint-order stylelint-scss -D
Copy the code

Add the stylelint.config.js file in the root directory

module.exports = {
  defaultSeverity: 'warn',
  extends: [
    'stylelint-config-standard',
    'stylelint-config-recess-order', // Attribute collation
  ],
  plugins: ['stylelint-scss', 'stylelint-order'],
  rules: {
    'no-invalid-double-slash-comments': null.// Allow double slash comments
    'custom-property-no-missing-var-function': null,
    'no-empty-source': null,
    'selector-class-pattern': null,
    'alpha-value-notation': null.// Allow decimals
    'color-function-notation': null.// RGB colors are allowed
    'media-feature-name-no-vendor-prefix': true.// Do not allow prefixes of media feature names, plug-ins add them automatically
    'selector-pseudo-element-no-unknown': [
      true,
      {
        ignorePseudoElements: ['deep'], // Ignore the deep pseudo-element
      },
    ],
    'at-rule-no-unknown': [
      true,
      {
        ignoreAtRules: [
          'mixin',
          'include',
          'if',
          'else',
          'extend',
          'for',
          '$',
          'forward',
          'use',
        ], // Ignore rules},],}},Copy the code

UI Framework introduction (Element-Plus)

The UI framework used in this project is Element-Plus, because the current framework is all in beta version. After many mistakes, the current version is 1.0-beta.24. Check the official document of the framework. Introduce the use of the unplugin-vue-Components plug-in as needed

NPM I [email protected] unplugin - vue - componentsCopy the code

According to the need to introduce

Configuration webpack

const Components = require('unplugin-vue-components/webpack')
const { ElementPlusResolver } = require('unplugin-vue-components/resolvers')...module.exports = {
  ...
  plugins: [...// Element-plus is introduced on demand
    Components({
      resolvers: [
        ElementPlusResolver({
          importStyle: false.// Do not introduce a style file for later themetization}),],}),],};Copy the code

The loader for MJS in webPack configuration is also required

Changed fullySpecified to false so that the element-Plus Module can be imported without an extension to avoid Module Not found errors and compile failures

module.exports = {
  module: {
    rules: [
      // element-plus
      {
        test: /\.mjs$/,
        include: /node_modules/,
        resolve: {
          fullySpecified: false,},type: 'javascript/auto',},],},}Copy the code

Add import TS files on demand

// element-plus.ts
import type { App } from 'vue'

import {
  ElButton,
  ElSelect,
  ...
} from 'element-plus'

const components = [
  ElButton,
  ElSelect,
  ...
]

const option = {
  size: 'medium',}export default function introduceElement(app: App) :void {
  components.forEach((component) = > {
    app.use(component)
  })
  app.config.globalProperties.$ELEMENT = option
}
Copy the code

And import the file into the entry file

// index.ts

import introduceElement from '@/utils/vue/element-plus'
const app = createApp(App)
// Introduce element UI components on demand
introduceElement(app)
Copy the code

themed

Create a new theme. SCSS file

@forward "element-plus/theme-chalk/src/common/var.scss" with (
  $colors: (
    "primary": (
      "base": #016EFD,),"success": (
      "base": #016EFD,),"warning": (
      "base": #faad14,),"danger": (
      "base": #f56c6c,),"error": (
      "base": #f56c6c,),"info": (
      "base": #0076ff,),),$font-path : '~element-plus/dist/fonts' ,
  $button-padding-horizontal: (
    "default": 80px));Copy the code

Create a new elementPlus.scss file

@use './theme.scss' as *;
@use 'element-plus/theme-chalk/src/index.scss' as *;
Copy the code

And imported in the entry file index.ts

import './styles/elementPlus.scss'
Copy the code

At this point, theming was complete, and several versions of Element-Plus were tried before theming worked without error

Project optimization

Package volume analysis

Optimize by analyzing the size of each bundle.

npm i -D webpack-bundle-analyzer
Copy the code

We can do this by adding scripts to package.json

"build:analyzer": "webpack --env analyzer --config build/webpack.prod.js"
Copy the code

Webpack configuration file

function resolve(dir) {
  return path.join(__dirname, "..", dir);
};

const BundleAnalyzerPlugin = require("webpack-bundle-analyzer").BundleAnalyzerPlugin; .module.exports = function (env, argv) {
  const analyzerPlugins = env.analyzer
    ? [
        new BundleAnalyzerPlugin({
          analyzerMode: "static".openAnalyzer: false.// generateStatsFile: true,
          reportFilename: resolve("./report/report.html"),
          statsFilename: resolve("./report/stats.json"}),] : [];return merge(common, {
    mode: "production".plugins: [
      
      ...
        
      ...analyzerPlugins,
    ],
  });
};

Copy the code

The final package size results are printed to the report folder in the root directory

Added compilation progress bar to optimize compilation prompt

npm i -D progress-bar-webpack-plugin friendly-errors-webpack-plugin 
Copy the code
  • Progress-bar-webpack-plugin: progress bar plugin
  • Friendly-errors-webpack-plugin: optimizes the prompt plug-in
const { merge } = require('webpack-merge')
const webpack = require('webpack')
const { resolve } = require('./utils.js')
const FriendlyErrorsWebpackPlugin = require('friendly-errors-webpack-plugin')
const common = require('./webpack.base.conf')
const chalk = require('chalk')
const ProgressBarPlugin = require('progress-bar-webpack-plugin')

const devWebpackConfig = merge(common, {
  // Log printing only prints errors and warnings
  stats: 'errors-warnings'. }) devWebpackConfig.plugins.push(/ / the progress bar
  new ProgressBarPlugin({
    format: ` :msg [:bar] ${chalk.green.bold(':percent')} (:elapsed s)`.clear: true,}).// Error message
  new FriendlyErrorsWebpackPlugin({
    // Output on success
    compilationSuccessInfo: {
      messages: [
        `Your application is running here: http://${devWebpackConfig.devServer.host}:${devWebpackConfig.devServer.port}`,]},// Whether to empty the console every time
    clearConsole: true,}))module.exports = devWebpackConfig

Copy the code

Cache cache

Configure webPack persistent cache cache: Filesystem to cache webpack modules and chunks to improve the build speed.

Using cache: Filesystem can cache webPack templates for the build process to speed up the second build.

function resolve(dir) {
  return path.join(__dirname, "..", dir);
};

const devWebpackConfig = merge(common, {
  ...
  / / cache
  cache: {
    type: 'filesystem'.buildDependencies: {
      config: [__filename], // The array object that the extra code depends on for the build. Webpack will use the hash values of these items and all dependencies to invalidate the file system cache.
    },
    cacheDirectory: resolve('temp_cache'),
    name: 'scf-cache'./ / path temp_cache/SCF - cache
    compression: 'gzip',}})Copy the code

Clear the dist folder

npm i clean-webpack-plugin -D
Copy the code

This plug-in can clean up old files (the results of the last build) under DIST at package time to ensure that the build results in the Dist folder are up to date.

const { CleanWebpackPlugin } = require('clean-webpack-plugin')
module.exports = {
	plugins: [
   		/ / clear the dist
    	new CleanWebpackPlugin(),
	]
}
Copy the code

CSS separation

npm i mini-css-extract-plugin -D
Copy the code

The mini-CSS-extract-plugin can extract CSS into a separate file, create a CSS file for each JS file containing CSS, and support on-demand loading of CSS and SourceMaps.

Extracting CSS files for configuration also prevents large files packaged in JS and network requests timeouts because of large files.

const MiniCssExtractPlugin = require('mini-css-extract-plugin')

module.exports = function (env, argv) {
    module: {
      rules: [{test: /\.(sa|sc|c)ss$/,
          use: [
            {
              loader: MiniCssExtractPlugin.loader,
            },
            {
              loader: 'css-loader'}, {loader: 'postcss-loader'}, {loader: 'sass-loader',},],},},plugins: [
      / / CSS
      new MiniCssExtractPlugin({
        filename: 'css/[name].[contenthash].css'.chunkFilename: 'css/[name].[contenthash].css',}),],})}Copy the code

CSS compression

npm i css-minimizer-webpack-plugin -D
Copy the code

Css-minimizer-webpack-plugin can optimize and compress CSS files.

const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");

module.exports = {
  plugins: [
    new CssMinimizerPlugin(),
  ],
};
Copy the code

SVG Sprites figure

npm i svg-sprite-loader -D
Copy the code

Modify the WebPack configuration to configure Sprites diagrams for SVG images in the specified directory (SRC/Assets/SVG)

module.exports = {
  module: {
    rules: [{test: /\.svg$/,
        loader: 'svg-sprite-loader'.include: [resolve('src/assets/svg')].options: {
          symbolId: 'icon-[name]',}}, {test: /\.(png|jpe? g|gif|svg)(\? . *)? $/,
        type: 'asset'.parser: {
          dataUrlCondition: {
            maxSize: 10 * 1024,}},generator: {
          filename: 'images/[base]',},exclude: [resolve('src/assets/svg'],},],},}Copy the code

Plug-in SVG component

<template> <svg :class="svgClass" aria-hidden="true"> <use :xlink:href="iconName"></use> </svg> </template> <script> export default { name: 'SvgIcon', props: { iconClass: { type: String, required: true, }, className: { type: String, }, }, computed: { iconName() { return `#icon-${this.iconClass}` }, svgClass() { if (this.className) { return 'svg-icon ' + this.className } else { return 'svg-icon' } }, }, } </script> <style scoped> .svg-icon { width: 1em; height: 1em; Vertical - align: 0.15 em. fill: currentColor; overflow: hidden; } </style>Copy the code

Create ts file and import SVG uniformly

import type { App } from 'vue'
import SvgIcon from '@/components/common/svg/svg-icon.vue' / / SVG components

const requireAll = (requireContext: any) = >
  requireContext.keys().map(requireContext)
const req = require.context('@/assets/svg'.false./\.svg$/)
requireAll(req)

export default function svgIconRegistered(app: App) :void {
  app.component('SvgIcon', SvgIcon)
}
Copy the code

In the entry file index.ts

import { createApp } from 'vue'
import App from './App.vue'
import svgIconRegistered from '@/utils/vue/svg-component'
const app = createApp(App)
/ / SVG Sprites
svgIconRegistered(app)
Copy the code

For example, menu-icon is the file name of an SVG diagram

<svg-icon icon-class="menu-icon" class="menu-icon" />
Copy the code

Check and optimize before Git commit

Integrating HusKY and Lint-staged, Husky can help you block bad code commits and thrusters; Lint-staged files can be checked only once at a time.

npm i lint-staged husky -D
Copy the code

Run after installation

npx husky install
Copy the code

When you run it, you’ll notice that the project root directory generates a.husky folder. Create a new pre-commit file in that directory

// pre-commit file #! /bin/sh . "$(dirname "$0")/_/husky.sh" npx lint-stagedCopy the code

Then create a new lint-lanterns.config.js file in the root directory,

module.exports = {
  'src/**/*.{js,vue,png,svg,jpg,jepg,gif}': [
    (filenames) = >
      filenames.map(
        (filename) = > `prettier --write --ignore-unknown '${filename}'`),],}Copy the code

This will prettier the submission before it is submitted

The project address

Github.com/chenkai77/w…