From 64d7c3ba54ed2dceabcc1cb65634381d7b42ce47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=83=BD=E5=AE=81?= Date: Sun, 16 Jul 2023 17:00:39 +0800 Subject: [PATCH] feat(build): support custom `assetsDir` (#2497) --- docs/reference/site-config.md | 13 +++++++++++++ src/client/app/utils.ts | 5 ++++- src/client/shim.d.ts | 1 + src/node/build/bundle.ts | 8 ++++---- src/node/build/render.ts | 2 +- src/node/config.ts | 4 ++++ src/node/plugin.ts | 3 ++- src/node/serve/serve.ts | 3 ++- src/node/siteConfig.ts | 2 ++ 9 files changed, 33 insertions(+), 8 deletions(-) diff --git a/docs/reference/site-config.md b/docs/reference/site-config.md index 0f020e8a..73fa8953 100644 --- a/docs/reference/site-config.md +++ b/docs/reference/site-config.md @@ -290,6 +290,19 @@ export default { } ``` +### assetsDir + +- Type: `string` +- Default: `assets` + +The directory for assets files. See also: [assetsDir](https://vitejs.dev/config/build-options.html#build-assetsdir). + +```ts +export default { + assetsDir: 'static' +} +``` + ### cacheDir - Type: `string` diff --git a/src/client/app/utils.ts b/src/client/app/utils.ts index a399609b..9a5fb483 100644 --- a/src/client/app/utils.ts +++ b/src/client/app/utils.ts @@ -58,7 +58,10 @@ export function pathToFile(path: string) { pageHash = __VP_HASH_MAP__[pagePath.toLowerCase()] } if (!pageHash) return null - pagePath = `${base}assets/${pagePath}.${pageHash}.js` + pagePath = `${base}${__ASSETS_DIR__.replace( + /"(.+)"/, + '$1' + )}/${pagePath}.${pageHash}.js` } else { // ssr build uses much simpler name mapping pagePath = `./${sanitizeFileName( diff --git a/src/client/shim.d.ts b/src/client/shim.d.ts index 6817bb42..b53e8ab2 100644 --- a/src/client/shim.d.ts +++ b/src/client/shim.d.ts @@ -3,6 +3,7 @@ declare const __VP_LOCAL_SEARCH__: boolean declare const __ALGOLIA__: boolean declare const __CARBON__: boolean declare const __VUE_PROD_DEVTOOLS__: boolean +declare const __ASSETS_DIR__: string declare module '*.vue' { import type { DefineComponent } from 'vue' diff --git a/src/node/build/bundle.ts b/src/node/build/bundle.ts index fda61462..93a4d620 100644 --- a/src/node/build/bundle.ts +++ b/src/node/build/bundle.ts @@ -94,19 +94,19 @@ export async function bundle( output: { sanitizeFileName, ...rollupOptions?.output, - assetFileNames: 'assets/[name].[hash].[ext]', + assetFileNames: `${config.assetsDir}/[name].[hash].[ext]`, ...(ssr ? { entryFileNames: '[name].js', chunkFileNames: '[name].[hash].js' } : { - entryFileNames: 'assets/[name].[hash].js', + entryFileNames: `${config.assetsDir}/[name].[hash].js`, chunkFileNames(chunk) { // avoid ads chunk being intercepted by adblock return /(?:Carbon|BuySell)Ads/.test(chunk.name) - ? 'assets/chunks/ui-custom.[hash].js' - : 'assets/chunks/[name].[hash].js' + ? `${config.assetsDir}/chunks/ui-custom.[hash].js` + : `${config.assetsDir}/chunks/[name].[hash].js` }, manualChunks(id, ctx) { if (lazyDefaultThemeComponentsRE.test(id)) { diff --git a/src/node/build/render.ts b/src/node/build/render.ts index cfe3bf36..e391ed39 100644 --- a/src/node/build/render.ts +++ b/src/node/build/render.ts @@ -46,7 +46,7 @@ export async function renderPage( // for any initial page load, we only need the lean version of the page js // since the static content is already on the page! const pageHash = pageToHashMap[pageName.toLowerCase()] - const pageClientJsFileName = `assets/${pageName}.${pageHash}.lean.js` + const pageClientJsFileName = `${config.assetsDir}/${pageName}.${pageHash}.lean.js` let pageData: PageData let hasCustom404 = true diff --git a/src/node/config.ts b/src/node/config.ts index 04ef1b18..bb187a9c 100644 --- a/src/node/config.ts +++ b/src/node/config.ts @@ -73,6 +73,9 @@ export async function resolveConfig( }) const site = await resolveSiteData(root, userConfig) const srcDir = normalizePath(path.resolve(root, userConfig.srcDir || '.')) + const assetsDir = userConfig.assetsDir + ? userConfig.assetsDir.replace(/\//g, '') + : 'assets' const outDir = userConfig.outDir ? normalizePath(path.resolve(root, userConfig.outDir)) : resolve(root, 'dist') @@ -94,6 +97,7 @@ export async function resolveConfig( const config: SiteConfig = { root, srcDir, + assetsDir, site, themeDir, pages, diff --git a/src/node/plugin.ts b/src/node/plugin.ts index 748f8b8e..7b149ceb 100644 --- a/src/node/plugin.ts +++ b/src/node/plugin.ts @@ -129,7 +129,8 @@ export async function createVitePressPlugin( __ALGOLIA__: site.themeConfig?.search?.provider === 'algolia' || !!site.themeConfig?.algolia, // legacy - __CARBON__: !!site.themeConfig?.carbonAds + __CARBON__: !!site.themeConfig?.carbonAds, + __ASSETS_DIR__: JSON.stringify(siteConfig.assetsDir) }, optimizeDeps: { // force include vue to avoid duplicated copies when linked + optimized diff --git a/src/node/serve/serve.ts b/src/node/serve/serve.ts index e6843676..e2434e90 100644 --- a/src/node/serve/serve.ts +++ b/src/node/serve/serve.ts @@ -28,7 +28,8 @@ export async function serve(options: ServeOptions = {}) { const config = await resolveConfig(options.root, 'serve', 'production') const base = trimChar(options?.base ?? config?.site?.base ?? '', '/') - const notAnAsset = (pathname: string) => !pathname.includes('/assets/') + const notAnAsset = (pathname: string) => + !pathname.includes(`/${config.assetsDir}/`) const notFound = fs.readFileSync(path.resolve(config.outDir, './404.html')) const onNoMatch: IOptions['onNoMatch'] = (req, res) => { res.statusCode = 404 diff --git a/src/node/siteConfig.ts b/src/node/siteConfig.ts index bbc7f6bb..152eca1e 100644 --- a/src/node/siteConfig.ts +++ b/src/node/siteConfig.ts @@ -59,6 +59,7 @@ export interface UserConfig srcDir?: string srcExclude?: string[] outDir?: string + assetsDir?: string cacheDir?: string shouldPreload?: (link: string, page: string) => boolean @@ -192,6 +193,7 @@ export interface SiteConfig configDeps: string[] themeDir: string outDir: string + assetsDir: string cacheDir: string tempDir: string pages: string[]