6-летний проект мигрировал на vite2, в десятки раз быстрее, реально ароматнее

Vue.js Vite

vite-dev.png

задний план

Система гоу старая, большая и грязная.Каждый раз, когда разработка спроса крайне неудобна, вряд ли допустимо начинать 30|40 секунд.Ведь это происходит только раз в день, ноHMRОбновляется несколько секунд, терпеть не могу, я увидел рассвет, когда увидел vite2! тарелка это

Давайте посмотрим на запуск и компиляцию vue-cli3...

编译-new-48803ms.png

  • Этот проект представляет собой внутреннюю систему управления операциями, возраст 6+
  • на основеvue2+elementui, 2 года вступления будетvue-cli2обновлен доvue-cli3, 2 года спустя сегодня я не могу дождаться, чтобы бежатьvite2охватывать
  • Мигрируйте только среду разработки (моей проблемой является только среда разработки, вы можете сами рассмотреть производственную среду)

Анализ болевых точек

по сути правильноwebpackАнализ принципа работы,webpackРабочий процесс в среде разработки примерно такой (личное мнение не нравится или нет):

Найти входной файл => Анализ зависимостей => Преобразовать функцию модуля => Упаковать и сгенерировать пакет => Запуск службы узла

Так что по мере того, как проект становится больше, скорость становится все медленнее и медленнее...

Что касаетсяHMRТо же верно, ноHMRЯвляется ли текущий файл записью, проводимойrebuild, связанные зависимости должны быть перегружены

ЗачемVite

  • вит основан наesmРеализовано, основные браузеры уже поддерживают его, поэтому нет необходимости упаковывать и компилировать файл.
  • Проект запускается очень быстро (простые оценочные данные после миграции увеличиваются с 30с до 1с. В 30 раз? 3000%? Совсем не преувеличение...)
  • или на основеesm,HMRОчень быстро, не нужно компилировать и перезагружать, скорость можно описать в мгновение ока...

viteГрубый рабочий процесс:

Запустить службу => найти файл записи (скрипт модуля) => браузер отправляет запрос => vite перехватывает обработку запроса и возвращает файл в браузер

Откройтесь и встаньте на путь миграции

  1. Установите связанные пакеты npm

    npm i vite vite-plugin-vue vite-plugin-html -D
    
    • vite-plugin-vue, для строительстваvue,нагрузкаjsx
    • vite-plugin-html, для внедрения шаблона входного файла
  2. существуетpackage.jsonфайл, добавьтеviteКоманда запуска:

    "vite": "cross-env VITE_NODE_ENV=dev vite"
    
  3. новый корневой каталогvite.config.jsдокумент

  4. Будуpublicвнизindex.htmlСкопируйте копию в корневой каталог

    Мигрируйте только среду разработки, index.html по-прежнему требуется для общедоступных, а режимы vite и webpack поддерживаются в среде разработки.

  5. Изменить корневой каталогindex.html(Файл входа для запуска vite должен быть корневым каталогом)

    <% if (htmlWebpackPlugin.options.isVite) { %>
      <script type="module" src="/src/main.js"></script>
    <%}%>
    

    htmlWebpackPlugin внедряется в vite.config.js, isVite используется для определения того, является ли запуск vite.

    import { injectHtml } from 'vite-plugin-html';
    export default defineConfig({
      plugins:[
        injectHtml({
          injectData: {
            htmlWebpackPlugin: {
              options: {
                isVite: true
              }
            },
            title: '运营管理平台'
          }
        })
      ]
    })
    ​
    
  6. всеvite.config.jsнастроить

    import { defineConfig } from 'vite'
    import path from 'path'
    import fs from 'fs'
    import { createVuePlugin } from 'vite-plugin-vue2'
    import { injectHtml, minifyHtml } from 'vite-plugin-html'
    import dotenv from 'dotenv'
    ​
    try {
        // 根据环境变量加载环境变量文件
        const VITE_NODE_ENV = process.env.VITE_NODE_ENV
        const envLocalSuffix = VITE_NODE_ENV === 'dev' ? '.local' : ''
        const file = dotenv.parse(fs.readFileSync(`./.env.${VITE_NODE_ENV}${envLocalSuffix}`), {
            debug: true
        })
        for (const key in file) {
            process.env[key] = file[key]
        }
    } catch (e) {
        console.error(e)
    }
    ​
    const resolve = (dir) => {
        return path.join(__dirname, './', dir)
    }
    export default defineConfig({
        root: './',
        publicDir: 'public',
        base: './',
        mode: 'development',
        optimizeDeps: {
            include: []
        },
        resolve: {
            alias: {
                'vendor': resolve('src/vendor'),
                '@': resolve('src'),
                '~component': resolve('src/components')
            },
            extensions: [
                '.mjs',
                '.js',
                '.ts',
                '.jsx',
                '.tsx',
                '.json',
                '.vue'
            ]
        },
        plugins: [
            createVuePlugin({
                jsx: true,
                jsxOptions: {
                    injectH: false
                }
            }),
            minifyHtml(),
            injectHtml({
                injectData: {
                    htmlWebpackPlugin: {
                        options: {
                            isVite: true
                        }
                    },
                    title: '运营管理平台'
                }
            })
        ],
        define: {
            'process.env': process.env
        },
        server: {
            host: '0.0.0.0',
            open: true,
            port: 3100,
            proxy: {}
        }
    })
    ​
    

    Соответствующая конфигурация будет подробно описана в проблемах, возникающих ниже.

