From 5279de6859df61b6191a4c3bfc76da582309a5ec Mon Sep 17 00:00:00 2001 From: ygj6 <7699524+ygj6@users.noreply.github.com> Date: Wed, 29 Dec 2021 05:30:47 +0800 Subject: [PATCH] feat: import.meta.glob support ?raw (#5545) --- .../glob-import/__tests__/glob-import.spec.ts | 12 +++++++ packages/playground/glob-import/index.html | 16 ++++++++++ packages/vite/package.json | 1 + packages/vite/src/node/importGlob.ts | 31 ++++++++++++++++--- pnpm-lock.yaml | 17 ++-------- 5 files changed, 58 insertions(+), 19 deletions(-) diff --git a/packages/playground/glob-import/__tests__/glob-import.spec.ts b/packages/playground/glob-import/__tests__/glob-import.spec.ts index 4377f7961ef229..311f94cd00571a 100644 --- a/packages/playground/glob-import/__tests__/glob-import.spec.ts +++ b/packages/playground/glob-import/__tests__/glob-import.spec.ts @@ -45,12 +45,24 @@ const allResult = { } } +const rawResult = { + '/dir/baz.json': { + msg: 'baz' + } +} + test('should work', async () => { expect(await page.textContent('.result')).toBe( JSON.stringify(allResult, null, 2) ) }) +test('import glob raw', async () => { + expect(await page.textContent('.globraw')).toBe( + JSON.stringify(rawResult, null, 2) + ) +}) + if (!isBuild) { test('hmr for adding/removing files', async () => { addFile('dir/a.js', '') diff --git a/packages/playground/glob-import/index.html b/packages/playground/glob-import/index.html index 2262c65414db67..e408ec8adda602 100644 --- a/packages/playground/glob-import/index.html +++ b/packages/playground/glob-import/index.html @@ -1,4 +1,5 @@

+

 
 
 
+
+
diff --git a/packages/vite/package.json b/packages/vite/package.json
index 579b832726559c..d092428fb17d52 100644
--- a/packages/vite/package.json
+++ b/packages/vite/package.json
@@ -45,6 +45,7 @@
   "//": "READ CONTRIBUTING.md to understand what to put under deps vs. devDeps!",
   "dependencies": {
     "esbuild": "^0.13.12",
+    "json5": "^2.2.0",
     "postcss": "^8.4.5",
     "resolve": "^1.20.0",
     "rollup": "^2.59.0"
diff --git a/packages/vite/src/node/importGlob.ts b/packages/vite/src/node/importGlob.ts
index 4b6bfbb740a966..0a5a0faeccbab1 100644
--- a/packages/vite/src/node/importGlob.ts
+++ b/packages/vite/src/node/importGlob.ts
@@ -1,5 +1,7 @@
 import path from 'path'
+import { promises as fsp } from 'fs'
 import glob from 'fast-glob'
+import * as JSON5 from 'json5'
 import {
   isModernFlag,
   preloadMethod,
@@ -8,6 +10,12 @@ import {
 import { cleanUrl } from './utils'
 import type { RollupError } from 'rollup'
 
+export interface AssertOptions {
+  assert?: {
+    type: string
+  }
+}
+
 export async function transformImportGlob(
   source: string,
   pos: number,
@@ -38,7 +46,7 @@ export async function transformImportGlob(
   importer = cleanUrl(importer)
   const importerBasename = path.basename(importer)
 
-  let [pattern, endIndex] = lexGlobPattern(source, pos)
+  let [pattern, assertion, endIndex] = lexGlobPattern(source, pos)
   if (!pattern.startsWith('.') && !pattern.startsWith('/')) {
     throw err(`pattern must start with "." or "/" (relative to project root)`)
   }
@@ -79,8 +87,12 @@ export async function transformImportGlob(
       ;[importee] = await normalizeUrl(file, pos)
     }
     imports.push(importee)
-    const identifier = `__glob_${importIndex}_${i}`
-    if (isEager) {
+    if (assertion?.assert?.type === 'raw') {
+      entries += ` ${JSON.stringify(file)}: ${JSON.stringify(
+        await fsp.readFile(path.join(base, file), 'utf-8')
+      )},`
+    } else if (isEager) {
+      const identifier = `__glob_${importIndex}_${i}`
       importsString += `import ${
         isEagerDefault ? `` : `* as `
       }${identifier} from ${JSON.stringify(importee)};`
@@ -115,7 +127,10 @@ const enum LexerState {
   inTemplateString
 }
 
-function lexGlobPattern(code: string, pos: number): [string, number] {
+function lexGlobPattern(
+  code: string,
+  pos: number
+): [string, AssertOptions, number] {
   let state = LexerState.inCall
   let pattern = ''
 
@@ -163,7 +178,13 @@ function lexGlobPattern(code: string, pos: number): [string, number] {
   }
 
   const endIndex = getEndIndex(code, i)
-  return [pattern, endIndex + 1]
+  const options = code.substring(i + 1, endIndex)
+  const commaIndex = options.indexOf(`,`)
+  let assert = {}
+  if (commaIndex > -1) {
+    assert = JSON5.parse(options.substr(commaIndex + 1))
+  }
+  return [pattern, assert, endIndex + 1]
 }
 
 // reg without the 'g' option, only matches the first match
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 7cdcbdc5340eda..78175029b85e3e 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -757,6 +757,7 @@ importers:
       fast-glob: ^3.2.7
       fsevents: ~2.3.2
       http-proxy: ^1.18.1
+      json5: ^2.2.0
       launch-editor-middleware: ^2.3.0
       magic-string: ^0.25.7
       micromatch: ^4.0.4
@@ -785,6 +786,7 @@ importers:
       ws: ^8.3.0
     dependencies:
       esbuild: 0.13.12
+      json5: 2.2.0
       postcss: 8.4.5
       resolve: 1.20.0
       rollup: 2.59.0
@@ -4717,19 +4719,6 @@ packages:
     peerDependenciesMeta:
       debug:
         optional: true
-    dev: false
-
-  /follow-redirects/1.14.5_debug@4.3.3:
-    resolution: {integrity: sha512-wtphSXy7d4/OR+MvIFbCVBDzZ5520qV8XfPklSN5QtxuMUJZ+b0Wnst1e1lCDocfzuCkHqj8k0FpZqO+UIaKNA==}
-    engines: {node: '>=4.0'}
-    peerDependencies:
-      debug: '*'
-    peerDependenciesMeta:
-      debug:
-        optional: true
-    dependencies:
-      debug: 4.3.3
-    dev: true
 
   /form-data/3.0.1:
     resolution: {integrity: sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==}
@@ -5137,7 +5126,7 @@ packages:
     engines: {node: '>=8.0.0'}
     dependencies:
       eventemitter3: 4.0.7
-      follow-redirects: 1.14.5_debug@4.3.3
+      follow-redirects: 1.14.5
       requires-port: 1.0.0
     transitivePeerDependencies:
       - debug