Skip to content

Commit 3e519dd

Browse files
committed
feat: add base option for import.meta.glob (vitejs#17453)
1 parent 22b2994 commit 3e519dd

File tree

4 files changed

+63
-4
lines changed

4 files changed

+63
-4
lines changed

packages/vite/src/node/plugins/importMetaGlob.ts

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ export interface ParsedImportGlob {
3838

3939
interface ParsedGeneralImportGlobOptions extends GeneralImportGlobOptions {
4040
query?: string
41+
base?: string
4142
}
4243

4344
export function getAffectedGlobModules(
@@ -114,6 +115,7 @@ const knownOptions = {
114115
import: ['string'],
115116
exhaustive: ['boolean'],
116117
query: ['object', 'string'],
118+
base: ['string'],
117119
}
118120

119121
const forceDefaultAs = ['raw', 'url']
@@ -303,7 +305,9 @@ export async function parseImportGlob(
303305
}
304306

305307
const globsResolved = await Promise.all(
306-
globs.map((glob) => toAbsoluteGlob(glob, root, importer, resolveId)),
308+
globs.map((glob) =>
309+
toAbsoluteGlob(glob, root, importer, resolveId, options.base),
310+
),
307311
)
308312
const isRelative = globs.every((i) => '.!'.includes(i[0]))
309313

@@ -414,15 +418,26 @@ export async function transformGlobImport(
414418
throw new Error(
415419
"In virtual modules, all globs must start with '/'",
416420
)
417-
const filePath = `/${relative(root, file)}`
418-
return { filePath, importPath: filePath }
421+
422+
if (options.base) {
423+
const rootBase = posix.join(root, options.base)
424+
const filePath = `${relative(rootBase, file)}`
425+
const importPath = `/${relative(root, file)}`
426+
return { filePath, importPath }
427+
} else {
428+
const filePath = `/${relative(root, file)}`
429+
return { filePath, importPath: filePath }
430+
}
419431
}
420432

421433
let importPath = relative(dir, file)
422434
if (importPath[0] !== '.') importPath = `./${importPath}`
423435

424436
let filePath: string
425-
if (isRelative) {
437+
if (options.base) {
438+
const rootBase = posix.join(root, options.base)
439+
filePath = relative(rootBase, file)
440+
} else if (isRelative) {
426441
filePath = importPath
427442
} else {
428443
filePath = relative(root, file)
@@ -543,6 +558,7 @@ export async function toAbsoluteGlob(
543558
root: string,
544559
importer: string | undefined,
545560
resolveId: IdResolver,
561+
base?: string,
546562
): Promise<string> {
547563
let pre = ''
548564
if (glob[0] === '!') {
@@ -551,9 +567,13 @@ export async function toAbsoluteGlob(
551567
}
552568
root = globSafePath(root)
553569
const dir = importer ? globSafePath(dirname(importer)) : root
570+
571+
glob = base ? posix.join(base, glob) : glob
572+
554573
if (glob[0] === '/') return pre + posix.join(root, glob.slice(1))
555574
if (glob.startsWith('./')) return pre + posix.join(dir, glob.slice(2))
556575
if (glob.startsWith('../')) return pre + posix.join(dir, glob)
576+
if (base && !posix.isAbsolute(base)) return pre + posix.join(dir, glob)
557577
if (glob.startsWith('**')) return pre + glob
558578

559579
const isSubImportsPattern = glob[0] === '#' && glob.includes('*')

playground/glob-import/dir/d/e/f.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"msg": "f"
3+
}

playground/glob-import/dir/d/e/g.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"msg": "g"
3+
}

playground/glob-import/index.html

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ <h2>Sub imports</h2>
2525
<pre class="sub-imports"></pre>
2626
<h2>In package</h2>
2727
<pre class="in-package"></pre>
28+
<h2>Base</h2>
29+
<pre class="result-base"></pre>
2830

2931
<script type="module" src="./dir/index.js"></script>
3032
<script type="module">
@@ -162,3 +164,34 @@ <h2>In package</h2>
162164
<script type="module">
163165
import '@vitejs/test-import-meta-glob-pkg'
164166
</script>
167+
168+
<script type="module">
169+
// const rawModules1 = import.meta.glob('**/*.json', {
170+
// // query: '?raw',
171+
// eager: true,
172+
// import: 'default',
173+
// base: '/dir/d',
174+
// })
175+
// const rawModules2 = import.meta.glob('**/*.json', {
176+
// // query: '?raw',
177+
// eager: true,
178+
// import: 'default',
179+
// base: '../glob-import/dir/d',
180+
// })
181+
const baseModules = import.meta.glob('**/*.json', {
182+
query: '?raw',
183+
eager: true,
184+
import: 'default',
185+
base: './dir/d',
186+
})
187+
188+
const globbase = {}
189+
Object.keys(baseModules).forEach((key) => {
190+
globbase[key] = JSON.parse(baseModules[key])
191+
})
192+
document.querySelector('.result-base').textContent = JSON.stringify(
193+
globbase,
194+
null,
195+
2,
196+
)
197+
</script>

0 commit comments

Comments
 (0)