Проблемы, возникающие при миграции

  1. Uncaught SyntaxError: The requested module 'xx.js' does not provide an export named 'xx'

    Я столкнулся с двумя ситуациями:

    А. Модуль может иметь только один выход по умолчанию.importФигурные скобки после команды ставить не нужно, иначе будет сообщено об ошибке

    Метод обработки: оригинал{}импортированныйkeys, изменено на импорт по умолчаниюkey,es6присваивание деструктуризации

    -import { postRedeemDistUserUpdate } from '@/http-handle/api_types'
    ​
    +import api_types from '@/http-handle/api_types'
    +const { postRedeemDistUserUpdate } = api_types
    

    б. Браузер поддерживает толькоesm,не поддерживаетсяcjs, необходимоcjsизменить наesm(Я прочитал онлайн-статью и прошелcjs2esmoduleобработано, но некоторые сценарии моего приложения ошибочны и в итоге удалены)

    Способ обращения: Не рекомендуетсяcjs2esmodule, установите вручнуюmodule.exportsизменить наexport

    -module.exports = {
    
    +export default {
    
  2. .vueрасширение файла, последняя версияviteкажется, поддерживаетсяextensionsДобавить к.vue, но рекомендуется добавлять суффикс вручную. (Операция Sao: регулярное добавление совпадающей партии)

  3. Uncaught ReferenceError: require is not defined

    Браузер не поддерживает cjs

    Метод обработки:requireВсе указанные файлы должны быть изменены наimportЦитировать

  4. начало, пустая страница

    Метод обработки: обратите внимание на входной файл index.html, вам нужно разместить корневую директорию проекта

  5. viteПо умолчанию нетprocess.env,доступныйdefineопределить глобальные переменные

    vue-cliВ режиме переменные окружения считываются из корневого каталога.envпеременные в файле, затемviteМожно ли читать в .envПеременные в файле в конечном итоге внедряются вprocess.envв?

    Возможно ли, чтобы эти два режима сосуществовали? Стоимость уменьшилась?

    Метод обработки:

    1. Установите инструмент загрузки переменных среды:dotenv
    npm i dotenv -D
    
    1. пользовательская глобальная переменнаяprocess.env

      vite.config.jsСредняя конфигурация

    define: {
      'process.env': {}
    }
    
    1. Загрузите переменные среды и добавьте вprocess.env

      vite.config.jsСредняя конфигурация

      Поскольку переносится только среда разработки, я читаю здесь файл .local по умолчанию.

      VITE_NODE_ENV внедряется через cross-env при запуске

import dotenv from 'dotenv'
try {
    const VITE_NODE_ENV = process.env.VITE_NODE_ENV
    const envLocalSuffix = VITE_NODE_ENV === 'dev' ? '.local' : ''
    const file = dotenv.parse(fs.readFileSync(`./.env.${VITE_NODE_ENV}${envLocalSuffix}`), {
        debug: true
    })
    console.log(file)
    for (const key in file) {
        process.env[key] = file[key]
    }
} catch (e) {
    console.error(e)
}
  1. jsxслужба поддержки

    vite.config.jsСредняя конфигурация

    plugins: [
      createVuePlugin({
        jsx: true,
        jsxOptions: {
          injectH: false
        }
    })
    
  2. в вебпакеrequire.contextметод, вviteкитайский посол用import.meta.globзаменять

Существующие проблемы

Функция импорта/экспорта в проекте реализована на чистом фронтенде

require('script-loader!file-saver')
require('script-loader!@/vendor/Blob')

Поскольку вышеуказанные файлы в настоящее время не поддерживаютсяimportимпорт,webpackСледующее черезscript-loaderНагрузка подключена к глобальной,viteсреда не может быть решена. Когда вам нужна функция импорта и экспорта, вы можете переключиться только наvue-cliРежим запуска службы...

Если у тебя есть план, пожалуйста, направь меня~, я действительно не хочу возвращатьсяwebpackразвитый...

наконец

Общая миграция не вызвала каких-либо неразрешимых проблем, и стоимость миграции по-прежнему невелика.Фактическая операция составляет 1-2 дня, а эффективность затрат очень высока.Согласно данным, мой проект в десятки раз превышает эффективность запуска. и несколько раз HMR.Повышение эффективности... Вы можете попробовать это на своей внутренней системе.

Вышеупомянутое является только записью личной практики, а не ориентировочной ценностью, только для справки...