vite+vue3+ts项目如何配置多入口?

项目为什么设置多入口?

  • 项目开发时会遇到a项目有部分组件或者业务模块要复用到b项目,如果a,b两个项目复用的代码有修改的话需要及时同步,可以手动copy,也可以将复用的部分提取为类似于npm包但是每次修改都需要重新publish;
  • 显而易见这两种方式都不太友好,于是考虑到的多入口的形式 这样系统的用户前台和管理后台放在了同一个代码仓库进行管理,可以避免修改冲突,已经重复发布等问题;

配置多入口

  1. 先调整文件目录,前台portal和后台admin的代码放到不同的文件夹下如图在这里插入图片描述

  2. 借助plugins实现输入不同的url跳转不同的平台eg: 输入/admin 跳转后台,输入 / 跳转到前台

  • 这里用到 connect-history-api-fallback 通过指定的索引页代理请求的中间件,对于使用HTML5历史API的单页应用程序非常有用。
    详细的说明看connect-history-api-fallback
  • npm install --save connect-history-api-fallback
  • 在根目录下添加vite-plugin-history.ts文件
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,
        })
      );
    },
  };
};

  • 在vite.config.ts文件里引入该文件,并在plugins里配置如下
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. 打包配置,我们期望执行不同的命令打包对应的包,
  • 在package.json配置如下
"scripts": {
    
    
    "build:portal": "vue-tsc --noEmit && vite build --mode portal",
    "build:admin": "vue-tsc --noEmit && vite build --mode admin",
  },
  • 在vite.config.ts文件配置build如下
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}`,
    },
  };
});
  • 打包后生成的目录如下:
    打包后生成的目录
  • 展开admin文件夹如下图:
    打包后admin文件夹结构
  • 发现index.html外层包裹了一层,有时候我们配置nginx的时候不需要这一层,vite目前的配置我还没查找的可以去掉这一层的,不过可以通过别的方式去掉 eg:添加脚本执行postbuild.sh文件
"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 '构建完成'

或者借鉴知乎上小谋的vue3+vite的配置扩展indexPath文章分享;

  • 最后附上完整的vite.config.ts配置
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;

猜你喜欢

转载自blog.csdn.net/kang_k/article/details/130268581