欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Vite3遷移Webpack5的實(shí)現(xiàn)

 更新時(shí)間:2023年04月27日 09:24:29   作者:魷魚須不懂Vue  
本文主要介紹了Vite3遷移Webpack5的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

為什么要做遷移

現(xiàn)有問題

1、按需加載頁面的時(shí)候加載速度慢。

2、熱更新時(shí)常失效,手動(dòng)刷新加載速度也慢。

性能提升

1、舊框架啟動(dòng)約13秒,但啟動(dòng)后每個(gè)頁面切換加載都得等待5-10s,開發(fā)體驗(yàn)較差。新框架項(xiàng)目啟動(dòng)加所有頁面加載約65秒。利用webpack5緩存的新特性,啟動(dòng)速度變快的同時(shí),帶來更好的開發(fā)體驗(yàn)。

2、舊框架在jenkins打包需要2分52秒,新框架打包僅需1分48秒,速度提升了37%。

webpack5為什么快

webpack5 較于 webpack4,新增了持久化緩存、改進(jìn)緩存算法等優(yōu)化,通過配置webpack 持久化緩存,來緩存生成的 webpack 模塊和 chunk,改善下一次打包的構(gòu)建速度,可提速 90% 左右

安裝依賴

    "vue": "^3.2.37",
    "webpack": "5.64.4",
    "webpack-bundle-analyzer": "4.5.0",
    "webpack-cli": "4.10.0",
    "webpack-dev-server": "4.6.0",
    "webpack-merge": "5.8.0"
    "babel-loader": "8.2.3",
    "@babel/plugin-transform-runtime": "7.16.4",
    "clean-webpack-plugin": "4.0.0",
    "css-loader": "6.5.1",
    "css-minimizer-webpack-plugin": "3.2.0",// 對(duì)CSS文件進(jìn)行壓縮
    "mini-css-extract-plugin": "2.4.5",// 將CSS文件抽取出來配置, 防止將樣式打包在 js 中文件過大和因?yàn)槲募缶W(wǎng)絡(luò)請(qǐng)求超時(shí)的情況。
    "postcss-loader": "6.2.1",
    "postcss-preset-env": "7.0.1",
    "vue-style-loader": "4.1.3",
    "style-loader": "^3.3.2",
    "less-loader": "^11.1.0",
    "friendly-errors-webpack-plugin": "1.7.0",
    "html-webpack-plugin": "5.5.0",
    "progress-bar-webpack-plugin": "2.1.0",
    "vue-loader": "^17.0.1",    
    "eslint-webpack-plugin": "^4.0.0",
    "stylelint-webpack-plugin": "^4.1.0",
    "copy-webpack-plugin": "^11.0.0",
    "cross-env": "^7.0.3",
    "@babel/runtime-corejs3": "7.16.3"http:// 安裝到dependencies

webpack5配置

為了區(qū)分開發(fā)環(huán)境和打包環(huán)境,分了3個(gè)js文件(base、dev、prod),通過webpack-merge這個(gè)插件,進(jìn)行合并操作。

webpack.base.conf.js

