How to configure multiple entries for vite+vue3+ts project?

Why does the project have multiple entrances?

  • During project development, you may encounter some components or business modules of project A that need to be reused in project B. If the codes reused by projects A and B are modified, they need to be synchronized in time. You can copy them manually, or you can copy the reused parts. Extracted as an npm package but needs to be re-published every time it is modified;
  • Obviously, these two methods are not very friendly, so we considered the multi-entry form so that the user frontend and management backend of the system are placed in the same code warehouse for management, which can avoid modification conflicts, repeated releases and other problems;

Configure multiple entries

  1. First adjust the file directory, and put the codes of the front-end portal and the back-end admin in different folders as shown in the figure.Insert image description here

  2. Use plugins to enter different URLs to jump to different platforms, for example: enter /admin to jump to the backend, enter / to jump to the frontend

  • The connect-history-api-fallback middleware used here proxies requests through the specified index page, which is very useful for single-page applications using the HTML5 history API.
    For detailed instructions, see connect-history-api-fallback
  • npm install --save connect-history-api-fallback
  • Add the vite-plugin-history.ts file in the root directory
const historyFallback = require('connect-history-api-fallback');

module.exports = function createVitePluginHistory(options) {
    
    
  return {
    
    
    name: 'vite-plugin-history',
    enforce: 'pre',
    config() {
    
    
      return {
    
    
        appType: 'mpa',
      };
    },
    configureServer(server) {
    
    
      server.middlewares.use(
        historyFallback({
    
    
          verbose: Boolean(process.env.DEBUG) && process.env.DEBUG !== 'false',
          disableDotRule: undefined,
          htmlAcceptHeaders: ['text/html', 'application/xhtml+xml'],
          ...options,
        })
      );
    },
  };
};

  • Introduce this file into the vite.config.ts file and configure it in plugins as follows
const historyFallback = require('./vite-plugin-history');
const viteConfig = defineConfig((mode: ConfigEnv) => {
    
    
  const moduleName = mode.mode;
  return {
    
    
    server: {
    
    
      hmr: true,
      port: 8000,
      open: '/',
      cors: true,
    root: './src/modules',
    plugins: [
      vue(),
      historyFallback({
    
    
        rewrites: [
          {
    
    // 注意这里url使用了admin后项目中的路由url应避免起重复名称哦
            from: '/admin',
            to: `/admin/index.html`,
          },
          {
    
    
            from: '/',
            to: `/portal/index.html`,
          },
        ],
      }),
    ],
    },
  };
});
  1. Packaging configuration, we expect to execute different commands to package the corresponding packages,
  • The configuration in package.json is as follows
"scripts": {
    
    
    "build:portal": "vue-tsc --noEmit && vite build --mode portal",
    "build:admin": "vue-tsc --noEmit && vite build --mode admin",
  },
  • Configure build in the vite.config.ts file as follows
const viteConfig = defineConfig((mode: ConfigEnv) => {
    
    
  const moduleName = mode.mode;
  return {
    
    
    server: {
    
    
      hmr: true,
      port: 8000,
      open: '/',
      cors: true,
      proxy: {
    
    
    },
    root: './src/modules',
    plugins: [
      vue(),
    base: '/', // 设置打包路径
    publicDir: '../../public',
    build: {
    
    
      rollupOptions: {
    
    
        input: {
    
    
          [moduleName]: resolve(__dirname, `./src/modules/${
      
      moduleName}/index.html`),
        },
        output: {
    
    
          chunkFileNames: 'js/[name]-[hash].js',
          entryFileNames: 'js/[name]-[hash].js',
          assetFileNames: '[ext]/[name]-[hash].[ext]',
        },
      },
      outDir: `../../build/${
      
      moduleName}`,
    },
  };
});
  • The directory generated after packaging is as follows:
    The directory generated after packaging
  • Expand the admin folder as shown below:
    The admin folder structure after packaging
  • I found that index.html is wrapped with an outer layer. Sometimes we don’t need this layer when configuring nginx. I haven’t found the current configuration of vite that can remove this layer, but it can be removed in other ways. eg: add The script executes the postbuild.sh file
"scripts": {
    
    
    "postbuild:portal": "sh ./postbuild.sh portal",
    "postbuild:admin": "sh ./postbuild.sh admin",
  },
// postbuild.sh  文件内容如下

#!/bin/bash
# 解决构建完成后 index.html路径问题
# (修改 build/admin/admin/index.html -> build/admin/index.html)
# (修改 build/portal/portal/index.html -> build/portal/index.htm)
rootDir=./build/$1
cd ${
    
    rootDir}
cp ./$1/index.html ./
rm -rf ./$1

echo '构建完成'

Or learn from Xiaomou’s vue3+vite configuration to expand indexPath article sharing;

  • Finally, the complete vite.config.ts configuration is attached.
import {
    
     defineConfig, ConfigEnv } from 'vite';
import vue from '@vitejs/plugin-vue';
import {
    
     resolve } from 'path';
const historyFallback = require('./vite-plugin-history');
// https://vitejs.dev/config/
const viteConfig = defineConfig((mode: ConfigEnv) => {
    
    
  const moduleName = mode.mode;
  return {
    
    
    server: {
    
    
      hmr: true,
      port: 8000,
      open: '/',
      cors: true,
      proxy: {
    
    
        '/api': {
    
    
          target: 'http://xxx.com',
          changeOrigin: true,
          secure: false,
          cookieDomainRewrite: {
    
    
            'xxx.com': 'localhost',
          },
          // rewrite: (path) => path.replace('/api', ''),
        },
      },
    },
    root: './src/modules',
    plugins: [
      vue(),
      historyFallback({
    
    
      // 注意这里url使用了/admin后,项目中的route路由的path应避免起重复名称哦,不然会跳转不正确
        rewrites: [
          {
    
    
            from: '/admin',
            to: `/admin/index.html`,
          },
          {
    
    
            from: '/',
            to: `/portal/index.html`,
          },
        ],
      }),
    ],
    resolve: {
    
    
      alias: {
    
    
        '@': resolve(__dirname, 'src'),
      },
      extensions: ['.ts', '.js', '.vue', '.json'],
    },
    base: '/', // 设置打包路径
    publicDir: '../../public',
    build: {
    
    
      rollupOptions: {
    
    
        input: {
    
    
          [moduleName]: resolve(__dirname, `./src/modules/${
      
      moduleName}/index.html`),
        },
        output: {
    
    
          chunkFileNames: 'js/[name]-[hash].js',
          entryFileNames: 'js/[name]-[hash].js',
          assetFileNames: '[ext]/[name]-[hash].[ext]',
        },
      },
      outDir: `../../build/${
      
      moduleName}`,
      minify: 'terser',
      terserOptions: {
    
    
        compress: {
    
    
          drop_console: true,
        },
      },
    },
  };
});

export default viteConfig;

Guess you like

Origin blog.csdn.net/kang_k/article/details/130268581