Skip to content

Commit

Permalink
feat: accept assets to be specified as input (#16087)
Browse files Browse the repository at this point in the history
  • Loading branch information
sapphi-red authored Mar 12, 2024
1 parent 03b9674 commit 75a9fc6
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 2 deletions.
27 changes: 25 additions & 2 deletions packages/vite/src/node/plugins/asset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,15 @@ export function assetPlugin(config: ResolvedConfig): Plugin {
}
}

return `export default ${JSON.stringify(url)}`
return {
code: `export default ${JSON.stringify(url)}`,
// Force rollup to keep this module from being shared between other entry points if it's an entrypoint.
// If the resulting chunk is empty, it will be removed in generateBundle.
moduleSideEffects:
config.command === 'build' && this.getModuleInfo(id)?.isEntry
? 'no-treeshake'
: false,
}
},

renderChunk(code, chunk, opts) {
Expand All @@ -224,6 +232,19 @@ export function assetPlugin(config: ResolvedConfig): Plugin {
},

generateBundle(_, bundle) {
// Remove empty entry point file
for (const file in bundle) {
const chunk = bundle[file]
if (
chunk.type === 'chunk' &&
chunk.isEntry &&
chunk.moduleIds.length === 1 &&
config.assetsInclude(chunk.moduleIds[0])
) {
delete bundle[file]
}
}

// do not emit assets for SSR build
if (
config.command === 'build' &&
Expand Down Expand Up @@ -340,7 +361,7 @@ async function fileToBuiltUrl(
const content = await fsp.readFile(file)

let url: string
if (shouldInline(config, file, id, content, forceInline)) {
if (shouldInline(config, file, id, content, pluginContext, forceInline)) {
if (config.build.lib && isGitLfsPlaceholder(content)) {
config.logger.warn(
colors.yellow(`Inlined file ${id} was not downloaded via Git LFS`),
Expand Down Expand Up @@ -405,9 +426,11 @@ const shouldInline = (
file: string,
id: string,
content: Buffer,
pluginContext: PluginContext,
forceInline: boolean | undefined,
): boolean => {
if (config.build.lib) return true
if (pluginContext.getModuleInfo(id)?.isEntry) return false
if (forceInline !== undefined) return forceInline
let limit: number
if (typeof config.build.assetsInlineLimit === 'function') {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@ import {
getColor,
isBuild,
isServe,
listAssets,
page,
readManifest,
serverLogs,
untilBrowserLogAfter,
untilUpdated,
} from '~utils'
Expand Down Expand Up @@ -39,6 +41,7 @@ describe.runIf(isBuild)('build', () => {
const scssAssetEntry = manifest['nested/blue.scss']
const imgAssetEntry = manifest['../images/logo.png']
const dirFooAssetEntry = manifest['../../dir/foo.css']
const iconEntrypointEntry = manifest['icon.png']
expect(htmlEntry.css.length).toEqual(1)
expect(htmlEntry.assets.length).toEqual(1)
expect(cssAssetEntry?.file).not.toBeUndefined()
Expand All @@ -53,6 +56,7 @@ describe.runIf(isBuild)('build', () => {
expect(dirFooAssetEntry).not.toBeUndefined() // '\\' should not be used even on windows
// use the entry name
expect(dirFooAssetEntry.file).toMatch('assets/bar-')
expect(iconEntrypointEntry?.file).not.toBeUndefined()
})

test('CSS imported from JS entry should have a non-nested chunk name', () => {
Expand All @@ -61,6 +65,17 @@ describe.runIf(isBuild)('build', () => {
expect(mainTsEntryCss.length).toBe(1)
expect(mainTsEntryCss[0].replace('assets/', '')).not.toContain('/')
})

test('entrypoint assets should not generate empty JS file', () => {
expect(serverLogs).not.toContainEqual(
'Generated an empty chunk: "icon.png".',
)

const assets = listAssets('dev')
expect(assets).not.toContainEqual(
expect.stringMatching(/icon.png-[-\w]{8}\.js$/),
)
})
})

describe.runIf(isServe)('serve', () => {
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 75a9fc6

Please sign in to comment.