const { resolve, babelLoaderConf } = require('./utils.js')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const { VueLoaderPlugin } = require('vue-loader/dist/index')
// const StylelintPlugin = require('stylelint-webpack-plugin')
const ESLintPlugin = require('eslint-webpack-plugin')
const { YouibotPlusResolver } = require('youibot-plus')
const MiniCssExtractPlugin = require('mini-css-extract-plugin') // 將CSS文件抽取出來配置, 防止將樣式打包在 js 中文件過大和因?yàn)槲募缶W(wǎng)絡(luò)請(qǐng)求超時(shí)的情況。
const { AntDesignVueResolver } = require('unplugin-vue-components/resolvers')
const isDev = process.env.NODE_ENV === 'development' // 是否是開發(fā)模式
module.exports = {
  entry: {
    app: resolve('src/main.ts')
  },
  resolve: {
    //引入模塊時(shí)不帶擴(kuò)展名,會(huì)按照配置的數(shù)組從左到右的順序去嘗試解析模塊
    extensions: ['.ts', '.tsx', '.js', '.vue', '.json'],
    alias: {
      '@': resolve('src')
    }
  },
  module: {
    noParse: /^(vue|vue-router|youibot-plus|echarts)$/, // 不解析庫
    rules: [
      {
        test: /\.vue$/,
        use: [
          {
            loader: 'vue-loader'
          }
        ],
        include: /(src)/
      },
      //babel7之后已經(jīng)有了解析 typescript 的能力,也就不再需要 ts-loader
      {
        test: /\.(ts|js)x?$/,
        use: [
          {
            loader: 'thread-loader', // 開啟多進(jìn)程打包
            options: {
              worker: 3
            }
          },
          babelLoaderConf
        ],
        exclude: /node_modules/
      },
      {
        test: /\.css$/,
        use: [
          // 開發(fā)環(huán)境使用style-looader(通過動(dòng)態(tài)添加 style 標(biāo)簽的方式,將樣式引入頁面),打包模式抽離css
          isDev ? 'vue-style-loader' : MiniCssExtractPlugin.loader,
          {
            loader: 'css-loader',
            options: {
              sourceMap: false
            }
          }
        ]
      },
      {
        test: /\.less$/,
        use: [
          isDev ? 'vue-style-loader' : MiniCssExtractPlugin.loader,
          {
            loader: 'css-loader',
            options: {
              sourceMap: false
            }
          },
          {
            loader: 'postcss-loader',
            options: {
              postcssOptions: {
                // postcss-preset-env 內(nèi)部集成了 autoprefixer 添加css第三方前綴
                plugins: ['postcss-preset-env']
              }
            }
          },
          {
            loader: 'less-loader',
            options: {
              lessOptions: {
                javascriptEnabled: true
              },
              additionalData: '@import "@/styles/variables.less";'
            }
          }
        ]
      },
      {
        test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
        type: 'asset',
        parser: {
          dataUrlCondition: {
            // 文件小于 10k 會(huì)轉(zhuǎn)換為 base64,大于則拷貝文件
            maxSize: 10 * 1024
          }
        },
        generator: {
          filename: 'images/[base]'
        }
      },
      {
        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]'
        }
      }
    ]
  },
  plugins: [
    new VueLoaderPlugin(),
    //將打包后的文件自動(dòng)引入到index.html里面
    new HtmlWebpackPlugin({
      template: resolve('public/index.html'),
      favicon: resolve('public/logo.ico')
    }),
    require('unplugin-vue-components/webpack')({
      resolvers: [
        AntDesignVueResolver({
          importStyle: false
        }),
        YouibotPlusResolver()
      ],
      dts: true,
      dirs: ['src/components', 'src/pages'] // 按需加載的文件夾
    }),
    require('unplugin-auto-import/webpack')({
      imports: ['vue', 'vue-router', 'pinia'],
      resolvers: [AntDesignVueResolver()],
      eslintrc: {
        enabled: true,
        filepath: '../.eslintrc-auto-import.json',
        globalsPropValue: true
      },
      dts: 'src/types/auto-imports.d.ts'
    }),
    // new StylelintPlugin(),
    new ESLintPlugin()
  ]
}

webpack.dev.js

