diff --git a/docs/guide/features.md b/docs/guide/features.md index dcb3fc2b0d6092..2cbfd384947aaf 100644 --- a/docs/guide/features.md +++ b/docs/guide/features.md @@ -625,6 +625,20 @@ Only the globs that are relative paths are interpreted as relative to the resolv All the resulting module keys are modified to be relative to the base if provided. +#### Case Sensitive Matching + +By default, glob pattern matching is case-sensitive. You can use the `caseSensitiveMatch` option to change this behavior: + +```ts twoslash +import 'vite/client' +// ---cut--- +const modules = import.meta.glob('./dir/module*.js', { + caseSensitiveMatch: false, +}) +``` + +With `caseSensitiveMatch: false`, the glob will match files regardless of case (e.g., `Module.js`, `module.js`, `MODULE.js` will all be matched by `module*.js`). + ### Glob Import Caveats Note that: diff --git a/packages/vite/src/node/plugins/importMetaGlob.ts b/packages/vite/src/node/plugins/importMetaGlob.ts index 955c3f0766e4d6..a1c96069f2e9b9 100644 --- a/packages/vite/src/node/plugins/importMetaGlob.ts +++ b/packages/vite/src/node/plugins/importMetaGlob.ts @@ -134,6 +134,7 @@ const knownOptions = { exhaustive: ['boolean'], query: ['object', 'string'], base: ['string'], + caseSensitiveMatch: ['boolean'], } const forceDefaultAs = ['raw', 'url'] @@ -454,6 +455,7 @@ export async function transformGlobImport( cwd, dot: !!options.exhaustive, expandDirectories: false, + caseSensitiveMatch: options.caseSensitiveMatch ?? true, ignore: options.exhaustive ? [] : ['**/node_modules/**'], }) ) diff --git a/packages/vite/types/importGlob.d.ts b/packages/vite/types/importGlob.d.ts index dfd6f6fe6bb4d1..45afd80ee43caf 100644 --- a/packages/vite/types/importGlob.d.ts +++ b/packages/vite/types/importGlob.d.ts @@ -32,6 +32,10 @@ export interface ImportGlobOptions< * Base path to resolve relative paths. */ base?: string + /** + * Whether the glob pattern matching should be case-sensitive. Defaults to `true`. + */ + caseSensitiveMatch?: boolean } export type GeneralImportGlobOptions = ImportGlobOptions diff --git a/playground/glob-import/__tests__/glob-import.spec.ts b/playground/glob-import/__tests__/glob-import.spec.ts index 81125143c69479..8b3f5f50e7edb7 100644 --- a/playground/glob-import/__tests__/glob-import.spec.ts +++ b/playground/glob-import/__tests__/glob-import.spec.ts @@ -311,3 +311,22 @@ test('import.meta.glob and dynamic import vars transformations should be visible JSON.stringify({ globTransformed: true, dynamicImportTransformed: true }), ) }) + +test('caseSensitiveMatch option', async () => { + await expect + .poll(async () => + JSON.parse(await page.textContent('.case-sensitive-true')), + ) + .toStrictEqual(['./case-sensitive-dir/data-test.js']) + + if (process.env._VITE_TEST_JS_PLUGIN) { + await expect + .poll(async () => + JSON.parse(await page.textContent('.case-sensitive-false')), + ) + .toStrictEqual([ + './case-sensitive-dir/DATA-other.js', + './case-sensitive-dir/data-test.js', + ]) + } +}) diff --git a/playground/glob-import/case-sensitive-dir/DATA-other.js b/playground/glob-import/case-sensitive-dir/DATA-other.js new file mode 100644 index 00000000000000..2057afd88aed13 --- /dev/null +++ b/playground/glob-import/case-sensitive-dir/DATA-other.js @@ -0,0 +1 @@ +export default 'DATA-OTHER' diff --git a/playground/glob-import/case-sensitive-dir/data-test.js b/playground/glob-import/case-sensitive-dir/data-test.js new file mode 100644 index 00000000000000..383a47b1d00e81 --- /dev/null +++ b/playground/glob-import/case-sensitive-dir/data-test.js @@ -0,0 +1 @@ +export default 'data-test' diff --git a/playground/glob-import/index.html b/playground/glob-import/index.html index 20d4467361e2d7..03b9a61ef0c8ab 100644 --- a/playground/glob-import/index.html +++ b/playground/glob-import/index.html @@ -214,3 +214,38 @@

Transform visibility

document.querySelector('.transform-visibility').textContent = JSON.stringify(result) + +

Case Sensitive Match (default: true)

+

+
+

Case Sensitive Match (false)

+

+
+