Build the column series catalog entry

Liang Xiaoying: A pig girl from the front technology department of Weiddoctor who likes reading 📚&& swimming 🏊🏻 ~ 🤔

The current [email protected]

I. What project is suitable for migration

  1. Use the vuE2 system
  2. Internal systems – No need for large traffic scenarios: Because vite changes quickly, basic functions of the system need to be changed regularly, resulting in instability
  3. Non-ssr systems – THERE are many problems with SSR until the community is enriched
  4. A system that is regularly maintained
  5. Have pain points for development and want to improve: slow packaging, slow cold start, slow HMR update…
  6. Vite production environment rollup is used, but the transformation cost is large, the improvement efficiency is not high, and the risk is high, so it is not recommended to use. [my humble opinion, big guy light spray]

2. Migration Steps

The internal system will be used as a case study, vite for development, and Webpack for production.

  1. Briefly learn about vite features. If there is a problem, please look at the vite official website to check whether there is an update or solution!!
  2. NPM I [email protected] [email protected] [email protected] -d
  3. Package. json adds a script — “vite”: “NODE_ENV=development vite”
  4. The key is to configure vite.config.js [default is called this filename, you can configure other..
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 { cjs2esmVitePlugin } from 'cjs2esmodule'
import dotenv from 'dotenv'
const config = require('./config')

try {
  // Load environment variable files according to environment variables
  const file = dotenv.parse(fs.readFileSync(`./config/.env.${process.env.NODE_ENV}`), {
    debug: true
  })
  console.log(file)
  // Assign a value to the environment variable based on the obtained key
  for (const key in file) {
    process.env[key] = file[key]
  }
} catch (e) {
  console.error(e)
}
const API_LOCATION = process.env.API_LOCATION || '/api'

function resolve(dir) {
  return path.join(__dirname, '/', dir)
}
export default defineConfig({
  root: '/'.// The project root (where the index.html file is) can be either an absolute path or a relative path to the configuration file itself.
  publicDir: 'public'.// Serve as a static resource folder. The value can be either an absolute path to the file system or a relative path to the project's root directory.
  base: '/'.// Common base path. The value can be an absolute path or an empty string
  mode: 'development'.optimizeDeps: { // Third party dependencies to prebuild
    include: []},resolve: {
    alias: {
      // 'vue': 'vue/dist/vue.esm.js', // if template parsed - use this vue: the internal end of the regular expression vue
      'vendor': resolve('src/vendor'),
      The '@': resolve('src'),
      '~ @': resolve('src'),
      '~component': resolve('src/components'),
      '~config': resolve('config'),}},plugins: [
    cjs2esmVitePlugin(), // Convert commonJS to ES Module: error
    createVuePlugin({
      jsx: true.jsxOptions: {
        injectH: false,
      },
    }),
    minifyHtml(), HTML / / compression
    injectHtml({ // Import file index.html template injection
      injectData: { // Template injected data
        htmlWebpackPlugin: {
          options: {
            isVite: true.shotcut: '/static/img/favicon.png',}},title: 'HMO Operation Background ',}})],define: {
    'process.env': process.env
  },
  server: {
    host: 'liang.myweb.com'.open: true.// Whether to open the browser automatically
    port: process.env.PORT || config.dev.port,
    proxy: {
      [API_LOCATION]: {
        target: 'http://127.0.0.1:8001'.rewrite: (path) = > path.replace(API_LOCATION, ' ')}}},});Copy the code

【 Step pit diary 😄】

1. Vite currently requires the entry file to be index. HTML in the root directory, if the previous webpack entry file has the same name, this needs to be changed.

Solution: vite.config.js:

import { injectHtml } from 'vite-plugin-html';
export default defineConfig({
  plugins:[
    injectHtml({ // Import file index.html template injection
      injectData: { // Template injected data
        htmlWebpackPlugin: { // Select the object key with the same name as the WebPack plug-in
          options: {
            isVite: true.shotcut: '/static/img/favicon.png',}},title: 'HMO Operation Background '}})]})Copy the code

webpack.xxx.js

new HtmlWebpackPlugin({
  template: 'index.html'.inject: true.isVite: false // Add the identifier
})
Copy the code

Root directory entry file index.html – ejs template

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

2. The new version xx error: the old version can be switched, such [email protected]

3. Is the export not named?

Uncaught SyntaxError: The requested module ‘/config/index.js’ does not provide an export named ‘default’Uncaught SyntaxError: The requested module ‘/config/index.js’ does not provide an export named ‘default’

Error cause: The browser only supports ESM and does not support CJS vite.config.js

import { cjs2esmVitePlugin } from 'cjs2esmodule'
export default defineConfig({
  plugins: [
  	cjs2esmVitePlugin(), // Convert commonJS to es Module]})Copy the code

If require.xx is written on demand, it can be changed to import, as follows:

const subjectList = r => require.ensure( [], () => r(require('@/pages/xxx/subject/list.vue')), 'subject' );

// Change to: Vue dynamic component: ()=>import()

const subjectList = () => import(/* webpackChunkName: "subject" */ '@/pages/xxx/subject/list.vue')
const arr = [
  {
    path: '/subject/list',
    name: 'subject/list',
    component: subjectList
    meta: {...}
  }
];
export default arr;
Copy the code

4. Use the proxyhttp-proxy. See the full optionshere.

Case study:

proxy: {
      '/rest': {
        target: 'http://my.web.com/'.changeOrigin: true.bypass: (req, res, proxyOption) = > {
          console.log('Current request agent:${req.url} -> ${proxyOption.target}`); }},}Copy the code

5. Ts file error?

Verify that TS processing for vite is configured

"compilerOptions": {
  "types": ["vite/client"]}Copy the code

6. Global environment variable error?

// const isProd = ENV === 'production'; // webpack-dev environment variable
// const isProd = import.meta.env.PROD; // vite-dev environment variable
// to avoid 👆🏻 above, use NODE_ENV to distinguish:
const isProd = process.env.NODE_ENV === 'production'; So when we start:"dev": "NODE_ENV=development vite"
Copy the code

Or explore the Babel plugin for the community: Babel-preset -vite babel-plugin-transform-vite-meta-env babel-plugin-transform-vite-meta-glob

7. Read some printouts of logs & errors etc.?

Cli –debug, or vite.config.js to configure and print related parameters

8. When importing a file such as.vue, can you omit the extension?

Yes!! Resolve. Extensions: [‘.vue’] [‘.vue’] [‘.vue’] [‘.vue’] [‘.vue’]

error: No loader is configured for “.vue”

Harm! Add the extension honestly! The convenient way to add a global extension is as follows:link

9. Less file not found?

[vite] Internal server error: ‘~@/styles/var.less’ wasn’t found.

NPM install -d less (1) : NPM install -d less (2)

10. How to support JSX?

vite.config.js

import { createVuePlugin } from 'vite-plugin-vue2';
createVuePlugin({
  jsx: true.JSX / / configuration
  jsxOptions: {
    injectH: false,}})Copy the code
Vue.component('my-component',{
	render () {
  	return (<div>my template</div>)}})Copy the code

11. Configure agents based on environment variables.

(1) Cross-env to set environment variables across platforms

1. The installation of cross – env

npm i cross-env -D

(2) Load environment variable files. It loads environment variables from the.env file into process.env

2. Install dotenv

npm i dotenv -D

(3) config/.env.development configuration variable

NODE_ENV = development
API_LOCATION = /api
LOGOUT_PC_LOCATION = http://user.myweb.com/login
CRM_ADDRESS = http://crm.myweb.com
Copy the code

(4) Configure vte.config.ts

try {
  // Load environment variable files according to environment variables
  const file = dotenv.parse(fs.readFileSync(`./config/.env.${process.env.NODE_ENV}`), {
    debug: true
  })
  console.log(file)
  // Assign a value to the environment variable based on the obtained key
  for (const key in file) {
    process.env[key] = file[key]
  }
} catch (e) {
  console.error(e)
}
const API_LOCATION = process.env.API_LOCATION || '/api'. Is omittedexport default defineConfig({
  server: {
    proxy: {
      [API_LOCATION]: {
        target: 'http://127.0.0.1:8001'.rewrite: (path) = > path.replace(API_LOCATION, ' ') // Configure the proxy based on the environment variables}}}})Copy the code

(5) Package. json startup script

"vite": "cross-env NODE_ENV=development vite"
Copy the code

12. Environment variable error?

Webpack uses an environment variable called process.env. Vite does not have this variable, so the error is reported

Uncaught ReferenceError: process is not defined

Vite uses import.meta. Env, but our old code doesn’t want to move? Vite still leaves a hole for us to define global variables.

export default defineConfig({
  // ...
  define: {
    'process.env': {}
  }
})
Copy the code

13. anything else?

. There are endless bugs, many of them are non-generic problems, are found after the introduction of Vite system itself some problems, here is not an example. More general issues will be tracked later