const { merge } = require('webpack-merge')
const webpack = require('webpack')
const { getNetworkIp, 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, {
  mode: 'development',
  devtool: 'eval-cheap-module-source-map',
  output: {
    path: resolve('dist'),
    filename: 'js/[name].[hash].js',
    chunkFilename: 'js/[name].[hash].js',
    publicPath: '/'
  },
  // 日志打印只打印錯(cuò)誤和警告
  stats: 'errors-warnings',
  devServer: {
    host: getNetworkIp(),
    port: 8094, // 端口號(hào)
    open: true, // 自動(dòng)打開
    hot: true, // 熱更新
    allowedHosts: 'all',
    client: {
      progress: false, // 將運(yùn)行進(jìn)度輸出到控制臺(tái)。
      overlay: { warnings: false, errors: true } // 全屏顯示錯(cuò)誤信息
    }
  },
  plugins: [
    new webpack.DefinePlugin({
      'process.env.NODE_ENV': JSON.stringify('development'),
      __VUE_OPTIONS_API__: true, //控制臺(tái)警告處理
      __VUE_PROD_DEVTOOLS__: true //控制臺(tái)警告處理
    })
  ],
  // 緩存
  cache: {
    type: 'filesystem',
    buildDependencies: {
      config: [__filename] // 針對(duì)構(gòu)建的額外代碼依賴的數(shù)組對(duì)象。webpack 將使用這些項(xiàng)和所有依賴項(xiàng)的哈希值來使文件系統(tǒng)緩存失效。
    },
    cacheDirectory: resolve('temp_cache'),
    name: 'scf-cache', // 路徑temp_cache/scf-cache
    compression: 'gzip'
  }
})
devWebpackConfig.plugins.push(
  // 進(jìn)度條
  new ProgressBarPlugin({
    format: `  :msg [:bar] ${chalk.green.bold(':percent')} (:elapsed s)`,
    clear: true
  }),
  // 錯(cuò)誤提示
  new FriendlyErrorsWebpackPlugin({
    // 成功的時(shí)候輸出
    compilationSuccessInfo: {
      messages: [`Your application is running here: http://${devWebpackConfig.devServer.host}:${devWebpackConfig.devServer.port}`]
    },
    // 是否每次都清空控制臺(tái)
    clearConsole: true
  })
)
module.exports = devWebpackConfig

webpack.prod.js

const path = require('path')
const { merge } = require('webpack-merge')
const webpack = require('webpack')
const { resolve } = require('./utils.js')
const MiniCssExtractPlugin = require('mini-css-extract-plugin') // 將CSS文件抽取出來配置, 防止將樣式打包在 js 中文件過大和因?yàn)槲募缶W(wǎng)絡(luò)請(qǐng)求超時(shí)的情況。
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin') // 對(duì)CSS文件進(jìn)行壓縮
const TerserPlugin = require('terser-webpack-plugin')
const common = require('./webpack.base.conf')
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
const CopyPlugin = require('copy-webpack-plugin')
module.exports = () => {
  const analyzerPlugins = process.env.NODE_ENV === 'analyzer' ? [new BundleAnalyzerPlugin()] : []
  return merge(common, {
    mode: 'production',
    optimization: {
      // chunk拆分,提升首屏加載速度
      splitChunks: {
        cacheGroups: {
          vendors: {
            // 提取node_modules代碼
            test: /node_modules/, // 只匹配node_modules里面的模塊
            name: 'vendors', // 提取文件命名為vendors,js后綴和chunkhash會(huì)自動(dòng)加
            minChunks: 1, // 只要使用一次就提取出來
            chunks: 'initial', // 只提取初始化就能獲取到的模塊,不管異步的
            minSize: 0, // 提取代碼體積大于0就提取出來
            priority: 1 // 提取優(yōu)先級(jí)為1
          },
          commons: {
            // 提取頁面公共代碼
            name: 'commons', // 提取文件命名為commons
            minChunks: 2, // 只要使用兩次就提取出來
            chunks: 'initial', // 只提取初始化就能獲取到的模塊,不管異步的
            minSize: 0 // 提取代碼體積大于0就提取出來
          }
        }
      },
      // 壓縮
      minimize: true,
      minimizer: [
        new TerserPlugin({
          parallel: true, // 開啟多線程壓縮
          terserOptions: {
            compress: {
              pure_funcs: ['console.log'] // 刪除console.log
            }
          }
        }),
        new CssMinimizerPlugin()
      ],
      // tree shaking
      usedExports: true
    },
    performance: {
      hints: false
    },
    // devtool: 'source-map', //如果配置source-map的話,生產(chǎn)環(huán)境下也可以定位到具體代碼,但是相應(yīng)的打包文件也會(huì)變大(map文件體積,4m變成17m),而且會(huì)有代碼暴露的風(fēng)險(xiǎn)。
    plugins: [
      // 清空dist
      new CleanWebpackPlugin(),
      new CopyPlugin({
        patterns: [
          {
            from: path.resolve(__dirname, '../public'), // 復(fù)制public下文件
            to: path.resolve(__dirname, '../dist'), // 復(fù)制到dist目錄中
            filter: source => !source.includes('index.html') // 忽略index.html
          }
        ]
      }),
      // css抽離
      new MiniCssExtractPlugin({
        filename: 'css/[name].[contenthash].css',
        chunkFilename: 'css/[name].[contenthash].css'
      }),
      // css壓縮
      new CssMinimizerPlugin(),
      new webpack.DefinePlugin({
        //在業(yè)務(wù)代碼中也可以訪問process變量區(qū)分環(huán)境
        'process.env.NODE_ENV': JSON.stringify('production'),
        __VUE_OPTIONS_API__: true, //控制臺(tái)警告處理
        __VUE_PROD_DEVTOOLS__: false //控制臺(tái)警告處理
      }),
      ...analyzerPlugins
    ],
    output: {
      path: resolve('dist'),
      filename: 'js/[name].[hash].js',
      chunkFilename: 'js/[name].[hash].js'
    }
  })
}

