import type { AliasOptions, Plugin } from 'vite'; import path from 'node:path'; import process from 'node:process'; import { fileURLToPath, URL } from 'node:url'; import mswMockPlugin from '@lingshu/vite-plugin-msw'; import sharePlugin from '@lingshu/vite-plugin-share'; import vue from '@vitejs/plugin-vue'; import vueJsx from '@vitejs/plugin-vue-jsx'; import { visualizer } from 'rollup-plugin-visualizer'; import UnoCSS from 'unocss/vite'; import { defineConfig } from 'vite'; function resolveAtSlashPlugin(): Plugin { const lcdpSrc = fileURLToPath(new URL('./src', import.meta.url)); const designerSrc = fileURLToPath(new URL('../../packages/print-webapp/packages/designer/src', import.meta.url)); const designerPathToken = 'print-webapp/packages/designer'; const lcdpAnchor = path.join(lcdpSrc, 'main.ts'); const designerAnchor = path.join(designerSrc, 'index.js'); return { name: 'lcdp-or-print-designer-at-slash-mobile', enforce: 'pre', async resolveId(source, importer) { if (!source.startsWith('@/')) { return null; } const sub = source.slice(2); const normalizedImporter = (importer || '').replace(/\\/g, '/').split('?')[0]; const fromDesigner = normalizedImporter.includes(designerPathToken); const anchor = fromDesigner ? designerAnchor : lcdpAnchor; const resolved = await this.resolve(`./${sub}`, anchor, { skipSelf: true }); return resolved?.id ?? null; }, }; } export default defineConfig((configEnv) => { const appSrcPath = fileURLToPath(new URL('./src/', import.meta.url)); const formDesignerSrcPath = fileURLToPath(new URL('../../packages/form-designer/src/', import.meta.url)); const businessModulePath = fileURLToPath(new URL('../../packages/business-module/src', import.meta.url)); const businessComponentsPath = fileURLToPath(new URL('../../packages/business-components/src/', import.meta.url)); const mobileRegisterIndexPath = fileURLToPath(new URL('../../packages/form-designer/src/config/register/mobile-index.ts', import.meta.url)); const mobileRegisterLoaderPath = fileURLToPath(new URL('../../packages/form-designer/src/config/register/loader.mobile.ts', import.meta.url)); // pc端组件库 shim const minmetalsBizComponentsShimPath = fileURLToPath(new URL('./src/mobile-shims/minmetals-biz-components.ts', import.meta.url)); const minmetalsProComponentsShimPath = fileURLToPath(new URL('./src/mobile-shims/minmetals-pro-components.ts', import.meta.url)); const lingshuBpmComponentsShimPath = fileURLToPath(new URL('./src/mobile-shims/lingshu-bpm-components.ts', import.meta.url)); const alias: AliasOptions = [ { find: /^~@\/config\/register$/, replacement: mobileRegisterIndexPath, }, { find: /^~@\/config\/register\/loader$/, replacement: mobileRegisterLoaderPath, }, { find: '@lingshu/business-module', replacement: businessModulePath, }, { find: /^@minmetals-ui\/biz-components$/, replacement: minmetalsBizComponentsShimPath, }, { find: /^@minmetals-ui\/pro-components$/, replacement: minmetalsProComponentsShimPath, }, { find: /^@lingshu\/bpm-components$/, replacement: lingshuBpmComponentsShimPath, }, // 拦截动态请求的 PC 端 CSS,直接指向移动端 Shim(避免 Rolldown 生成空 JS Chunk 导致 dist_exports 报错) { find: /^@lingshu\/bpm-components\/dist\/index\.css$/, replacement: lingshuBpmComponentsShimPath, }, { find: /^@minmetals-ui\/biz-components\/dist\/index\.css$/, replacement: minmetalsBizComponentsShimPath, }, // '@lingshu/core-utils': fileURLToPath(new URL('../../packages/core-utils/src/index.ts', import.meta.url)), // '@lingshu/ai-agents': fileURLToPath(new URL('../../packages/ai-agents/src/index.ts', import.meta.url)), // FIXME: 因以下依赖包暂未打包,临时采用声明别名引用源码 { find: /^~@\//, replacement: formDesignerSrcPath, }, { find: /^@busi-comp\//, replacement: businessComponentsPath, }, ]; const envProjectName = process.env.projectName; console.log('[LCDP Mobile Build]: projectName', envProjectName); const baseName = `/micro/${envProjectName || 'mip-lcdp'}`; return { base: baseName, define: { 'window.DEFAULT_PROJECT_NAME': JSON.stringify(`${envProjectName || 'mip-lcdp'}`), 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'development'), }, plugins: [ resolveAtSlashPlugin(), vue(), vueJsx(), UnoCSS(), mswMockPlugin(configEnv.mode), sharePlugin( configEnv, { debug: false, proxy: true, sharedCss: [ { name: 'vant-cisdi', paths: [ 'lib/index.css', ], pathsNotInMicro: [], }, ], }, ), { name: 'copy-html', enforce: 'post', generateBundle(options, bundle: any) { const originalHtml = bundle['mobile.html']; if (originalHtml) { this.emitFile({ type: 'asset', fileName: 'mobile/index.html', source: originalHtml.source, }); } }, }, ...configEnv.mode === 'analyze' ? [visualizer({ filename: 'build-analyze-mobile.html', gzipSize: true })] : [], ], oxc: { define: { 'console.log': 'void 0', 'console.info': 'void 0', 'console.warn': 'void 0', 'console.debug': 'void 0', }, }, resolve: { alias, conditions: ['import', 'module', 'browser', 'default'], }, optimizeDeps: { // 排除 @lingshu/lowcode-create,因为它已经构建好了,直接使用 dist 目录中的文件 exclude: ['@lingshu/lowcode-create'], }, build: { cssMinify: 'esbuild', sourcemap: false, outDir: 'dist', // 移动端构建不清空,因为通常是作为 PC 端的补充构建 emptyOutDir: false, rollupOptions: { input: { 'index': fileURLToPath(new URL('./mobile.html', import.meta.url)), 'single-spa-entry': fileURLToPath(new URL('./src/single-spa-entry.ts', import.meta.url)), }, external: ['monaco-editor'], output: { // 移动端特有的输出路径 entryFileNames: (chunkInfo) => { if (chunkInfo.name === 'single-spa-entry') { return 'mobile/single-spa-entry.js'; } return 'mobile/assets/[name]-[hash].js'; }, chunkFileNames: 'mobile/assets/[name]-[hash].js', assetFileNames: 'mobile/assets/[name]-[hash].[ext]', manualChunks(id) { if (id.includes('node_modules')) { if (id.includes('@minmetals-ui/mobile-biz-components')) { return 'vendor-minmetals-mobile'; } if (id.includes('element-plus') || id.includes('element-plus-cisdi')) { return 'vendor-pc-ui'; } if ( id.includes('@lingshu/communication') || id.includes('@lingshu/core-utils') || id.includes('@lingshu/integration-vue3') || id.includes('@lingshu/language-lib') || id.includes('@lingshu/theme-lib') || id.includes('@lingshu/icon') || id.includes('@minmetals/common-lib') || id.includes('@minmetals/tools') ) { return 'vendor-runtime'; } if (id.includes('@lingshu/bpm-api-service')) { return 'vendor-bpm-api'; } if (id.includes('@lingshu/') || id.includes('@minmetals/')) { return 'vendor-shared'; } return 'vendor-misc'; } if ( id.includes('/packages/form-designer/src/') || id.includes('/packages/business-module/src/') || id.includes('/packages/business-components/src/') ) { return 'pkg-mobile-app'; } if (id.includes('/packages/core-utils/')) { return 'pkg-core-utils'; } }, }, }, }, }; });