Skip to content

Commit

Permalink
feat(import-glob): support read module from alias pattern (fix #12180)
Browse files Browse the repository at this point in the history
  • Loading branch information
sun0day committed Feb 27, 2023
1 parent bf9c49f commit 302b068
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 32 deletions.
79 changes: 54 additions & 25 deletions packages/vite/src/node/plugins/importMetaGlob.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@ import {
slash,
transformStableResult,
} from '../utils'
import type { Alias, AliasOptions } from '..'
import { isCSSRequest, isModuleCSSRequest } from './css'
import { getAliasPatterns, matches as matchesAlias } from './preAlias'

const { isMatch, scan } = micromatch

Expand Down Expand Up @@ -78,6 +80,7 @@ export function importGlobPlugin(config: ResolvedConfig): Plugin {
(im) => this.resolve(im, id).then((i) => i?.id || im),
config.isProduction,
config.experimental.importGlobRestoreExtension,
config.resolve.alias,
)
if (result) {
if (server) {
Expand Down Expand Up @@ -351,6 +354,7 @@ export async function transformGlobImport(
resolveId: IdResolver,
isProduction: boolean,
restoreQueryExtension = false,
alias?: (AliasOptions | undefined) & Alias[],
): Promise<TransformGlobImportResult | null> {
id = slash(id)
root = slash(root)
Expand Down Expand Up @@ -389,6 +393,11 @@ export async function transformGlobImport(
start,
end,
}) => {
const aliasPattern =
alias &&
getAliasPatterns(alias).find(({ find }) =>
matchesAlias(find, globs[0]),
)
const cwd = getCommonBase(globsResolved) ?? root
const files = (
await fg(globsResolved, {
Expand Down Expand Up @@ -439,9 +448,18 @@ export async function transformGlobImport(
}

let includesCSS = false
const importKey =
options.import && options.import !== '*'
? options.import
: undefined
files.forEach((file, i) => {
const paths = resolvePaths(file)
const filePath = paths.filePath
const aliasPath =
aliasPattern &&
typeof aliasPattern.find === 'string' &&
file.replace(aliasPattern.replacement, aliasPattern.find)
const aliasMatched = aliasPath && aliasPath !== file
let importPath = paths.importPath
let importQuery = query

Expand All @@ -457,11 +475,6 @@ export async function transformGlobImport(
!query && isCSSRequest(file) && !isModuleCSSRequest(file)
includesCSS ||= isCSS

const importKey =
options.import && options.import !== '*'
? options.import
: undefined

if (options.eager) {
const variableName = `${importPrefix}${index}_${i}`
const expression = importKey
Expand All @@ -471,34 +484,50 @@ export async function transformGlobImport(
`import ${expression} from ${JSON.stringify(importPath)}`,
)
if (!isProduction && isCSS) {
objectProps.push(
`get ${JSON.stringify(
filePath,
)}() { ${createCssDefaultImportWarning(
globs,
options,
)} return ${variableName} }`,
)
const injectModule = (filePath: string) =>
objectProps.push(
`get ${JSON.stringify(
filePath,
)}() { ${createCssDefaultImportWarning(
globs,
options,
)} return ${variableName} }`,
)

injectModule(filePath)
aliasMatched && injectModule(aliasPath)
} else {
objectProps.push(`${JSON.stringify(filePath)}: ${variableName}`)
const injectModule = (filePath: string) =>
objectProps.push(
`${JSON.stringify(filePath)}: ${variableName}`,
)
injectModule(filePath)
aliasMatched && injectModule(aliasPath)
}
} else {
let importStatement = `import(${JSON.stringify(importPath)})`
if (importKey)
importStatement += `.then(m => m[${JSON.stringify(importKey)}])`
if (!isProduction && isCSS) {
objectProps.push(
`${JSON.stringify(
filePath,
)}: () => { ${createCssDefaultImportWarning(
globs,
options,
)} return ${importStatement}}`,
)
const injectModule = (filePath: string) =>
objectProps.push(
`${JSON.stringify(
filePath,
)}: () => { ${createCssDefaultImportWarning(
globs,
options,
)} return ${importStatement}}`,
)

injectModule(filePath)
aliasMatched && injectModule(aliasPath)
} else {
objectProps.push(
`${JSON.stringify(filePath)}: () => ${importStatement}`,
)
const injectModule = (filePath: string) =>
objectProps.push(
`${JSON.stringify(filePath)}: () => ${importStatement}`,
)
injectModule(filePath)
aliasMatched && injectModule(aliasPath)
}
}
})
Expand Down
15 changes: 9 additions & 6 deletions packages/vite/src/node/plugins/preAlias.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export function preAliasPlugin(config: ResolvedConfig): Plugin {
id !== '@vite/client' &&
id !== '@vite/env'
) {
if (findPatterns.find((pattern) => matches(pattern, id))) {
if (findPatterns.find(({ find }) => matches(find, id))) {
const optimizedId = await tryOptimizedResolve(
depsOptimizer,
id,
Expand Down Expand Up @@ -98,7 +98,7 @@ function optimizeAliasReplacementForSSR(
}

// In sync with rollup plugin alias logic
function matches(pattern: string | RegExp, importee: string) {
export function matches(pattern: string | RegExp, importee: string): boolean {
if (pattern instanceof RegExp) {
return pattern.test(importee)
}
Expand All @@ -111,14 +111,17 @@ function matches(pattern: string | RegExp, importee: string) {
return importee.startsWith(pattern + '/')
}

function getAliasPatterns(
export function getAliasPatterns(
entries: (AliasOptions | undefined) & Alias[],
): (string | RegExp)[] {
): Alias[] {
if (!entries) {
return []
}
if (Array.isArray(entries)) {
return entries.map((entry) => entry.find)
return entries
}
return Object.entries(entries).map(([find]) => find)
return Object.entries(entries as AliasOptions).map(([find, replacement]) => ({
find,
replacement,
}))
}
3 changes: 3 additions & 0 deletions playground/glob-import/__tests__/glob-import.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ const globWithAlias = {
'/dir/alias.js': {
default: 'hi',
},
'@dir/alias.js': {
default: 'hi',
},
}

const allResult = {
Expand Down
3 changes: 2 additions & 1 deletion playground/glob-import/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -136,8 +136,9 @@ <h2>Escape alias glob</h2>
.sort()
.join('\n')
const alias = Object.entries(globs)
.filter(([_, mod]) => Object.keys(mod?.alias ?? {}).length === 1)
.filter(([_, mod]) => Object.keys(mod?.alias ?? {}).length === 2)
.map(([glob]) => glob)

document.querySelector('.escape-alias').textContent = alias.sort().join('\n')
</script>

Expand Down

0 comments on commit 302b068

Please sign in to comment.