utils.js

const path = require('path')
const os = require('os')
exports.getNetworkIp = function () {
  let needHost = '' // 打開的host
  try {
    // 獲得網(wǎng)絡(luò)接口列表
    let network = os.networkInterfaces()
    for (let dev in network) {
      let iface = network[dev]
      for (let i = 0; i < iface.length; i++) {
        let alias = iface[i]
        if (alias.family === 'IPv4' && alias.address !== '127.0.0.1' && !alias.internal) {
          needHost = alias.address
        }
      }
    }
  } catch (e) {
    needHost = 'localhost'
  }
  return needHost
}
exports.resolve = function (dir) {
  return path.join(__dirname, '..', dir)
}
// babel-loader配置
exports.babelLoaderConf = {
  loader: 'babel-loader',
  options: {
    presets: [
      [
        '@babel/preset-env',
        {
          targets: {
            browsers: ['ie>=8', 'chrome>=62'],
            node: '8.9.0'
          },
          debug: false,
          useBuiltIns: 'usage',
          corejs: '3.0'
        }
      ],
      [
        '@babel/preset-typescript',
        {
          allExtensions: true // 支持所有文件擴(kuò)展名,否則在vue文件中使用ts會(huì)報(bào)錯(cuò)
        }
      ]
    ],
    plugins: [
      [
        //js文件在babel轉(zhuǎn)碼后會(huì)生成很多helper函數(shù)(可能有大量重復(fù)),polyfill會(huì)在全局變量上掛載目標(biāo)瀏覽器缺失的功能,這個(gè)插件的作用是將 helper 和 polyfill 都改為從一個(gè)統(tǒng)一的地方引入,并且引入的對(duì)象和全局變量是完全隔離的
        //Babel 默認(rèn)只轉(zhuǎn)換新的 JavaScript 句法(syntax),而不轉(zhuǎn)換新的 API(polify實(shí)現(xiàn))
        '@babel/plugin-transform-runtime',
        {
          corejs: 3
        }
      ]
    ]
  }
}

知識(shí)點(diǎn)

環(huán)境區(qū)分

 // package.json 命令行
 "build:dev": "cross-env NODE_ENV=development webpack serve --config build/webpack.dev.js",
 "build:prod": "cross-env NODE_ENV=production webpack --config build/webpack.prod.js",
 "build:analyzer": "cross-env NODE_ENV=analyzer webpack serve --config build/webpack.prod.js",

在window環(huán)境下需要cross-env這個(gè)依賴幫助我們node環(huán)境下做變量標(biāo)識(shí),通過NODE_ENV進(jìn)行聲明即可。

