diff --git a/docs/config/index.md b/docs/config/index.md index 31e341a399756e..5daf5e7f714275 100644 --- a/docs/config/index.md +++ b/docs/config/index.md @@ -24,14 +24,14 @@ vite --config my-config.js ``` ::: tip NOTE -Vite will replace `__filename`, `__dirname`, and `import.meta.url` in config files and its deps. Using these as variable names or passing as a parameter to a function with string double quote (example `console.log`) will result in an error: +Vite will inject `__filename`, `__dirname` in config files and its deps. Declaring these variables at top level will result in an error: ```js -const __filename = "value" -// will be transformed to -const "path/vite.config.js" = "value" +const __filename = 'value' // SyntaxError: Identifier '__filename' has already been declared -console.log("import.meta.url") // break error on build +const func = () => { + const __filename = 'value' // no error +} ``` ::: diff --git a/packages/vite/src/node/config.ts b/packages/vite/src/node/config.ts index d80f5a60583abc..f1a51fc955c20d 100644 --- a/packages/vite/src/node/config.ts +++ b/packages/vite/src/node/config.ts @@ -790,6 +790,7 @@ async function bundleConfigFile( fileName: string, isESM = false ): Promise<{ code: string; dependencies: string[] }> { + const importMetaUrlVarName = '__vite_injected_original_import_meta_url' const result = await build({ absWorkingDir: process.cwd(), entryPoints: [fileName], @@ -800,6 +801,9 @@ async function bundleConfigFile( format: isESM ? 'esm' : 'cjs', sourcemap: 'inline', metafile: true, + define: { + 'import.meta.url': importMetaUrlVarName + }, plugins: [ { name: 'externalize-deps', @@ -815,22 +819,20 @@ async function bundleConfigFile( } }, { - name: 'replace-import-meta', + name: 'inject-file-scope-variables', setup(build) { build.onLoad({ filter: /\.[jt]s$/ }, async (args) => { const contents = await fs.promises.readFile(args.path, 'utf8') + const injectValues = + `const __dirname = ${JSON.stringify(path.dirname(args.path))};` + + `const __filename = ${JSON.stringify(args.path)};` + + `const ${importMetaUrlVarName} = ${JSON.stringify( + pathToFileURL(args.path).href + )};` + return { loader: args.path.endsWith('.ts') ? 'ts' : 'js', - contents: contents - .replace( - /\bimport\.meta\.url\b/g, - JSON.stringify(pathToFileURL(args.path).href) - ) - .replace( - /\b__dirname\b/g, - JSON.stringify(path.dirname(args.path)) - ) - .replace(/\b__filename\b/g, JSON.stringify(args.path)) + contents: injectValues + contents } }) }