1
+ import { pathToFileURL } from 'node:url'
1
2
import { fs , hash , importFileDefault , path } from '@vuepress/utils'
2
3
import { build } from 'esbuild'
3
4
import type { UserConfig } from './types.js'
@@ -17,6 +18,11 @@ export const loadUserConfig = async (
17
18
userConfigDependencies : [ ] ,
18
19
}
19
20
}
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'
20
26
const result = await build ( {
21
27
absWorkingDir : process . cwd ( ) ,
22
28
entryPoints : [ userConfigPath ] ,
@@ -28,6 +34,11 @@ export const loadUserConfig = async (
28
34
format : 'esm' ,
29
35
sourcemap : 'inline' ,
30
36
metafile : true ,
37
+ define : {
38
+ '__dirname' : dirnameVarName ,
39
+ '__filename' : filenameVarName ,
40
+ 'import.meta.url' : importMetaUrlVarName ,
41
+ } ,
31
42
plugins : [
32
43
{
33
44
name : 'externalize-deps' ,
@@ -43,6 +54,27 @@ export const loadUserConfig = async (
43
54
} )
44
55
} ,
45
56
} ,
57
+ {
58
+ name : 'inject-file-scope-variables' ,
59
+ setup ( build ) {
60
+ build . onLoad ( { filter : / \. [ c m ] ? [ j t ] 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
+ } ,
46
78
] ,
47
79
} )
48
80
0 commit comments