//webpack.dev.js
new webpack.DefinePlugin({
   'process.env.NODE_ENV': JSON.stringify('development'),
   __VUE_OPTIONS_API__: true, //控制臺(tái)警告處理
   __VUE_PROD_DEVTOOLS__: true //控制臺(tái)警告處理
 })
//webpack.prod.js
new webpack.DefinePlugin({
     'process.env.NODE_ENV': JSON.stringify('production'),
     __VUE_OPTIONS_API__: true, //控制臺(tái)警告處理
     __VUE_PROD_DEVTOOLS__: false //控制臺(tái)警告處理
   }),

在代碼中,通過definePlugin定義變量后,通過process.env.NODE_ENV來獲取當(dāng)前是開發(fā)環(huán)境還是生產(chǎn)環(huán)境。

css-loader和style-loader

css-loader的作用是將css文件轉(zhuǎn)換成webpack能夠處理的資源,而style-loader就是幫我們直接將css-loader解析后的內(nèi)容掛載到html頁面當(dāng)中

asset資源模塊

webpack5 新增資源模塊(asset module),允許使用資源文件(字體,圖標(biāo)等)而無需配置額外的 loader。

{
      test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
      type: 'asset',
      parser: {
        dataUrlCondition: {
          // 文件小于 10k 會(huì)轉(zhuǎn)換為 base64,大于則拷貝文件
          maxSize: 10 * 1024
        }
      },
      generator: {
        filename: 'images/[base]'
      }
    },
    {
      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]'
      }
    }

性能優(yōu)化

按需引入

echarts打包后占用體積過大

import * as echarts from 'echarts'//全局引入echarts
//按需引入echarts
import * as echarts from 'echarts/core'
import { BarChart } from 'echarts/charts'
import { LegendComponent, TitleComponent, TooltipComponent, GridComponent, DatasetComponent, TransformComponent } from 'echarts/components'
import { LabelLayout, UniversalTransition } from 'echarts/features'
import { CanvasRenderer } from 'echarts/renderers'
import { setTimeSecond, setTimeStr } from '@/utils/index'
import useStore from '@/stores'
// 注冊(cè)必須的組件
echarts.use([
  LegendComponent,
  TitleComponent,
  TooltipComponent,
  GridComponent,
  DatasetComponent,
  TransformComponent,
  BarChart,
  LabelLayout,
  UniversalTransition,
  CanvasRenderer
])

image.png

image.png

可以看到echarts如果是全局引用的情況下,打包體積有3.67m,但按需引入后就只有1.36m了。

組件庫的按需引入

通過unplugin-vue-components/webpack插件,不會(huì)全局引入ant-design,會(huì)按需引入。

require('unplugin-vue-components/webpack')({
      resolvers: [
        AntDesignVueResolver({
          importStyle: false
        }),
        YouibotPlusResolver()
      ],
      dts: true,
      dirs: ['src/components', 'src/pages'] // 按需加載的文件夾
}),

分包策略

// chunk拆分,提升首屏加載速度
  splitChunks: {
    cacheGroups: {
      vendors: {
        // 提取node_modules代碼
        test: /node_modules/, // 只匹配node_modules里面的模塊
        name: 'vendors', // 提取文件命名為vendors,js后綴和chunkhash會(huì)自動(dòng)加
        minChunks: 1, // 只要使用一次就提取出來
        chunks: 'initial', // 只提取初始化就能獲取到的模塊,不管異步的
        minSize: 0, // 提取代碼體積大于0就提取出來
        priority: 1 // 提取優(yōu)先級(jí)為1
      },
      commons: {
        // 提取頁面公共代碼
        name: 'commons', // 提取文件命名為commons
        minChunks: 2, // 只要使用兩次就提取出來
        chunks: 'initial', // 只提取初始化就能獲取到的模塊,不管異步的
        minSize: 0 // 提取代碼體積大于0就提取出來
      }
    }
  },

image.png

