refactor(vite): 提取 rollup 配置到独立文件
This commit is contained in:
102
vite.config.rollup.output.ts
Normal file
102
vite.config.rollup.output.ts
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
import type { ManualChunkMeta, PreRenderedAsset, RollupOptions } from 'rollup';
|
||||||
|
|
||||||
|
import path from 'node:path';
|
||||||
|
|
||||||
|
// https://www.npmjs.com/package/utils4u/v/2.19.2?activeTab=code
|
||||||
|
|
||||||
|
export const viteConfigRollupOptions: RollupOptions = {
|
||||||
|
/* onwarn: (warning, warn) => {
|
||||||
|
if (warning.code === 'EMPTY_BUNDLE') return;
|
||||||
|
if (warning.code === 'EVAL' && warning.id?.includes('node_modules/eruda')) return;
|
||||||
|
if (warning.code === 'EVAL' && warning.id?.includes('node_modules/mockjs')) return;
|
||||||
|
if (warning.code === 'EVAL' && warning.id?.includes('node_modules/protobufjs')) return;
|
||||||
|
warn(warning);
|
||||||
|
}, */
|
||||||
|
|
||||||
|
output: {
|
||||||
|
// Keep hashed file names predictable across entry, chunk, and asset outputs.
|
||||||
|
entryFileNames: 'entry/[name].[hash].js', // 默认: "[name].js"
|
||||||
|
chunkFileNames: 'chunk/[name].[hash].js', // 默认: "[name]-[hash].js"
|
||||||
|
// assetFileNames:'', // 默认: "assets/[name]-[hash][extname]"
|
||||||
|
// https://cn.rollupjs.org/configuration-options/#output-assetfilenames
|
||||||
|
assetFileNames(chunkInfo: PreRenderedAsset) {
|
||||||
|
const names = chunkInfo.names;
|
||||||
|
|
||||||
|
if (names.length !== 1) {
|
||||||
|
console.error('Multiple names for asset:', chunkInfo);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
const assetName = names[0];
|
||||||
|
const ext = assetName.split('.').pop()?.toLowerCase();
|
||||||
|
if (ext && /png|jpe?g|gif|svg|webp|avif/.test(ext)) {
|
||||||
|
return 'chunks/images/[name].[hash][extname]';
|
||||||
|
}
|
||||||
|
if (ext && /woff2?|ttf|otf/.test(ext)) {
|
||||||
|
return 'chunks/fonts/[name].[hash][extname]';
|
||||||
|
}
|
||||||
|
if (ext === 'css') {
|
||||||
|
return 'chunks/css/[name].[hash][extname]';
|
||||||
|
}
|
||||||
|
return '_chunks/[name].[hash][extname]';
|
||||||
|
},
|
||||||
|
|
||||||
|
manualChunks: (id: string, _meta: ManualChunkMeta) => {
|
||||||
|
/* 有一个问题: dynamic import will not move module into another chunk.
|
||||||
|
if (['/src/layouts'].some((prefix) => id.includes(prefix))) {
|
||||||
|
return 'layouts';
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (id.includes('index.page.vue')) {
|
||||||
|
const parentDir = path.basename(path.dirname(id));
|
||||||
|
return `${parentDir}-index.page`;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!id.includes('node_modules')) return;
|
||||||
|
// 处理 pnpm 的特殊路径结构
|
||||||
|
let packageName;
|
||||||
|
if (id.includes('.pnpm')) {
|
||||||
|
// pnpm 路径: .pnpm/naive-ui@2.43.1_vue@3.5.22/node_modules/naive-ui/...
|
||||||
|
const pnpmMatch = id.match(/\.pnpm\/(.+?)@/);
|
||||||
|
if (pnpmMatch) {
|
||||||
|
packageName = pnpmMatch[1];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 普通路径: node_modules/lodash/...
|
||||||
|
const normalMatch = id.match(/node_modules\/(@[^/]+\/[^/]+|[^/]+)\//);
|
||||||
|
if (normalMatch) {
|
||||||
|
packageName = normalMatch[1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (packageName) {
|
||||||
|
if (['highlight.js'].includes(packageName)) {
|
||||||
|
return 'lib-hljs';
|
||||||
|
}
|
||||||
|
|
||||||
|
// 根据包名分组
|
||||||
|
if (['consola', 'lodash', '@juggle+resize-observer', 'vueuc'].includes(packageName)) {
|
||||||
|
return 'lib-vendor';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (['naive-ui'].includes(packageName) && id.includes('_internal')) {
|
||||||
|
console.debug(`id :>> `, id);
|
||||||
|
return 'lib-naive-ui-internal';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (['naive-ui'].includes(packageName)) {
|
||||||
|
return 'lib-naive-ui';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (['primelocale', 'primevue', '@primeuix'].some((name) => packageName!.includes(name))) {
|
||||||
|
return 'lib-primevue';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (['vue', 'vue-router', 'pinia', 'vue-demi', 'vue-i18n'].includes(packageName)) {
|
||||||
|
return 'lib-vue-vendor';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
import consola from 'consola';
|
import consola from 'consola';
|
||||||
import path from 'node:path';
|
import path from 'node:path';
|
||||||
import { fileURLToPath, pathToFileURL, URL } from 'node:url';
|
import { fileURLToPath, pathToFileURL, URL } from 'node:url';
|
||||||
import type { ManualChunkMeta, PreRenderedAsset } from 'rollup';
|
|
||||||
import { glob } from 'tinyglobby';
|
import { glob } from 'tinyglobby';
|
||||||
import { createViteProxy } from 'utils4u/vite';
|
import { createViteProxy } from 'utils4u/vite';
|
||||||
import { defineConfig, loadEnv, type ConfigEnv, type PluginOption } from 'vite';
|
import { defineConfig, loadEnv, type ConfigEnv, type PluginOption } from 'vite';
|
||||||
import { optimizeDeps } from './vite.config.optimizeDeps';
|
import { optimizeDeps } from './vite.config.optimizeDeps';
|
||||||
|
import { viteConfigRollupOptions } from './vite.config.rollup.output';
|
||||||
|
|
||||||
type LoadPluginFunction = (configEnv: ConfigEnv) => PluginOption;
|
type LoadPluginFunction = (configEnv: ConfigEnv) => PluginOption;
|
||||||
async function loadPlugins(configEnv: ConfigEnv): Promise<PluginOption[]> {
|
async function loadPlugins(configEnv: ConfigEnv): Promise<PluginOption[]> {
|
||||||
@@ -82,97 +82,7 @@ export default defineConfig(async (configEnv) => {
|
|||||||
minify: env.VITE_APP_BUILD_MINIFY === 'true' ? undefined /* 即默认 */ : false, // 默认: 'terser'
|
minify: env.VITE_APP_BUILD_MINIFY === 'true' ? undefined /* 即默认 */ : false, // 默认: 'terser'
|
||||||
|
|
||||||
sourcemap: env.VITE_APP_BUILD_SOURCE_MAP === 'true',
|
sourcemap: env.VITE_APP_BUILD_SOURCE_MAP === 'true',
|
||||||
rollupOptions: {
|
rollupOptions: viteConfigRollupOptions,
|
||||||
/* onwarn: (warning, warn) => {
|
|
||||||
if (warning.code === 'EMPTY_BUNDLE') return;
|
|
||||||
if (warning.code === 'EVAL' && warning.id?.includes('node_modules/eruda')) return;
|
|
||||||
if (warning.code === 'EVAL' && warning.id?.includes('node_modules/mockjs')) return;
|
|
||||||
if (warning.code === 'EVAL' && warning.id?.includes('node_modules/protobufjs')) return;
|
|
||||||
warn(warning);
|
|
||||||
}, */
|
|
||||||
|
|
||||||
output: {
|
|
||||||
// Keep hashed file names predictable across entry, chunk, and asset outputs.
|
|
||||||
entryFileNames: 'entry/[name].[hash].js', // 默认: "[name].js"
|
|
||||||
chunkFileNames: 'chunk/[name].[hash].js', // 默认: "[name]-[hash].js"
|
|
||||||
// assetFileNames:'', // 默认: "assets/[name]-[hash][extname]"
|
|
||||||
// https://cn.rollupjs.org/configuration-options/#output-assetfilenames
|
|
||||||
assetFileNames(chunkInfo: PreRenderedAsset) {
|
|
||||||
const names = chunkInfo.names;
|
|
||||||
|
|
||||||
if (names.length !== 1) {
|
|
||||||
console.error('Multiple names for asset:', chunkInfo);
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
const assetName = names[0];
|
|
||||||
const ext = assetName.split('.').pop()?.toLowerCase();
|
|
||||||
if (ext && /png|jpe?g|gif|svg|webp|avif/.test(ext)) {
|
|
||||||
return 'chunks/images/[name].[hash][extname]';
|
|
||||||
}
|
|
||||||
if (ext && /woff2?|ttf|otf/.test(ext)) {
|
|
||||||
return 'chunks/fonts/[name].[hash][extname]';
|
|
||||||
}
|
|
||||||
if (ext === 'css') {
|
|
||||||
return 'chunks/css/[name].[hash][extname]';
|
|
||||||
}
|
|
||||||
return '_chunks/[name].[hash][extname]';
|
|
||||||
},
|
|
||||||
|
|
||||||
// https://www.npmjs.com/package/utils4u/v/2.19.2?activeTab=code
|
|
||||||
manualChunks: (id: string, _meta: ManualChunkMeta) => {
|
|
||||||
/* 有一个问题: dynamic import will not move module into another chunk.
|
|
||||||
if (['/src/layouts'].some((prefix) => id.includes(prefix))) {
|
|
||||||
return 'layouts';
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (id.includes('index.page.vue')) {
|
|
||||||
const parentDir = path.basename(path.dirname(id));
|
|
||||||
return `${parentDir}-index.page`;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!id.includes('node_modules')) return;
|
|
||||||
// 处理 pnpm 的特殊路径结构
|
|
||||||
let packageName;
|
|
||||||
if (id.includes('.pnpm')) {
|
|
||||||
// pnpm 路径: .pnpm/naive-ui@2.43.1_vue@3.5.22/node_modules/naive-ui/...
|
|
||||||
const pnpmMatch = id.match(/\.pnpm\/(.+?)@/);
|
|
||||||
if (pnpmMatch) {
|
|
||||||
packageName = pnpmMatch[1];
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// 普通路径: node_modules/lodash/...
|
|
||||||
const normalMatch = id.match(/node_modules\/(@[^/]+\/[^/]+|[^/]+)\//);
|
|
||||||
if (normalMatch) {
|
|
||||||
packageName = normalMatch[1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (packageName) {
|
|
||||||
if (['highlight.js'].includes(packageName)) {
|
|
||||||
return 'lib-hljs';
|
|
||||||
}
|
|
||||||
|
|
||||||
// 根据包名分组
|
|
||||||
if (['consola', 'lodash', '@juggle+resize-observer'].includes(packageName)) {
|
|
||||||
return 'lib-vendor';
|
|
||||||
}
|
|
||||||
if (['naive-ui', 'vueuc'].includes(packageName)) {
|
|
||||||
return 'lib-naive-ui';
|
|
||||||
}
|
|
||||||
if (
|
|
||||||
['primelocale', 'primevue', '@primeuix'].some((name) => packageName!.includes(name))
|
|
||||||
) {
|
|
||||||
return 'lib-primevue';
|
|
||||||
}
|
|
||||||
if (['vue', 'vue-router', 'pinia', 'vue-demi', 'vue-i18n'].includes(packageName)) {
|
|
||||||
return 'lib-vue-vendor';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
css: {
|
css: {
|
||||||
devSourcemap: true,
|
devSourcemap: true,
|
||||||
|
|||||||
Reference in New Issue
Block a user