From 96471f8c2be7052c539502107032a6fbcae17587 Mon Sep 17 00:00:00 2001 From: FinalAshen <819712530@qq.com> Date: Sat, 25 Nov 2023 17:23:30 +0800 Subject: [PATCH 1/4] fix: esbuild glob import resolve error --- packages/vite/src/node/optimizer/scan.ts | 38 ++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/packages/vite/src/node/optimizer/scan.ts b/packages/vite/src/node/optimizer/scan.ts index c0d97f480ca9de..3dc9d9ce9b7b37 100644 --- a/packages/vite/src/node/optimizer/scan.ts +++ b/packages/vite/src/node/optimizer/scan.ts @@ -486,6 +486,21 @@ function esbuildScanPlugin( } } + const globImportOnLoadCallback: ( + args: OnLoadArgs, + ) => Promise = async ({ path: p }) => { + const externalLoadResult: OnLoadResult = { + loader: 'js', + contents: '\nexport default {}', + } + if (!entries.includes(p)) { + return externalLoadResult + } + if (SPECIAL_QUERY_RE.test(p)) { + return externalLoadResult + } + } + // extract scripts inside HTML-like files and treat it as a js module build.onLoad( { filter: htmlTypesRE, namespace: 'html' }, @@ -498,6 +513,29 @@ function esbuildScanPlugin( { filter: htmlTypesRE, namespace: 'file' }, htmlTypeOnLoadCallback, ) + // css + build.onLoad( + { filter: CSS_LANGS_RE, namespace: 'file' }, + globImportOnLoadCallback, + ) + // json & wasm + build.onLoad( + { filter: /\.(json|json5|wasm)$/, namespace: 'file' }, + globImportOnLoadCallback, + ) + // known asset types + build.onLoad( + { + filter: new RegExp(`\\.(${KNOWN_ASSET_TYPES.join('|')})$`), + namespace: 'file', + }, + globImportOnLoadCallback, + ) + // known vite query types: ?worker, ?raw + build.onLoad( + { filter: SPECIAL_QUERY_RE, namespace: 'file' }, + globImportOnLoadCallback, + ) // bare imports: record and externalize ---------------------------------- build.onResolve( From 9aee2bc25f824f3f543caa10df73e5733612a35d Mon Sep 17 00:00:00 2001 From: FinalAshen <819712530@qq.com> Date: Wed, 29 Nov 2023 20:58:24 +0800 Subject: [PATCH 2/4] chore: merge onLoad and onResolve callbacks of special resource --- packages/vite/src/node/optimizer/scan.ts | 46 ++++++++++++++---------- 1 file changed, 27 insertions(+), 19 deletions(-) diff --git a/packages/vite/src/node/optimizer/scan.ts b/packages/vite/src/node/optimizer/scan.ts index 3dc9d9ce9b7b37..3b27c32785d233 100644 --- a/packages/vite/src/node/optimizer/scan.ts +++ b/packages/vite/src/node/optimizer/scan.ts @@ -8,6 +8,8 @@ import type { Loader, OnLoadArgs, OnLoadResult, + OnResolveArgs, + OnResolveResult, Plugin, } from 'esbuild' import esbuild, { formatMessages, transform } from 'esbuild' @@ -486,19 +488,28 @@ function esbuildScanPlugin( } } - const globImportOnLoadCallback: ( - args: OnLoadArgs, - ) => Promise = async ({ path: p }) => { - const externalLoadResult: OnLoadResult = { + const globImportCallback: ( + args: OnResolveArgs | OnLoadArgs, + ) => Promise = async ( + args, + ) => { + const { path } = args + const externalOnLoadResult: OnLoadResult = { loader: 'js', contents: '\nexport default {}', } - if (!entries.includes(p)) { - return externalLoadResult + // The onLoad hook is triggered + if (!('kind' in args)) { + return externalOnLoadResult } - if (SPECIAL_QUERY_RE.test(p)) { - return externalLoadResult + // The onResolve hook is triggered + if (SPECIAL_QUERY_RE.test(path)) { + return { + path, + external: true, + } } + return externalUnlessEntry({ path }) } // extract scripts inside HTML-like files and treat it as a js module @@ -516,12 +527,12 @@ function esbuildScanPlugin( // css build.onLoad( { filter: CSS_LANGS_RE, namespace: 'file' }, - globImportOnLoadCallback, + globImportCallback, ) // json & wasm build.onLoad( { filter: /\.(json|json5|wasm)$/, namespace: 'file' }, - globImportOnLoadCallback, + globImportCallback, ) // known asset types build.onLoad( @@ -529,12 +540,12 @@ function esbuildScanPlugin( filter: new RegExp(`\\.(${KNOWN_ASSET_TYPES.join('|')})$`), namespace: 'file', }, - globImportOnLoadCallback, + globImportCallback, ) // known vite query types: ?worker, ?raw build.onLoad( { filter: SPECIAL_QUERY_RE, namespace: 'file' }, - globImportOnLoadCallback, + globImportCallback, ) // bare imports: record and externalize ---------------------------------- @@ -588,24 +599,21 @@ function esbuildScanPlugin( // may end with these extensions // css - build.onResolve({ filter: CSS_LANGS_RE }, externalUnlessEntry) + build.onResolve({ filter: CSS_LANGS_RE }, globImportCallback) // json & wasm - build.onResolve({ filter: /\.(json|json5|wasm)$/ }, externalUnlessEntry) + build.onResolve({ filter: /\.(json|json5|wasm)$/ }, globImportCallback) // known asset types build.onResolve( { filter: new RegExp(`\\.(${KNOWN_ASSET_TYPES.join('|')})$`), }, - externalUnlessEntry, + globImportCallback, ) // known vite query types: ?worker, ?raw - build.onResolve({ filter: SPECIAL_QUERY_RE }, ({ path }) => ({ - path, - external: true, - })) + build.onResolve({ filter: SPECIAL_QUERY_RE }, globImportCallback) // catch all ------------------------------------------------------------- From 6354b2b3832153b38e16260afeb9d7c2973ca517 Mon Sep 17 00:00:00 2001 From: FinalAshen <819712530@qq.com> Date: Thu, 30 Nov 2023 16:32:47 +0800 Subject: [PATCH 3/4] chore: merge the onload and onResolve hooks for glob imports resources --- packages/vite/src/node/optimizer/scan.ts | 104 ++++++++--------------- 1 file changed, 36 insertions(+), 68 deletions(-) diff --git a/packages/vite/src/node/optimizer/scan.ts b/packages/vite/src/node/optimizer/scan.ts index 3b27c32785d233..baa09f25ea16cf 100644 --- a/packages/vite/src/node/optimizer/scan.ts +++ b/packages/vite/src/node/optimizer/scan.ts @@ -8,8 +8,6 @@ import type { Loader, OnLoadArgs, OnLoadResult, - OnResolveArgs, - OnResolveResult, Plugin, } from 'esbuild' import esbuild, { formatMessages, transform } from 'esbuild' @@ -302,9 +300,11 @@ function esbuildScanPlugin( '@vite/env', ] + const isUnlessEntry = (path: string) => !entries.includes(path) + const externalUnlessEntry = ({ path }: { path: string }) => ({ path, - external: !entries.includes(path), + external: isUnlessEntry(path), }) const doTransformGlobImport = async ( @@ -488,30 +488,6 @@ function esbuildScanPlugin( } } - const globImportCallback: ( - args: OnResolveArgs | OnLoadArgs, - ) => Promise = async ( - args, - ) => { - const { path } = args - const externalOnLoadResult: OnLoadResult = { - loader: 'js', - contents: '\nexport default {}', - } - // The onLoad hook is triggered - if (!('kind' in args)) { - return externalOnLoadResult - } - // The onResolve hook is triggered - if (SPECIAL_QUERY_RE.test(path)) { - return { - path, - external: true, - } - } - return externalUnlessEntry({ path }) - } - // extract scripts inside HTML-like files and treat it as a js module build.onLoad( { filter: htmlTypesRE, namespace: 'html' }, @@ -524,29 +500,44 @@ function esbuildScanPlugin( { filter: htmlTypesRE, namespace: 'file' }, htmlTypeOnLoadCallback, ) + + const setupExternalize = ( + filter: RegExp, + doExternalize: (path: string) => boolean, + ) => { + // Externalized file types ----------------------------------------------- + // these are done on raw ids using esbuild's native regex filter so it + // should be faster than doing it in the catch-all via js + // they are done after the bare import resolve because a package name + // may end with these extensions + build.onResolve({ filter }, ({ path }) => { + return { + path, + external: doExternalize(path), + } + }) + // onResolve is not called for glob imports. + // we need to add that here as well until esbuild calls onResolve for glob imports. + // https://github.com/evanw/esbuild/issues/3317 + build.onLoad({ filter, namespace: 'file' }, () => { + const externalOnLoadResult: OnLoadResult = { + loader: 'js', + contents: 'export default {}', + } + return externalOnLoadResult + }) + } // css - build.onLoad( - { filter: CSS_LANGS_RE, namespace: 'file' }, - globImportCallback, - ) + setupExternalize(CSS_LANGS_RE, isUnlessEntry) // json & wasm - build.onLoad( - { filter: /\.(json|json5|wasm)$/, namespace: 'file' }, - globImportCallback, - ) + setupExternalize(/\.(json|json5|wasm)$/, isUnlessEntry) // known asset types - build.onLoad( - { - filter: new RegExp(`\\.(${KNOWN_ASSET_TYPES.join('|')})$`), - namespace: 'file', - }, - globImportCallback, + setupExternalize( + new RegExp(`\\.(${KNOWN_ASSET_TYPES.join('|')})$`), + isUnlessEntry, ) // known vite query types: ?worker, ?raw - build.onLoad( - { filter: SPECIAL_QUERY_RE, namespace: 'file' }, - globImportCallback, - ) + setupExternalize(SPECIAL_QUERY_RE, () => true) // bare imports: record and externalize ---------------------------------- build.onResolve( @@ -592,29 +583,6 @@ function esbuildScanPlugin( }, ) - // Externalized file types ----------------------------------------------- - // these are done on raw ids using esbuild's native regex filter so it - // should be faster than doing it in the catch-all via js - // they are done after the bare import resolve because a package name - // may end with these extensions - - // css - build.onResolve({ filter: CSS_LANGS_RE }, globImportCallback) - - // json & wasm - build.onResolve({ filter: /\.(json|json5|wasm)$/ }, globImportCallback) - - // known asset types - build.onResolve( - { - filter: new RegExp(`\\.(${KNOWN_ASSET_TYPES.join('|')})$`), - }, - globImportCallback, - ) - - // known vite query types: ?worker, ?raw - build.onResolve({ filter: SPECIAL_QUERY_RE }, globImportCallback) - // catch all ------------------------------------------------------------- build.onResolve( From dcdf1acb9f56f9d23ee80a3b853f9c5b44dec107 Mon Sep 17 00:00:00 2001 From: sapphi-red <49056869+sapphi-red@users.noreply.github.com> Date: Fri, 1 Dec 2023 17:28:37 +0900 Subject: [PATCH 4/4] chore: reduce diff --- packages/vite/src/node/optimizer/scan.ts | 78 ++++++++++++------------ 1 file changed, 40 insertions(+), 38 deletions(-) diff --git a/packages/vite/src/node/optimizer/scan.ts b/packages/vite/src/node/optimizer/scan.ts index baa09f25ea16cf..be0984508c09b3 100644 --- a/packages/vite/src/node/optimizer/scan.ts +++ b/packages/vite/src/node/optimizer/scan.ts @@ -501,44 +501,6 @@ function esbuildScanPlugin( htmlTypeOnLoadCallback, ) - const setupExternalize = ( - filter: RegExp, - doExternalize: (path: string) => boolean, - ) => { - // Externalized file types ----------------------------------------------- - // these are done on raw ids using esbuild's native regex filter so it - // should be faster than doing it in the catch-all via js - // they are done after the bare import resolve because a package name - // may end with these extensions - build.onResolve({ filter }, ({ path }) => { - return { - path, - external: doExternalize(path), - } - }) - // onResolve is not called for glob imports. - // we need to add that here as well until esbuild calls onResolve for glob imports. - // https://github.com/evanw/esbuild/issues/3317 - build.onLoad({ filter, namespace: 'file' }, () => { - const externalOnLoadResult: OnLoadResult = { - loader: 'js', - contents: 'export default {}', - } - return externalOnLoadResult - }) - } - // css - setupExternalize(CSS_LANGS_RE, isUnlessEntry) - // json & wasm - setupExternalize(/\.(json|json5|wasm)$/, isUnlessEntry) - // known asset types - setupExternalize( - new RegExp(`\\.(${KNOWN_ASSET_TYPES.join('|')})$`), - isUnlessEntry, - ) - // known vite query types: ?worker, ?raw - setupExternalize(SPECIAL_QUERY_RE, () => true) - // bare imports: record and externalize ---------------------------------- build.onResolve( { @@ -583,6 +545,46 @@ function esbuildScanPlugin( }, ) + // Externalized file types ----------------------------------------------- + // these are done on raw ids using esbuild's native regex filter so it + // should be faster than doing it in the catch-all via js + // they are done after the bare import resolve because a package name + // may end with these extensions + + const setupExternalize = ( + filter: RegExp, + doExternalize: (path: string) => boolean, + ) => { + build.onResolve({ filter }, ({ path }) => { + return { + path, + external: doExternalize(path), + } + }) + // onResolve is not called for glob imports. + // we need to add that here as well until esbuild calls onResolve for glob imports. + // https://github.com/evanw/esbuild/issues/3317 + build.onLoad({ filter, namespace: 'file' }, () => { + const externalOnLoadResult: OnLoadResult = { + loader: 'js', + contents: 'export default {}', + } + return externalOnLoadResult + }) + } + + // css + setupExternalize(CSS_LANGS_RE, isUnlessEntry) + // json & wasm + setupExternalize(/\.(json|json5|wasm)$/, isUnlessEntry) + // known asset types + setupExternalize( + new RegExp(`\\.(${KNOWN_ASSET_TYPES.join('|')})$`), + isUnlessEntry, + ) + // known vite query types: ?worker, ?raw + setupExternalize(SPECIAL_QUERY_RE, () => true) + // catch all ------------------------------------------------------------- build.onResolve(