//index.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <link rel="icon" type="image/svg+xml" href="/logo.ico" rel="external nofollow"  />
    <meta name="viewport" content="width=device-width,initial-scale=1" />
    <script src="/config.js"></script>
    <title>YOUIFLEET</title>
    <link rel="icon" href="logo.ico" rel="external nofollow"  />
    <script defer="defer" src="js/vendors.cb5671c1aeb89321634e.js"></script>
    <script defer="defer" src="js/app.cb5671c1aeb89321634e.js"></script>
    <link href="css/vendors.acd8e0885f2241c62cf1.css" rel="external nofollow"  rel="stylesheet" />
    <link href="css/app.63706e02f684f71c27bd.css" rel="external nofollow"  rel="stylesheet" />
  </head>
  <body>
    <div id="app"></div>
    <link rel="stylesheet/less" href="/color.less" rel="external nofollow"  />
    <script src="/less-2.7.2.min.js"></script>
  </body>
</html>

這里可以看到通過分包策略后,打出了兩個(gè)js文件,可以看到是defer異步執(zhí)行,不阻塞html的渲染(async也是異步的,但是并行加載,js加載好了就會(huì)執(zhí)行,如果js前后有依賴性,可能會(huì)出錯(cuò))。

多線程打包

 {
        test: /\.(ts|js)x?$/,
        use: [
          {
            loader: 'thread-loader', // 開啟多進(jìn)程打包
            options: {
              worker: 3
            }
          },
          babelLoaderConf
        ],
        exclude: /node_modules/
      },

由于運(yùn)行在 Node.js 之上的 webpack 是單線程模型的,我們需要 webpack 能同一時(shí)間處理多個(gè)任務(wù),發(fā)揮多核 CPU 電腦的威力。

thread-loader 就能實(shí)現(xiàn)多線程打包,它把任務(wù)分解給多個(gè)子進(jìn)程去并發(fā)的執(zhí)行,子進(jìn)程處理完后再把結(jié)果發(fā)送給主進(jìn)程,來提升打包速度。

優(yōu)化策略遠(yuǎn)不止這幾項(xiàng),還有路由懶加載,組件懶加載,gzip壓縮,cdn引入第三方依賴DllPlugin 動(dòng)態(tài)鏈接庫,Web Worker骨架屏...通過打包后的結(jié)果進(jìn)行對(duì)應(yīng)分析即可。

踩坑記錄

Stylelint報(bào)錯(cuò)

image.png

該問題需要通過husky配置lint-staged處理,但由于我們項(xiàng)目前后端代碼放在一個(gè)大文件夾下內(nèi)分單獨(dú)文件夾管理,配置不了husky,所以只能暫時(shí)將stylelint-webpack-plugin給注釋掉,如果大佬有解決方案可以在評(píng)論區(qū)提一下感謝。

Vue動(dòng)態(tài)路由配置component

// 生成路由數(shù)據(jù)
const generateRoute = (list: Array<IRouteData>): RouterType[] => {
  const routerList: RouterType[] = []
  const modules = require.context('../pages', true, /\.vue$/).keys()
  /**
   *
   * @param { Array<IRouteData>} routers 接口返回?cái)?shù)據(jù)
   * @param {RouterType[]} routerData 生成數(shù)據(jù)存儲(chǔ)
   */
  function generateRouter(routers: Array<IRouteData>, routerData: RouterType[] = []): void {
    routers.forEach(routerItem => {
      const { url, name, icon, children } = routerItem
      //判斷是否存在子路由
      const isRouteChildren = children && children.length && children[0].type === 0
      const redirect = isRouteChildren ? children[0].url : undefined
      const component =
        modules.indexOf(`.${url}/index.vue`) !== -1 ? () => import(/* webpackChunkName: "[request]" */ `@/pages${url}/index.vue`) : null
      const routerItemData: RouterType = {
        path: url,
        redirect,
        name,
        component,
        meta: {
          title: name,
          icon: icon,
          attribution: name
        },
        children: []
      }
      if (isRouteChildren) {
        generateRouter(children, routerItemData.children)
      }
      routerData.push(routerItemData)
    })
  }
  generateRouter(list, routerList)
  return routerList
}

