-
-
Notifications
You must be signed in to change notification settings - Fork 99
/
load-svelte-config.ts
115 lines (109 loc) · 3.35 KB
/
load-svelte-config.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
import { createRequire } from 'module';
import path from 'path';
import fs from 'fs';
import { pathToFileURL } from 'url';
import { log } from './log';
import { Options } from './options';
import { UserConfig } from 'vite';
// used to require cjs config in esm.
// NOTE dynamic import() cjs technically works, but timestamp query cache bust
// have no effect, likely because it has another internal cache?
let esmRequire: NodeRequire;
export const knownSvelteConfigNames = [
'svelte.config.js',
'svelte.config.cjs',
'svelte.config.mjs'
];
// hide dynamic import from ts transform to prevent it turning into a require
// see https://github.com/microsoft/TypeScript/issues/43329#issuecomment-811606238
// also use timestamp query to avoid caching on reload
const dynamicImportDefault = new Function(
'path',
'timestamp',
'return import(path + "?t=" + timestamp).then(m => m.default)'
);
export async function loadSvelteConfig(
viteConfig?: UserConfig,
inlineOptions?: Partial<Options>
): Promise<Partial<Options> | undefined> {
if (inlineOptions.configFile === false) {
return;
}
const configFile = findConfigToLoad(viteConfig, inlineOptions);
if (configFile) {
let err;
// try to use dynamic import for svelte.config.js first
if (configFile.endsWith('.js') || configFile.endsWith('.mjs')) {
try {
const result = await dynamicImportDefault(
pathToFileURL(configFile).href,
fs.statSync(configFile).mtimeMs
);
if (result != null) {
return {
...result,
configFile
};
} else {
throw new Error(`invalid export in ${configFile}`);
}
} catch (e) {
log.error(`failed to import config ${configFile}`, e);
err = e;
}
}
// cjs or error with dynamic import
if (!configFile.endsWith('.mjs')) {
try {
// identify which require function to use (esm and cjs mode)
const _require = import.meta.url
? (esmRequire ??= createRequire(import.meta.url))
: require;
// avoid loading cached version on reload
delete _require.cache[_require.resolve(configFile)];
const result = _require(configFile);
if (result != null) {
return {
...result,
configFile
};
} else {
throw new Error(`invalid export in ${configFile}`);
}
} catch (e) {
log.error(`failed to require config ${configFile}`, e);
if (!err) {
err = e;
}
}
}
// failed to load existing config file
throw err;
}
}
function findConfigToLoad(viteConfig?: UserConfig, inlineOptions?: Partial<Options>) {
const root = viteConfig?.root || process.cwd();
if (inlineOptions?.configFile) {
const abolutePath = path.isAbsolute(inlineOptions.configFile)
? inlineOptions.configFile
: path.resolve(root, inlineOptions.configFile);
if (!fs.existsSync(abolutePath)) {
throw new Error(`failed to find svelte config file ${abolutePath}.`);
}
return abolutePath;
} else {
const existingKnownConfigFiles = knownSvelteConfigNames
.map((candidate) => path.resolve(root, candidate))
.filter((file) => fs.existsSync(file));
if (existingKnownConfigFiles.length === 0) {
log.debug(`no svelte config found at ${root}`);
return;
} else if (existingKnownConfigFiles.length > 1) {
log.warn(
`found more than one svelte config file, using ${existingKnownConfigFiles[0]}. you should only have one!`,
existingKnownConfigFiles
);
}
return existingKnownConfigFiles[0];
}
}