使用Vue 3+Vite 4构建多页应用时,如何规范资源/Chunk命名?
Vite多页应用构建配置问题:按页面拆分CSS并指定输出结构
场景与需求
使用Vite 4.1.4 + Vue 3.2.45构建多页应用(非库模式),部署在以Razor Pages(cshtml)为入口的ASP.NET Core网站中。需求如下:
- 每个页面/入口构建为包含所有JS和CSS的独立文件夹,允许模块重复
- 理想状态下CSS按页面拆分(与输入文件匹配)并做作用域隔离;若无法实现,需预先指定主CSS输出包名称,避免随Vite自动生成的模块(如
BusyButton)变化
项目src目录结构
├───assets │ /*Assets here*/ ├───components │ /*components here*/ ├───composables │ /*composables here*/ ├───pages │ │ ErrorNotFound.vue | | /* Pages here */ │ ├───Propertylistings │ │ propertylistings.ts │ │ PropertyListings.vue │ ├───Tasks │ │ tasks.ts │ │ Tasks.vue │ │ TasksDetail.vue │ │ TasksGrid.vue │ └───Users │ users.ts │ Users.vue │ UsersDetail.vue │ UsersGrid.vue ├───router │ taskRouter.ts │ userRouter.ts | /* Others here*/ ├───services │ │ Services.ts │ └───api │ Api.ts └───viewmodels TaskDTO.ts UserDTO.ts /* etc */
当前Vite配置
import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' import { fileURLToPath, URL } from 'url' import glob from 'glob'; import path from 'node:path'; var inputFiles = (glob.globSync('src/pages/**/*.ts')).map(file => [ // 移除`src/`前缀和文件扩展名,例如src/nested/foo.js变为nested/foo path.relative( 'src', file.slice(0, file.length - path.extname(file).length) ), // 将相对路径转为绝对路径,例如src/nested/foo变为/project/src/nested/foo.js fileURLToPath(new URL(file, import.meta.url)) ]); const outputDir = "../wwwroot/client"; export default defineConfig({ plugins: [ vue() ], build: { outDir: outputDir, emptyOutDir: true, manifest: "manifest.json", sourcemap: true, cssCodeSplit: false, /* 生成单个样式文件 */ rollupOptions: { input: Object.fromEntries(inputFiles), output: { format: "es", sourcemap: true, exports: 'named', assetFileNames: (assetInfo) => { console.log("AssertInfo %s, %s", assetInfo.name, assetInfo.type) let extType = assetInfo.name.split('.').pop(); if (/png|jpe?g|svg|gif|tiff|bmp|ico/i.test(extType)) { extType = 'img'; } return `assets/[name]-[hash][extname]`; }, }, } }, resolve: { alias: { '@': fileURLToPath(new URL('./src', import.meta.url)) } }, server: { /*开发环境代理配置 */ } })
当前构建输出结构
│ manifest.json │ └───assets │ BusyButton-e579a0b5.js /* 该名称随机生成,BusyButton是被多组件引用的自定义组件 */ │ BusyButton-e579a0b5.js.map │ ErrorNotFound-a6c93dbd.js │ ErrorNotFound-a6c93dbd.js.map │ style-341893d8.css /* 需要按页面拆分并正确命名 */ │ _plugin-vue_export-helper-175348a6.js │ _plugin-vue_export-helper-175348a6.js.map │ └───pages ├───Propertylistings │ propertylistings-4859e993.js │ propertylistings-4859e993.js.map │ ├───Tasks │ tasks-a58b1702.js │ tasks-a58b1702.js.map │ └───Users users-0e4c54f0.js users-0e4c54f0.js.map
现存问题
BusyButton作为被多组件引用的自定义组件,被随机选为了主输出文件名,导致输出文件命名不可控- 开启
cssCodeSplit: false时生成单个style-xxx.css文件;移除该选项后,CSS文件会被命名为BusyButton-xxx.css,均无法按页面拆分 - 无法实现每个页面入口对应独立的CSS文件,输出结构不符合预期
期望输出结构
└───pages ├───Propertylistings | propertylistings-4859e993.css /* 每个页面入口对应独立CSS文件 */ │ propertylistings-4859e993.js │ propertylistings-4859e993.js.map │ ├───Tasks | tasks-a58b1702.css /* 每个页面入口对应独立CSS文件 */ │ tasks-a58b1702.js │ tasks-a58b1702.js.map │ └───Users users-0e4c54f0.css /* 每个页面入口对应独立CSS文件 */ users-0e4c54f0.js users-0e4c54f0.js.map
内容的提问来源于stack exchange,提问作者Jonathan Counihan
相关产品推荐
相关产品推荐