這個(gè)component配置包含了血淚史,因?yàn)橹耙婚_始component配置的時(shí)候找不到父路由的時(shí)候,我給配了子路由的component,導(dǎo)致后面component加載重復(fù)一直切換報(bào)錯(cuò),其實(shí)配置一個(gè)null就可以。

附錄

感謝以下大佬的文章分享

# 透過分析 webpack 面試題,構(gòu)建 webpack5.x 知識(shí)體系

# 前端性能優(yōu)化——包體積壓縮82%、打包速度提升65%

# 前端性能優(yōu)化——首頁資源壓縮63%、白屏?xí)r間縮短86%

#【腳手架】從0到1搭建React18+TS4.x+Webpack5項(xiàng)目(一)項(xiàng)目初始化

到此這篇關(guān)于Vite3遷移Webpack5的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)Vite3遷移Webpack5內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Vue中實(shí)現(xiàn)滾動(dòng)加載與無限滾動(dòng)

    Vue中實(shí)現(xiàn)滾動(dòng)加載與無限滾動(dòng)

    本文主要介紹了Vue中實(shí)現(xiàn)滾動(dòng)加載與無限滾動(dòng),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-06-06
  • 利用Nuxt.js做Vuex數(shù)據(jù)持久化

    利用Nuxt.js做Vuex數(shù)據(jù)持久化

    這篇文章主要介紹了利用Nuxt.js做Vuex數(shù)據(jù)持久化問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-10-10
  • vue?點(diǎn)擊刪除常用方式小結(jié)

    vue?點(diǎn)擊刪除常用方式小結(jié)

    這篇文章主要介紹了vue?點(diǎn)擊刪除常用方式小結(jié),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-04-04
  • 在vue中使用G2圖表的示例代碼

    在vue中使用G2圖表的示例代碼

    這篇文章主要介紹了在vue中使用G2圖表的示例代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2019-03-03
  • Vue中插槽slot的使用方法

    Vue中插槽slot的使用方法

    插槽就是子組件中的提供給父組件使用的一個(gè)占位符,用<slot></slot> 表示,父組件可以在這個(gè)占位符中填充任何模板代碼,如 HTML、組件等,填充的內(nèi)容會(huì)替換子組件的<slot></slot>標(biāo)簽,這篇文章主要介紹了Vue插槽的理解和使用,需要的朋友可以參考下
    2023-03-03
  • 淺談vue項(xiàng)目4rs vue-router上線后history模式遇到的坑

    淺談vue項(xiàng)目4rs vue-router上線后history模式遇到的坑

    今天小編就為大家分享一篇淺談vue項(xiàng)目4rs vue-router上線后history模式遇到的坑,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2018-09-09
  • vue中路由重定向redirect問題

    vue中路由重定向redirect問題

    這篇文章主要介紹了vue中路由重定向redirect問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-05-05
  • vue 請(qǐng)求后臺(tái)數(shù)據(jù)的實(shí)例代碼

    vue 請(qǐng)求后臺(tái)數(shù)據(jù)的實(shí)例代碼

    本篇文章主要介紹了vue 請(qǐng)求后臺(tái)數(shù)據(jù)的實(shí)例代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧、
    2017-06-06
  • vue3+vite中使用vuex的具體步驟

    vue3+vite中使用vuex的具體步驟

    在vue3+vite創(chuàng)建的項(xiàng)目中使用vuex,要注意的是vite有部分寫法和之前的webpack是不同的,這篇文章主要介紹了vue3+vite中使用vuex的具體步驟,需要的朋友可以參考下
    2022-11-11
  • vuex 中插件的編寫案例解析

    vuex 中插件的編寫案例解析

    Vuex 的 store 接受 plugins 選項(xiàng),這個(gè)選項(xiàng)暴露出每次 mutation 的鉤子。Vuex 插件就是一個(gè)函數(shù),這篇文章主要介紹了vuex 中插件的編寫案例,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2019-06-06

最新評(píng)論