Skip to content

Commit

Permalink
feat: better config __dirname support (#8442)
Browse files Browse the repository at this point in the history
  • Loading branch information
sapphi-red committed Jun 8, 2022
1 parent f59adf8 commit 51e9195
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 16 deletions.
10 changes: 5 additions & 5 deletions docs/config/index.md
Expand Up @@ -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
}
```

:::
Expand Down
24 changes: 13 additions & 11 deletions packages/vite/src/node/config.ts
Expand Up @@ -772,6 +772,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],
Expand All @@ -782,6 +783,9 @@ async function bundleConfigFile(
format: isESM ? 'esm' : 'cjs',
sourcemap: 'inline',
metafile: true,
define: {
'import.meta.url': importMetaUrlVarName
},
plugins: [
{
name: 'externalize-deps',
Expand All @@ -797,22 +801,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
}
})
}
Expand Down

0 comments on commit 51e9195

Please sign in to comment.