Skip to content

Commit 8171f4d

Browse files
committed
fix(cli): handle config file __dirname correctly
1 parent 0ec2641 commit 8171f4d

File tree

1 file changed

+32
-0
lines changed

1 file changed

+32
-0
lines changed

packages/cli/src/config/loadUserConfig.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { pathToFileURL } from 'node:url'
12
import { fs, hash, importFileDefault, path } from '@vuepress/utils'
23
import { build } from 'esbuild'
34
import type { UserConfig } from './types.js'
@@ -17,6 +18,11 @@ export const loadUserConfig = async (
1718
userConfigDependencies: [],
1819
}
1920
}
21+
// following code is forked and modified from vite
22+
// TODO: we can migrate to something like `bundler-require`, but its `__dirname` support is not as good as vite
23+
const dirnameVarName = '__vite_injected_original_dirname'
24+
const filenameVarName = '__vite_injected_original_filename'
25+
const importMetaUrlVarName = '__vite_injected_original_import_meta_url'
2026
const result = await build({
2127
absWorkingDir: process.cwd(),
2228
entryPoints: [userConfigPath],
@@ -28,6 +34,11 @@ export const loadUserConfig = async (
2834
format: 'esm',
2935
sourcemap: 'inline',
3036
metafile: true,
37+
define: {
38+
'__dirname': dirnameVarName,
39+
'__filename': filenameVarName,
40+
'import.meta.url': importMetaUrlVarName,
41+
},
3142
plugins: [
3243
{
3344
name: 'externalize-deps',
@@ -43,6 +54,27 @@ export const loadUserConfig = async (
4354
})
4455
},
4556
},
57+
{
58+
name: 'inject-file-scope-variables',
59+
setup(build) {
60+
build.onLoad({ filter: /\.[cm]?[jt]s$/ }, async (args) => {
61+
const contents = await fs.readFile(args.path, 'utf8')
62+
const injectValues =
63+
`const ${dirnameVarName} = ${JSON.stringify(
64+
path.dirname(args.path)
65+
)};` +
66+
`const ${filenameVarName} = ${JSON.stringify(args.path)};` +
67+
`const ${importMetaUrlVarName} = ${JSON.stringify(
68+
pathToFileURL(args.path).href
69+
)};`
70+
71+
return {
72+
loader: args.path.endsWith('ts') ? 'ts' : 'js',
73+
contents: injectValues + contents,
74+
}
75+
})
76+
},
77+
},
4678
],
4779
})
4880

0 commit comments

Comments
 (0)