Skip to content

Commit 5279de6

Browse files
authored
feat: import.meta.glob support ?raw (vitejs#5545)
1 parent 6d4ee18 commit 5279de6

File tree

5 files changed

+58
-19
lines changed

5 files changed

+58
-19
lines changed

packages/playground/glob-import/__tests__/glob-import.spec.ts

+12
Original file line numberDiff line numberDiff line change
@@ -45,12 +45,24 @@ const allResult = {
4545
}
4646
}
4747

48+
const rawResult = {
49+
'/dir/baz.json': {
50+
msg: 'baz'
51+
}
52+
}
53+
4854
test('should work', async () => {
4955
expect(await page.textContent('.result')).toBe(
5056
JSON.stringify(allResult, null, 2)
5157
)
5258
})
5359

60+
test('import glob raw', async () => {
61+
expect(await page.textContent('.globraw')).toBe(
62+
JSON.stringify(rawResult, null, 2)
63+
)
64+
})
65+
5466
if (!isBuild) {
5567
test('hmr for adding/removing files', async () => {
5668
addFile('dir/a.js', '')

packages/playground/glob-import/index.html

+16
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
<pre class="result"></pre>
2+
<pre class="globraw"></pre>
23

34
<script type="module" src="./dir/index.js"></script>
45
<script type="module">
@@ -25,3 +26,18 @@
2526
document.querySelector('.result').textContent = JSON.stringify(res, null, 2)
2627
})
2728
</script>
29+
30+
<script type="module">
31+
const rawModules = import.meta.globEager('/dir/*.json', {
32+
assert: { type: 'raw' }
33+
})
34+
const globraw = {}
35+
Object.keys(rawModules).forEach((key) => {
36+
globraw[key] = JSON.parse(rawModules[key])
37+
})
38+
document.querySelector('.globraw').textContent = JSON.stringify(
39+
globraw,
40+
null,
41+
2
42+
)
43+
</script>

packages/vite/package.json

+1
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
"//": "READ CONTRIBUTING.md to understand what to put under deps vs. devDeps!",
4646
"dependencies": {
4747
"esbuild": "^0.13.12",
48+
"json5": "^2.2.0",
4849
"postcss": "^8.4.5",
4950
"resolve": "^1.20.0",
5051
"rollup": "^2.59.0"

packages/vite/src/node/importGlob.ts

+26-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import path from 'path'
2+
import { promises as fsp } from 'fs'
23
import glob from 'fast-glob'
4+
import * as JSON5 from 'json5'
35
import {
46
isModernFlag,
57
preloadMethod,
@@ -8,6 +10,12 @@ import {
810
import { cleanUrl } from './utils'
911
import type { RollupError } from 'rollup'
1012

13+
export interface AssertOptions {
14+
assert?: {
15+
type: string
16+
}
17+
}
18+
1119
export async function transformImportGlob(
1220
source: string,
1321
pos: number,
@@ -38,7 +46,7 @@ export async function transformImportGlob(
3846
importer = cleanUrl(importer)
3947
const importerBasename = path.basename(importer)
4048

41-
let [pattern, endIndex] = lexGlobPattern(source, pos)
49+
let [pattern, assertion, endIndex] = lexGlobPattern(source, pos)
4250
if (!pattern.startsWith('.') && !pattern.startsWith('/')) {
4351
throw err(`pattern must start with "." or "/" (relative to project root)`)
4452
}
@@ -79,8 +87,12 @@ export async function transformImportGlob(
7987
;[importee] = await normalizeUrl(file, pos)
8088
}
8189
imports.push(importee)
82-
const identifier = `__glob_${importIndex}_${i}`
83-
if (isEager) {
90+
if (assertion?.assert?.type === 'raw') {
91+
entries += ` ${JSON.stringify(file)}: ${JSON.stringify(
92+
await fsp.readFile(path.join(base, file), 'utf-8')
93+
)},`
94+
} else if (isEager) {
95+
const identifier = `__glob_${importIndex}_${i}`
8496
importsString += `import ${
8597
isEagerDefault ? `` : `* as `
8698
}${identifier} from ${JSON.stringify(importee)};`
@@ -115,7 +127,10 @@ const enum LexerState {
115127
inTemplateString
116128
}
117129

118-
function lexGlobPattern(code: string, pos: number): [string, number] {
130+
function lexGlobPattern(
131+
code: string,
132+
pos: number
133+
): [string, AssertOptions, number] {
119134
let state = LexerState.inCall
120135
let pattern = ''
121136

@@ -163,7 +178,13 @@ function lexGlobPattern(code: string, pos: number): [string, number] {
163178
}
164179

165180
const endIndex = getEndIndex(code, i)
166-
return [pattern, endIndex + 1]
181+
const options = code.substring(i + 1, endIndex)
182+
const commaIndex = options.indexOf(`,`)
183+
let assert = {}
184+
if (commaIndex > -1) {
185+
assert = JSON5.parse(options.substr(commaIndex + 1))
186+
}
187+
return [pattern, assert, endIndex + 1]
167188
}
168189

169190
// reg without the 'g' option, only matches the first match

pnpm-lock.yaml

+3-14
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)