From b3a7842610c51aa48cedcf285b40590618a09e0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lubom=C3=ADr=20Bla=C5=BEek?= Date: Wed, 26 Jan 2022 20:09:39 +0100 Subject: [PATCH 01/10] feat(dev): added assets to manifest --- packages/vite/src/node/plugins/manifest.ts | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/packages/vite/src/node/plugins/manifest.ts b/packages/vite/src/node/plugins/manifest.ts index 2ce4869e67d98d..c8b83156922d39 100644 --- a/packages/vite/src/node/plugins/manifest.ts +++ b/packages/vite/src/node/plugins/manifest.ts @@ -1,5 +1,5 @@ import path from 'path' -import type { OutputChunk } from 'rollup' +import type { OutputChunk, OutputAsset } from 'rollup' import type { ResolvedConfig } from '..' import type { Plugin } from '../plugin' import { chunkToEmittedCssFileMap } from './css' @@ -101,10 +101,18 @@ export function manifestPlugin(config: ResolvedConfig): Plugin { return manifestChunk } + function createAsset(chunk: OutputAsset): ManifestChunk { + return { + file: chunk.fileName + } + } + for (const file in bundle) { const chunk = bundle[file] if (chunk.type === 'chunk') { manifest[getChunkName(chunk)] = createChunk(chunk) + } else if (chunk.type === 'asset' && typeof chunk.name === 'string') { + manifest[chunk.name] = createAsset(chunk) } } From 80e71397e578c8dd52dde9aff17fb8aefe76799a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lubom=C3=ADr=20Bla=C5=BEek?= Date: Tue, 15 Mar 2022 15:07:52 +0100 Subject: [PATCH 02/10] feat: added backend-integration assets manifest tests --- .../backend-integration/__tests__/backend-integration.spec.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/playground/backend-integration/__tests__/backend-integration.spec.ts b/packages/playground/backend-integration/__tests__/backend-integration.spec.ts index 3e189972f4baed..42513a682eabb9 100644 --- a/packages/playground/backend-integration/__tests__/backend-integration.spec.ts +++ b/packages/playground/backend-integration/__tests__/backend-integration.spec.ts @@ -28,8 +28,12 @@ if (isBuild) { test('manifest', async () => { const manifest = readManifest('dev') const htmlEntry = manifest['index.html'] + const cssAssetEntry = manifest['global.css.css'] + const imgAssetEntry = manifest['../images/logo.png'] expect(htmlEntry.css.length).toEqual(1) expect(htmlEntry.assets.length).toEqual(1) + expect(cssAssetEntry?.file).not.toBeUndefined() + expect(imgAssetEntry?.file).not.toBeUndefined() }) } else { describe('CSS HMR', () => { From 7fd58ea36ef5dc7ba3c5611545114fdeeb9d337e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lubom=C3=ADr=20Bla=C5=BEek?= Date: Sat, 28 May 2022 16:38:02 +0200 Subject: [PATCH 03/10] fix: merge file remnant --- .../__tests__/backend-integration.spec.ts | 63 ------------------- 1 file changed, 63 deletions(-) delete mode 100644 packages/playground/backend-integration/__tests__/backend-integration.spec.ts diff --git a/packages/playground/backend-integration/__tests__/backend-integration.spec.ts b/packages/playground/backend-integration/__tests__/backend-integration.spec.ts deleted file mode 100644 index 42513a682eabb9..00000000000000 --- a/packages/playground/backend-integration/__tests__/backend-integration.spec.ts +++ /dev/null @@ -1,63 +0,0 @@ -import { - editFile, - getColor, - isBuild, - readManifest, - untilUpdated -} from '../../testUtils' - -const outerAssetMatch = isBuild - ? /\/dev\/assets\/logo\.\w{8}\.png/ - : /\/dev\/@fs\/.+?\/images\/logo\.png/ - -test('should have no 404s', () => { - browserLogs.forEach((msg) => { - expect(msg).not.toMatch('404') - }) -}) - -describe('asset imports from js', () => { - test('file outside root', async () => { - expect( - await page.textContent('.asset-reference.outside-root .asset-url') - ).toMatch(outerAssetMatch) - }) -}) - -if (isBuild) { - test('manifest', async () => { - const manifest = readManifest('dev') - const htmlEntry = manifest['index.html'] - const cssAssetEntry = manifest['global.css.css'] - const imgAssetEntry = manifest['../images/logo.png'] - expect(htmlEntry.css.length).toEqual(1) - expect(htmlEntry.assets.length).toEqual(1) - expect(cssAssetEntry?.file).not.toBeUndefined() - expect(imgAssetEntry?.file).not.toBeUndefined() - }) -} else { - describe('CSS HMR', () => { - test('preserve the base in CSS HMR', async () => { - await untilUpdated(() => getColor('body'), 'black') // sanity check - editFile('frontend/entrypoints/global.css', (code) => - code.replace('black', 'red') - ) - await untilUpdated(() => getColor('body'), 'red') // successful HMR - - // Verify that the base (/dev/) was added during the css-update - const link = await page.$('link[rel="stylesheet"]') - expect(await link.getAttribute('href')).toContain('/dev/global.css?t=') - }) - - test('CSS dependencies are tracked for HMR', async () => { - const el = await page.$('h1') - browserLogs.length = 0 - - editFile('frontend/entrypoints/main.ts', (code) => - code.replace('text-black', 'text-[rgb(204,0,0)]') - ) - await untilUpdated(() => getColor(el), 'rgb(204, 0, 0)') - expect(browserLogs).toContain('[vite] css hot updated: /global.css') - }) - }) -} From 5e5e97025689cdb7eb394224a36075008c204ab2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lubom=C3=ADr=20Bla=C5=BEek?= Date: Sat, 28 May 2022 16:52:01 +0200 Subject: [PATCH 04/10] fix: lint error --- packages/vite/src/node/plugins/manifest.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/vite/src/node/plugins/manifest.ts b/packages/vite/src/node/plugins/manifest.ts index 331f33b24f3b01..443f66454b5b43 100644 --- a/packages/vite/src/node/plugins/manifest.ts +++ b/packages/vite/src/node/plugins/manifest.ts @@ -1,5 +1,5 @@ import path from 'path' -import type { OutputChunk, OutputAsset } from 'rollup' +import type { OutputAsset, OutputChunk } from 'rollup' import type { ResolvedConfig } from '..' import type { Plugin } from '../plugin' import { normalizePath } from '../utils' From af2ec794a42139d4b6a6d69bdfe7c25fe9aed83f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lubom=C3=ADr=20Bla=C5=BEek?= Date: Sat, 28 May 2022 17:01:36 +0200 Subject: [PATCH 05/10] feat: added src to assets manifest --- packages/vite/src/node/plugins/manifest.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/vite/src/node/plugins/manifest.ts b/packages/vite/src/node/plugins/manifest.ts index 443f66454b5b43..b496caf4dbae96 100644 --- a/packages/vite/src/node/plugins/manifest.ts +++ b/packages/vite/src/node/plugins/manifest.ts @@ -101,7 +101,8 @@ export function manifestPlugin(config: ResolvedConfig): Plugin { function createAsset(chunk: OutputAsset): ManifestChunk { return { - file: chunk.fileName + file: chunk.fileName, + src: chunk.name } } From 22d33c8ff01f25595bf12ef679d734dd71da5125 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lubom=C3=ADr=20Bla=C5=BEek?= Date: Thu, 9 Jun 2022 10:01:09 +0200 Subject: [PATCH 06/10] fix: css asset path --- packages/vite/src/node/plugins/css.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/vite/src/node/plugins/css.ts b/packages/vite/src/node/plugins/css.ts index 45ff0525b1042d..528e7f0c438e19 100644 --- a/packages/vite/src/node/plugins/css.ts +++ b/packages/vite/src/node/plugins/css.ts @@ -505,7 +505,9 @@ export function cssPostPlugin(config: ResolvedConfig): Plugin { // emit corresponding css file const fileHandle = this.emitFile({ - name: cssAssetName, + name: chunk.facadeModuleId + ? normalizePath(path.relative(config.root, chunk.facadeModuleId)) + : cssAssetName, type: 'asset', source: chunkCSS }) From 1919d04724f96f3b1a188c0b00ebcc1ba8989754 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lubom=C3=ADr=20Bla=C5=BEek?= Date: Thu, 9 Jun 2022 10:12:27 +0200 Subject: [PATCH 07/10] fix(tests): css entry --- .../backend-integration/__tests__/backend-integration.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/playground/backend-integration/__tests__/backend-integration.spec.ts b/playground/backend-integration/__tests__/backend-integration.spec.ts index e0339b5778b422..fb135eed2e873b 100644 --- a/playground/backend-integration/__tests__/backend-integration.spec.ts +++ b/playground/backend-integration/__tests__/backend-integration.spec.ts @@ -32,7 +32,7 @@ describe.runIf(isBuild)('build', () => { test('manifest', async () => { const manifest = readManifest('dev') const htmlEntry = manifest['index.html'] - const cssAssetEntry = manifest['global.css.css'] + const cssAssetEntry = manifest['global.css'] const imgAssetEntry = manifest['../images/logo.png'] expect(htmlEntry.css.length).toEqual(1) expect(htmlEntry.assets.length).toEqual(1) From fabc52b2ed766c8d99502bcc3ae5b062460aec34 Mon Sep 17 00:00:00 2001 From: Jess Archer Date: Fri, 10 Jun 2022 13:03:38 +1000 Subject: [PATCH 08/10] fix: css extension --- packages/vite/src/node/plugins/css.ts | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/packages/vite/src/node/plugins/css.ts b/packages/vite/src/node/plugins/css.ts index 528e7f0c438e19..cca82e703fc69c 100644 --- a/packages/vite/src/node/plugins/css.ts +++ b/packages/vite/src/node/plugins/css.ts @@ -488,6 +488,10 @@ export function cssPostPlugin(config: ResolvedConfig): Plugin { return chunkCSS } + function ensureFileExt(name: string, ext: string) { + return path.format({ ...path.parse(name), base: undefined, ext }) + } + if (config.build.cssCodeSplit) { if (isPureCssChunk) { // this is a shared CSS-only chunk that is empty. @@ -498,16 +502,19 @@ export function cssPostPlugin(config: ResolvedConfig): Plugin { opts.format === 'cjs' || opts.format === 'system' ) { - const cssAssetName = chunk.name + '.css' + const cssAssetName = ensureFileExt( + chunk.facadeModuleId + ? normalizePath(path.relative(config.root, chunk.facadeModuleId)) + : chunk.name, + '.css' + ) chunkCSS = resolveAssetUrlsInCss(chunkCSS, cssAssetName) chunkCSS = await finalizeCss(chunkCSS, true, config) // emit corresponding css file const fileHandle = this.emitFile({ - name: chunk.facadeModuleId - ? normalizePath(path.relative(config.root, chunk.facadeModuleId)) - : cssAssetName, + name: cssAssetName, type: 'asset', source: chunkCSS }) From 3147b88ff2afdd60c9b916f31b7a6b12f07d00cf Mon Sep 17 00:00:00 2001 From: Jess Archer Date: Fri, 10 Jun 2022 15:24:54 +1000 Subject: [PATCH 09/10] fix: css build path --- packages/vite/src/node/plugins/css.ts | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/packages/vite/src/node/plugins/css.ts b/packages/vite/src/node/plugins/css.ts index cca82e703fc69c..0de5be7a371fed 100644 --- a/packages/vite/src/node/plugins/css.ts +++ b/packages/vite/src/node/plugins/css.ts @@ -47,6 +47,7 @@ import { import type { Logger } from '../logger' import { addToHTMLProxyTransformResult } from './html' import { + assetFileNamesToFileName, assetUrlRE, checkPublicFile, fileToUrl, @@ -512,9 +513,24 @@ export function cssPostPlugin(config: ResolvedConfig): Plugin { chunkCSS = resolveAssetUrlsInCss(chunkCSS, cssAssetName) chunkCSS = await finalizeCss(chunkCSS, true, config) + const output = config.build?.rollupOptions?.output + const assetFileNames = + (output && !Array.isArray(output) + ? output.assetFileNames + : undefined) ?? + // defaults to '/[name].[hash][extname]' + // slightly different from rollup's one ('assets/[name]-[hash][extname]') + path.posix.join(config.build.assetsDir, '[name].[hash][extname]') + // emit corresponding css file const fileHandle = this.emitFile({ name: cssAssetName, + fileName: assetFileNamesToFileName( + assetFileNames, + cssAssetName, + getHash(chunkCSS), + chunkCSS + ), type: 'asset', source: chunkCSS }) From 9773d4edeaeddfcc2f12b93671668538450558c4 Mon Sep 17 00:00:00 2001 From: patak-dev Date: Sun, 19 Jun 2022 08:32:00 +0200 Subject: [PATCH 10/10] fix: abstract resolveAssetFileNames, support legacy plugin with custom assetFileNames --- packages/vite/src/node/plugins/asset.ts | 41 ++++++++++++++----------- packages/vite/src/node/plugins/css.ts | 14 ++------- 2 files changed, 26 insertions(+), 29 deletions(-) diff --git a/packages/vite/src/node/plugins/asset.ts b/packages/vite/src/node/plugins/asset.ts index 2a119808a4eb72..8f1f3516c36387 100644 --- a/packages/vite/src/node/plugins/asset.ts +++ b/packages/vite/src/node/plugins/asset.ts @@ -2,7 +2,7 @@ import path from 'path' import { parse as parseUrl } from 'url' import fs, { promises as fsp } from 'fs' import * as mrmime from 'mrmime' -import type { OutputOptions, PluginContext } from 'rollup' +import type { OutputOptions, PluginContext, PreRenderedAsset } from 'rollup' import MagicString from 'magic-string' import type { Plugin } from '../plugin' import type { ResolvedConfig } from '../config' @@ -217,6 +217,27 @@ export function getAssetFilename( return assetHashToFilenameMap.get(config)?.get(hash) } +export function resolveAssetFileNames( + config: ResolvedConfig +): string | ((chunkInfo: PreRenderedAsset) => string) { + const output = config.build?.rollupOptions?.output + const defaultAssetFileNames = path.posix.join( + config.build.assetsDir, + '[name].[hash][extname]' + ) + // Steps to determine which assetFileNames will be actually used. + // First, if output is an object or string, use assetFileNames in it. + // And a default assetFileNames as fallback. + let assetFileNames: Exclude = + (output && !Array.isArray(output) ? output.assetFileNames : undefined) ?? + defaultAssetFileNames + if (output && Array.isArray(output)) { + // Second, if output is an array, adopt assetFileNames in the first object. + assetFileNames = output[0].assetFileNames ?? assetFileNames + } + return assetFileNames +} + /** * converts the source filepath of the asset to the output filename based on the assetFileNames option. \ * this function imitates the behavior of rollup.js. \ @@ -364,25 +385,9 @@ async function fileToBuiltUrl( const contentHash = getHash(content) const { search, hash } = parseUrl(id) const postfix = (search || '') + (hash || '') - const output = config.build?.rollupOptions?.output - - const defaultAssetFileNames = path.posix.join( - config.build.assetsDir, - '[name].[hash][extname]' - ) - // Steps to determine which assetFileNames will be actually used. - // First, if output is an object or string, use assetFileNames in it. - // And a default assetFileNames as fallback. - let assetFileNames: Exclude = - (output && !Array.isArray(output) ? output.assetFileNames : undefined) ?? - defaultAssetFileNames - if (output && Array.isArray(output)) { - // Second, if output is an array, adopt assetFileNames in the first object. - assetFileNames = output[0].assetFileNames ?? assetFileNames - } const fileName = assetFileNamesToFileName( - assetFileNames, + resolveAssetFileNames(config), file, contentHash, content diff --git a/packages/vite/src/node/plugins/css.ts b/packages/vite/src/node/plugins/css.ts index d3239974cb3cf5..0d057fa4750238 100644 --- a/packages/vite/src/node/plugins/css.ts +++ b/packages/vite/src/node/plugins/css.ts @@ -53,7 +53,8 @@ import { getAssetFilename, publicAssetUrlCache, publicAssetUrlRE, - publicFileToBuiltUrl + publicFileToBuiltUrl, + resolveAssetFileNames } from './asset' // const debug = createDebugger('vite:css') @@ -508,20 +509,11 @@ export function cssPostPlugin(config: ResolvedConfig): Plugin { chunkCSS = resolveAssetUrlsInCss(chunkCSS, cssAssetName) chunkCSS = await finalizeCss(chunkCSS, true, config) - const output = config.build?.rollupOptions?.output - const assetFileNames = - (output && !Array.isArray(output) - ? output.assetFileNames - : undefined) ?? - // defaults to '/[name].[hash][extname]' - // slightly different from rollup's one ('assets/[name]-[hash][extname]') - path.posix.join(config.build.assetsDir, '[name].[hash][extname]') - // emit corresponding css file const fileHandle = this.emitFile({ name: cssAssetName, fileName: assetFileNamesToFileName( - assetFileNames, + resolveAssetFileNames(config), cssAssetName, getHash(chunkCSS), chunkCSS