From fc4661fae07b0bbdf72f6d11772a1b2b5a26c718 Mon Sep 17 00:00:00 2001 From: "qing.deng" Date: Mon, 25 Jul 2022 12:43:22 +0800 Subject: [PATCH 1/9] fix: support `import.meta.glob` to use template strings but not contain expressions. --- .../vite/src/node/plugins/importMetaGlob.ts | 38 ++++++++++++------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/packages/vite/src/node/plugins/importMetaGlob.ts b/packages/vite/src/node/plugins/importMetaGlob.ts index 6943bf24c56702..77af5394f404cd 100644 --- a/packages/vite/src/node/plugins/importMetaGlob.ts +++ b/packages/vite/src/node/plugins/importMetaGlob.ts @@ -14,6 +14,7 @@ import MagicString from 'magic-string' import fg from 'fast-glob' import { stringifyQuery } from 'ufo' import type { GeneralImportGlobOptions } from 'types/importGlob' +import type { TemplateLiteral } from '@babel/types' import type { Plugin } from '../plugin' import type { ViteDevServer } from '../server' import type { ModuleNode } from '../server/moduleGraph' @@ -168,29 +169,40 @@ export async function parseImportGlob( if (ast.arguments.length < 1 || ast.arguments.length > 2) throw err(`Expected 1-2 arguments, but got ${ast.arguments.length}`) - const arg1 = ast.arguments[0] as ArrayExpression | Literal + const arg1 = ast.arguments[0] as ArrayExpression | Literal | TemplateLiteral const arg2 = ast.arguments[1] as Node | undefined const globs: string[] = [] - if (arg1.type === 'ArrayExpression') { - for (const element of arg1.elements) { - if (!element) continue - if (element.type !== 'Literal') throw err('Could only use literals') + + const validateLiteral = ( + element: Literal | TemplateLiteral | ArrayExpression['elements'][0] + ) => { + if (!element) return + if (element.type === 'Literal') { if (typeof element.value !== 'string') throw err( `Expected glob to be a string, but got "${typeof element.value}"` ) - globs.push(element.value) + } else if (element.type === 'TemplateLiteral') { + if (element.expressions.length !== 0) { + throw err( + `Expected glob to be a string, but got contains expressions` + ) + } + globs.push(element.quasis[0].value.raw) + } else { + throw err('Could only use literals') + } + } + + if (arg1.type === 'ArrayExpression') { + for (const element of arg1.elements) { + if (!element) continue + validateLiteral(element) } - } else if (arg1.type === 'Literal') { - if (typeof arg1.value !== 'string') - throw err( - `Expected glob to be a string, but got "${typeof arg1.value}"` - ) - globs.push(arg1.value) } else { - throw err('Could only use literals') + validateLiteral(arg1) } // arg2 From 88996bea7b7d6748434fc31ede998107aa0cc66a Mon Sep 17 00:00:00 2001 From: "qing.deng" Date: Mon, 25 Jul 2022 12:43:55 +0800 Subject: [PATCH 2/9] test: update some test cases --- .../__tests__/plugins/importGlob/parse.test.ts | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/packages/vite/src/node/__tests__/plugins/importGlob/parse.test.ts b/packages/vite/src/node/__tests__/plugins/importGlob/parse.test.ts index 7f9c181037b450..86abe7c150fc5f 100644 --- a/packages/vite/src/node/__tests__/plugins/importGlob/parse.test.ts +++ b/packages/vite/src/node/__tests__/plugins/importGlob/parse.test.ts @@ -272,10 +272,25 @@ describe('parse negatives', async () => { expect( await runError('import.meta.glob(`hi ${hey}`)') ).toMatchInlineSnapshot( - '[Error: Invalid glob import syntax: Could only use literals]' + '[Error: Invalid glob import syntax: Expected glob to be a string, but got contains expressions]' ) }) + it('template without expressions', async () => { + expect(await run('import.meta.glob(`/**/*.page.client.*([a-zA-Z0-9])`)')) + .toMatchInlineSnapshot(` + [ + { + "globs": [ + "/**/*.page.client.*([a-zA-Z0-9])", + ], + "options": {}, + "start": 0, + }, + ] + `) + }) + it('be string', async () => { expect(await runError('import.meta.glob(1)')).toMatchInlineSnapshot( '[Error: Invalid glob import syntax: Expected glob to be a string, but got "number"]' From 0c380d3c12bb727186c5bde156bb1f1611a903eb Mon Sep 17 00:00:00 2001 From: "qing.deng" Date: Mon, 25 Jul 2022 13:16:42 +0800 Subject: [PATCH 3/9] ci: fix From 4ab32fd5eacad6f225aea1d36a222ad87e8af82a Mon Sep 17 00:00:00 2001 From: "qing.deng" Date: Mon, 25 Jul 2022 14:24:30 +0800 Subject: [PATCH 4/9] fix: use the correct type --- packages/vite/src/node/plugins/importMetaGlob.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/vite/src/node/plugins/importMetaGlob.ts b/packages/vite/src/node/plugins/importMetaGlob.ts index 77af5394f404cd..4c1e71c6c98d49 100644 --- a/packages/vite/src/node/plugins/importMetaGlob.ts +++ b/packages/vite/src/node/plugins/importMetaGlob.ts @@ -7,14 +7,14 @@ import type { Literal, MemberExpression, Node, - SequenceExpression + SequenceExpression, + TemplateLiteral } from 'estree' import { parseExpressionAt } from 'acorn' import MagicString from 'magic-string' import fg from 'fast-glob' import { stringifyQuery } from 'ufo' import type { GeneralImportGlobOptions } from 'types/importGlob' -import type { TemplateLiteral } from '@babel/types' import type { Plugin } from '../plugin' import type { ViteDevServer } from '../server' import type { ModuleNode } from '../server/moduleGraph' From d8750f874316db70138f049641835aa4b0b45629 Mon Sep 17 00:00:00 2001 From: "qing.deng" Date: Mon, 25 Jul 2022 19:01:35 +0800 Subject: [PATCH 5/9] fix: simplify type --- packages/vite/src/node/plugins/importMetaGlob.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/vite/src/node/plugins/importMetaGlob.ts b/packages/vite/src/node/plugins/importMetaGlob.ts index 4c1e71c6c98d49..fa0de7254b127c 100644 --- a/packages/vite/src/node/plugins/importMetaGlob.ts +++ b/packages/vite/src/node/plugins/importMetaGlob.ts @@ -4,10 +4,12 @@ import { stripLiteral } from 'strip-literal' import type { ArrayExpression, CallExpression, + Expression, Literal, MemberExpression, Node, SequenceExpression, + SpreadElement, TemplateLiteral } from 'estree' import { parseExpressionAt } from 'acorn' @@ -174,9 +176,7 @@ export async function parseImportGlob( const globs: string[] = [] - const validateLiteral = ( - element: Literal | TemplateLiteral | ArrayExpression['elements'][0] - ) => { + const validateLiteral = (element: Expression | SpreadElement) => { if (!element) return if (element.type === 'Literal') { if (typeof element.value !== 'string') From bd42ebbf65da6d6f171498a5ee624b7f962a5116 Mon Sep 17 00:00:00 2001 From: "qing.deng" Date: Mon, 25 Jul 2022 19:08:42 +0800 Subject: [PATCH 6/9] test: add unicode test cases --- .../__tests__/plugins/importGlob/parse.test.ts | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/packages/vite/src/node/__tests__/plugins/importGlob/parse.test.ts b/packages/vite/src/node/__tests__/plugins/importGlob/parse.test.ts index 86abe7c150fc5f..95e7eee0547d35 100644 --- a/packages/vite/src/node/__tests__/plugins/importGlob/parse.test.ts +++ b/packages/vite/src/node/__tests__/plugins/importGlob/parse.test.ts @@ -276,6 +276,21 @@ describe('parse negatives', async () => { ) }) + it('template with unicode', async () => { + expect(await run('import.meta.glob(`/\u0068\u0065\u006c\u006c\u006f`)')) + .toMatchInlineSnapshot(` + [ + { + "globs": [ + "/hello", + ], + "options": {}, + "start": 0, + }, + ] + `) + }) + it('template without expressions', async () => { expect(await run('import.meta.glob(`/**/*.page.client.*([a-zA-Z0-9])`)')) .toMatchInlineSnapshot(` From 45f3457752027c6f46da35220aadafe89a2f5576 Mon Sep 17 00:00:00 2001 From: "qing.deng" Date: Mon, 25 Jul 2022 19:42:56 +0800 Subject: [PATCH 7/9] fix: repeat logic --- packages/vite/src/node/plugins/importMetaGlob.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/vite/src/node/plugins/importMetaGlob.ts b/packages/vite/src/node/plugins/importMetaGlob.ts index fa0de7254b127c..b2d0cda9c5eb49 100644 --- a/packages/vite/src/node/plugins/importMetaGlob.ts +++ b/packages/vite/src/node/plugins/importMetaGlob.ts @@ -176,7 +176,7 @@ export async function parseImportGlob( const globs: string[] = [] - const validateLiteral = (element: Expression | SpreadElement) => { + const validateLiteral = (element: Expression | SpreadElement | null) => { if (!element) return if (element.type === 'Literal') { if (typeof element.value !== 'string') @@ -198,7 +198,6 @@ export async function parseImportGlob( if (arg1.type === 'ArrayExpression') { for (const element of arg1.elements) { - if (!element) continue validateLiteral(element) } } else { From 717efbb932fbf7beecdd38762eddf600acf395a9 Mon Sep 17 00:00:00 2001 From: "qing.deng" Date: Mon, 25 Jul 2022 21:15:20 +0800 Subject: [PATCH 8/9] feat: updated with better error messages --- packages/vite/src/node/plugins/importMetaGlob.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/vite/src/node/plugins/importMetaGlob.ts b/packages/vite/src/node/plugins/importMetaGlob.ts index b2d0cda9c5eb49..e6512dbcd6724b 100644 --- a/packages/vite/src/node/plugins/importMetaGlob.ts +++ b/packages/vite/src/node/plugins/importMetaGlob.ts @@ -187,7 +187,7 @@ export async function parseImportGlob( } else if (element.type === 'TemplateLiteral') { if (element.expressions.length !== 0) { throw err( - `Expected glob to be a string, but got contains expressions` + `Expected glob to be a string, but got dynamic template literal` ) } globs.push(element.quasis[0].value.raw) From dca6e01247b0f8ef6c283adc3e3ce1541e14266f Mon Sep 17 00:00:00 2001 From: "qing.deng" Date: Mon, 25 Jul 2022 23:13:29 +0800 Subject: [PATCH 9/9] fix: update test snap --- .../vite/src/node/__tests__/plugins/importGlob/parse.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/vite/src/node/__tests__/plugins/importGlob/parse.test.ts b/packages/vite/src/node/__tests__/plugins/importGlob/parse.test.ts index 95e7eee0547d35..7fb6286339d262 100644 --- a/packages/vite/src/node/__tests__/plugins/importGlob/parse.test.ts +++ b/packages/vite/src/node/__tests__/plugins/importGlob/parse.test.ts @@ -272,7 +272,7 @@ describe('parse negatives', async () => { expect( await runError('import.meta.glob(`hi ${hey}`)') ).toMatchInlineSnapshot( - '[Error: Invalid glob import syntax: Expected glob to be a string, but got contains expressions]' + '[Error: Invalid glob import syntax: Expected glob to be a string, but got dynamic template literal]' ) })