vike 0.4.159-commit-0424983 → 0.4.159-commit-d73533a
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/loadFileConfigEnv.js +129 -0
- package/dist/cjs/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/resolveImportPath.js +139 -0
- package/dist/cjs/node/plugin/plugins/importUserCode/v1-design/{transformImports.js → getVikeConfig/transformImports.js} +3 -3
- package/dist/cjs/node/plugin/plugins/importUserCode/v1-design/{transpileAndExecuteFile.js → getVikeConfig/transpileAndExecuteFile.js} +43 -29
- package/dist/cjs/node/plugin/plugins/importUserCode/v1-design/getVikeConfig.js +54 -274
- package/dist/cjs/node/plugin/shared/getHttpRequestAsyncStore.js +1 -1
- package/dist/cjs/node/plugin/shared/loggerNotProd.js +1 -1
- package/dist/cjs/utils/projectInfo.js +1 -1
- package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/loadFileConfigEnv.d.ts +21 -0
- package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/loadFileConfigEnv.js +123 -0
- package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/resolveImportPath.d.ts +12 -0
- package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/resolveImportPath.js +133 -0
- package/dist/esm/node/plugin/plugins/importUserCode/v1-design/{transformImports.js → getVikeConfig/transformImports.js} +3 -3
- package/dist/esm/node/plugin/plugins/importUserCode/v1-design/{transpileAndExecuteFile.d.ts → getVikeConfig/transpileAndExecuteFile.d.ts} +2 -2
- package/dist/esm/node/plugin/plugins/importUserCode/v1-design/{transpileAndExecuteFile.js → getVikeConfig/transpileAndExecuteFile.js} +44 -30
- package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig.d.ts +14 -1
- package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig.js +50 -270
- package/dist/esm/node/plugin/shared/getHttpRequestAsyncStore.js +1 -1
- package/dist/esm/node/plugin/shared/loggerNotProd.js +1 -1
- package/dist/esm/utils/projectInfo.d.ts +2 -2
- package/dist/esm/utils/projectInfo.js +1 -1
- package/package.json +1 -1
- /package/dist/esm/node/plugin/plugins/importUserCode/v1-design/{transformImports.d.ts → getVikeConfig/transformImports.d.ts} +0 -0
package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/loadFileConfigEnv.js
ADDED
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
// Files loadded at config time:
|
|
2
|
+
export { loadImportedFile };
|
|
3
|
+
export { loadValueFile };
|
|
4
|
+
export { loadConfigFile };
|
|
5
|
+
import { assertPosixPath, assert, assertUsage, assertWarning, hasProp, assertIsNotProductionRuntime, isNpmPackageImport } from '../../../../utils.js';
|
|
6
|
+
import { transpileAndExecuteFile } from './transpileAndExecuteFile.js';
|
|
7
|
+
import { assertPlusFileExport } from '../../../../../../shared/page-configs/assertPlusFileExport.js';
|
|
8
|
+
import pc from '@brillout/picocolors';
|
|
9
|
+
import { parseImportData } from './transformImports.js';
|
|
10
|
+
import { getConfigFileExport } from '../getConfigFileExport.js';
|
|
11
|
+
import { assertImportPath, resolveImportPath } from './resolveImportPath.js';
|
|
12
|
+
assertIsNotProductionRuntime();
|
|
13
|
+
// Load fake import
|
|
14
|
+
async function loadImportedFile(import_, userRootDir, importedFilesLoaded) {
|
|
15
|
+
const f = import_.filePathAbsoluteFilesystem;
|
|
16
|
+
if (!importedFilesLoaded[f]) {
|
|
17
|
+
importedFilesLoaded[f] = transpileAndExecuteFile(import_, true, userRootDir).then((r) => r.fileExports);
|
|
18
|
+
}
|
|
19
|
+
const fileExports = await importedFilesLoaded[f];
|
|
20
|
+
const fileExport = fileExports[import_.fileExportName];
|
|
21
|
+
return fileExport;
|
|
22
|
+
}
|
|
23
|
+
// Load +{configName}.js
|
|
24
|
+
async function loadValueFile(interfaceValueFile, configName, userRootDir) {
|
|
25
|
+
const { fileExports } = await transpileAndExecuteFile(interfaceValueFile.filePath, true, userRootDir);
|
|
26
|
+
const { filePathToShowToUser } = interfaceValueFile.filePath;
|
|
27
|
+
assertPlusFileExport(fileExports, filePathToShowToUser, configName);
|
|
28
|
+
Object.entries(fileExports).forEach(([exportName, configValue]) => {
|
|
29
|
+
const configName_ = exportName === 'default' ? configName : exportName;
|
|
30
|
+
interfaceValueFile.fileExportsByConfigName[configName_] = { configValue };
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
// Load +config.js, including all its extends fake imports
|
|
34
|
+
async function loadConfigFile(configFilePath, userRootDir, visited, isConfigOfExtension) {
|
|
35
|
+
const { filePathAbsoluteFilesystem } = configFilePath;
|
|
36
|
+
assertNoInfiniteLoop(visited, filePathAbsoluteFilesystem);
|
|
37
|
+
const { fileExports } = await transpileAndExecuteFile(configFilePath, false, userRootDir, isConfigOfExtension);
|
|
38
|
+
const { extendsConfigs, extendsFilePaths } = await loadExtendsConfigs(fileExports, configFilePath, userRootDir, [
|
|
39
|
+
...visited,
|
|
40
|
+
filePathAbsoluteFilesystem
|
|
41
|
+
]);
|
|
42
|
+
const configFile = {
|
|
43
|
+
fileExports,
|
|
44
|
+
filePath: configFilePath,
|
|
45
|
+
extendsFilePaths
|
|
46
|
+
};
|
|
47
|
+
return { configFile, extendsConfigs };
|
|
48
|
+
}
|
|
49
|
+
function assertNoInfiniteLoop(visited, filePathAbsoluteFilesystem) {
|
|
50
|
+
const idx = visited.indexOf(filePathAbsoluteFilesystem);
|
|
51
|
+
if (idx === -1)
|
|
52
|
+
return;
|
|
53
|
+
const loop = visited.slice(idx);
|
|
54
|
+
assert(loop[0] === filePathAbsoluteFilesystem);
|
|
55
|
+
assertUsage(idx === -1, `Infinite extends loop ${[...loop, filePathAbsoluteFilesystem].join('>')}`);
|
|
56
|
+
}
|
|
57
|
+
async function loadExtendsConfigs(configFileExports, configFilePath, userRootDir, visited) {
|
|
58
|
+
const extendsImportData = getExtendsImportData(configFileExports, configFilePath);
|
|
59
|
+
const extendsConfigFiles = [];
|
|
60
|
+
extendsImportData.map((importData) => {
|
|
61
|
+
const { importPath: importPath } = importData;
|
|
62
|
+
const filePathAbsoluteFilesystem = resolveImportPath(importData, configFilePath);
|
|
63
|
+
assertImportPath(filePathAbsoluteFilesystem, importData, configFilePath);
|
|
64
|
+
warnUserLandExtension(importPath, configFilePath);
|
|
65
|
+
// - filePathRelativeToUserRootDir has no functionality beyond nicer error messages for user
|
|
66
|
+
// - Using importPath would be visually nicer but it's ambigous => we rather pick filePathAbsoluteFilesystem for added clarity
|
|
67
|
+
const filePathRelativeToUserRootDir = determineFilePathRelativeToUserDir(filePathAbsoluteFilesystem, userRootDir);
|
|
68
|
+
const filePathAbsoluteVite = filePathRelativeToUserRootDir ?? importPath;
|
|
69
|
+
extendsConfigFiles.push({
|
|
70
|
+
filePathAbsoluteFilesystem,
|
|
71
|
+
filePathAbsoluteVite,
|
|
72
|
+
filePathRelativeToUserRootDir,
|
|
73
|
+
filePathToShowToUser: filePathAbsoluteVite,
|
|
74
|
+
importPathAbsolute: importPath
|
|
75
|
+
});
|
|
76
|
+
});
|
|
77
|
+
const extendsConfigs = [];
|
|
78
|
+
await Promise.all(extendsConfigFiles.map(async (configFilePath) => {
|
|
79
|
+
const result = await loadConfigFile(configFilePath, userRootDir, visited, true);
|
|
80
|
+
extendsConfigs.push(result.configFile);
|
|
81
|
+
extendsConfigs.push(...result.extendsConfigs);
|
|
82
|
+
}));
|
|
83
|
+
const extendsFilePaths = extendsConfigFiles.map((f) => f.filePathAbsoluteFilesystem);
|
|
84
|
+
return { extendsConfigs, extendsFilePaths };
|
|
85
|
+
}
|
|
86
|
+
function determineFilePathRelativeToUserDir(filePathAbsoluteFilesystem, userRootDir) {
|
|
87
|
+
assertPosixPath(filePathAbsoluteFilesystem);
|
|
88
|
+
assertPosixPath(userRootDir);
|
|
89
|
+
if (!filePathAbsoluteFilesystem.startsWith(userRootDir)) {
|
|
90
|
+
return null;
|
|
91
|
+
}
|
|
92
|
+
let filePathRelativeToUserRootDir = filePathAbsoluteFilesystem.slice(userRootDir.length);
|
|
93
|
+
if (!filePathRelativeToUserRootDir.startsWith('/'))
|
|
94
|
+
filePathRelativeToUserRootDir = '/' + filePathRelativeToUserRootDir;
|
|
95
|
+
return filePathRelativeToUserRootDir;
|
|
96
|
+
}
|
|
97
|
+
function warnUserLandExtension(importPath, configFilePath) {
|
|
98
|
+
assertWarning(isNpmPackageImport(importPath), `${configFilePath.filePathToShowToUser} uses ${pc.cyan('extends')} to inherit from ${pc.cyan(importPath)} which is a user-land file: this is experimental and may be remove at any time. Reach out to a maintainer if you need this.`, { onlyOnce: true });
|
|
99
|
+
}
|
|
100
|
+
function getExtendsImportData(configFileExports, configFilePath) {
|
|
101
|
+
const { filePathToShowToUser } = configFilePath;
|
|
102
|
+
const configFileExport = getConfigFileExport(configFileExports, filePathToShowToUser);
|
|
103
|
+
const wrongUsage = `${filePathToShowToUser} sets the config ${pc.cyan('extends')} to an invalid value, see https://vike.dev/extends`;
|
|
104
|
+
let extendList;
|
|
105
|
+
if (!('extends' in configFileExport)) {
|
|
106
|
+
return [];
|
|
107
|
+
}
|
|
108
|
+
else if (hasProp(configFileExport, 'extends', 'string')) {
|
|
109
|
+
extendList = [configFileExport.extends];
|
|
110
|
+
}
|
|
111
|
+
else if (hasProp(configFileExport, 'extends', 'string[]')) {
|
|
112
|
+
extendList = configFileExport.extends;
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
assertUsage(false, wrongUsage);
|
|
116
|
+
}
|
|
117
|
+
const extendsImportData = extendList.map((importDataSerialized) => {
|
|
118
|
+
const importData = parseImportData(importDataSerialized);
|
|
119
|
+
assertUsage(importData, wrongUsage);
|
|
120
|
+
return importData;
|
|
121
|
+
});
|
|
122
|
+
return extendsImportData;
|
|
123
|
+
}
|
package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/resolveImportPath.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export { resolveImport };
|
|
2
|
+
export { resolveImportPath };
|
|
3
|
+
export { assertImportPath };
|
|
4
|
+
export { clearFilesEnvMap };
|
|
5
|
+
import type { ConfigEnvInternal, DefinedAtFileFullInfo, FilePathResolved } from '../../../../../../shared/page-configs/PageConfig.js';
|
|
6
|
+
import { type ImportData } from './transformImports.js';
|
|
7
|
+
declare function resolveImport(configValue: unknown, importerFilePath: FilePathResolved, userRootDir: string, configEnv: ConfigEnvInternal, configName: string): null | (DefinedAtFileFullInfo & {
|
|
8
|
+
fileExportName: string;
|
|
9
|
+
});
|
|
10
|
+
declare function resolveImportPath(importData: ImportData, importerFilePath: FilePathResolved): string | null;
|
|
11
|
+
declare function assertImportPath(filePathAbsoluteFilesystem: string | null, importData: ImportData, importerFilePath: FilePathResolved): asserts filePathAbsoluteFilesystem is string;
|
|
12
|
+
declare function clearFilesEnvMap(): void;
|
package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/resolveImportPath.js
ADDED
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
export { resolveImport };
|
|
2
|
+
export { resolveImportPath };
|
|
3
|
+
export { assertImportPath };
|
|
4
|
+
export { clearFilesEnvMap };
|
|
5
|
+
import pc from '@brillout/picocolors';
|
|
6
|
+
import { assert, assertPosixPath, assertUsage, deepEqual, requireResolve } from '../../../../utils.js';
|
|
7
|
+
import { parseImportData } from './transformImports.js';
|
|
8
|
+
import path from 'path';
|
|
9
|
+
const filesEnvMap = new Map();
|
|
10
|
+
function resolveImport(configValue, importerFilePath, userRootDir, configEnv, configName) {
|
|
11
|
+
if (typeof configValue !== 'string')
|
|
12
|
+
return null;
|
|
13
|
+
const importData = parseImportData(configValue);
|
|
14
|
+
if (!importData)
|
|
15
|
+
return null;
|
|
16
|
+
const { importPath, exportName } = importData;
|
|
17
|
+
const filePathAbsoluteFilesystem = resolveImportPath(importData, importerFilePath);
|
|
18
|
+
assertFileEnv(filePathAbsoluteFilesystem ?? importPath, configEnv, configName);
|
|
19
|
+
const fileExportPathToShowToUser = exportName === 'default' || exportName === configName ? [] : [exportName];
|
|
20
|
+
if (importPath.startsWith('.')) {
|
|
21
|
+
// We need to resolve relative paths into absolute paths. Because the import paths are included in virtual files:
|
|
22
|
+
// ```
|
|
23
|
+
// [vite] Internal server error: Failed to resolve import "./onPageTransitionHooks" from "virtual:vike:pageConfigValuesAll:client:/pages/index". Does the file exist?
|
|
24
|
+
// ```
|
|
25
|
+
assertImportPath(filePathAbsoluteFilesystem, importData, importerFilePath);
|
|
26
|
+
const filePathRelativeToUserRootDir = resolveImportPath_relativeToUserRootDir(filePathAbsoluteFilesystem, importData, importerFilePath, userRootDir);
|
|
27
|
+
const filePath = {
|
|
28
|
+
filePathAbsoluteFilesystem,
|
|
29
|
+
filePathRelativeToUserRootDir,
|
|
30
|
+
filePathAbsoluteVite: filePathRelativeToUserRootDir,
|
|
31
|
+
filePathToShowToUser: filePathRelativeToUserRootDir,
|
|
32
|
+
importPathAbsolute: null
|
|
33
|
+
};
|
|
34
|
+
return {
|
|
35
|
+
...filePath,
|
|
36
|
+
fileExportName: exportName,
|
|
37
|
+
fileExportPathToShowToUser
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
// importPath can be:
|
|
42
|
+
// - an npm package import
|
|
43
|
+
// - a path alias
|
|
44
|
+
const filePath = {
|
|
45
|
+
filePathAbsoluteFilesystem,
|
|
46
|
+
filePathRelativeToUserRootDir: null,
|
|
47
|
+
filePathAbsoluteVite: importPath,
|
|
48
|
+
filePathToShowToUser: importPath,
|
|
49
|
+
importPathAbsolute: importPath
|
|
50
|
+
};
|
|
51
|
+
return {
|
|
52
|
+
...filePath,
|
|
53
|
+
fileExportName: exportName,
|
|
54
|
+
fileExportPathToShowToUser
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
function resolveImportPath_relativeToUserRootDir(filePathAbsoluteFilesystem, importData, configFilePath, userRootDir) {
|
|
59
|
+
assertPosixPath(userRootDir);
|
|
60
|
+
let filePathRelativeToUserRootDir;
|
|
61
|
+
if (filePathAbsoluteFilesystem.startsWith(userRootDir)) {
|
|
62
|
+
filePathRelativeToUserRootDir = getVitePathFromAbsolutePath(filePathAbsoluteFilesystem, userRootDir);
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
assertUsage(false, `${configFilePath.filePathToShowToUser} imports from a relative path ${pc.cyan(importData.importPath)} outside of ${userRootDir} which is forbidden: import from a relative path inside ${userRootDir}, or import from a dependency's package.json#exports entry instead`);
|
|
66
|
+
// None of the following works. Seems to be a Vite bug?
|
|
67
|
+
// /*
|
|
68
|
+
// assert(filePathAbsoluteFilesystem.startsWith('/'))
|
|
69
|
+
// filePath = `/@fs${filePathAbsoluteFilesystem}`
|
|
70
|
+
// /*/
|
|
71
|
+
// filePathRelativeToUserRootDir = path.posix.relative(userRootDir, filePathAbsoluteFilesystem)
|
|
72
|
+
// assert(filePathRelativeToUserRootDir.startsWith('../'))
|
|
73
|
+
// filePathRelativeToUserRootDir = '/' + filePathRelativeToUserRootDir
|
|
74
|
+
// //*/
|
|
75
|
+
}
|
|
76
|
+
assertPosixPath(filePathRelativeToUserRootDir);
|
|
77
|
+
assert(filePathRelativeToUserRootDir.startsWith('/'));
|
|
78
|
+
return filePathRelativeToUserRootDir;
|
|
79
|
+
}
|
|
80
|
+
function resolveImportPath(importData, importerFilePath) {
|
|
81
|
+
const importerFilePathAbsolute = importerFilePath.filePathAbsoluteFilesystem;
|
|
82
|
+
assertPosixPath(importerFilePathAbsolute);
|
|
83
|
+
const cwd = path.posix.dirname(importerFilePathAbsolute);
|
|
84
|
+
// We can't use import.meta.resolve() as of Junary 2023 (and probably for a lot longer): https://stackoverflow.com/questions/54977743/do-require-resolve-for-es-modules#comment137174954_62272600:~:text=But%20the%20argument%20parent%20(aka%20cwd)%20still%20requires%20a%20flag
|
|
85
|
+
// filePathAbsoluteFilesystem is expected to be null when importData.importPath is a Vite path alias
|
|
86
|
+
const filePathAbsoluteFilesystem = requireResolve(importData.importPath, cwd);
|
|
87
|
+
return filePathAbsoluteFilesystem;
|
|
88
|
+
}
|
|
89
|
+
function assertImportPath(filePathAbsoluteFilesystem, importData, importerFilePath) {
|
|
90
|
+
const { importPath: importPath, importStringWasGenerated, importString } = importData;
|
|
91
|
+
const { filePathToShowToUser } = importerFilePath;
|
|
92
|
+
if (!filePathAbsoluteFilesystem) {
|
|
93
|
+
const importPathString = pc.cyan(`'${importPath}'`);
|
|
94
|
+
const errIntro = importStringWasGenerated
|
|
95
|
+
? `The import path ${importPathString} in ${filePathToShowToUser}`
|
|
96
|
+
: `The import ${pc.cyan(importString)} defined in ${filePathToShowToUser}`;
|
|
97
|
+
const errIntro2 = `${errIntro} couldn't be resolved: does ${importPathString}`;
|
|
98
|
+
if (importPath.startsWith('.')) {
|
|
99
|
+
assertUsage(false, `${errIntro2} point to an existing file?`);
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
assertUsage(false, `${errIntro2} exist?`);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
function assertFileEnv(filePathForEnvCheck, configEnv, configName) {
|
|
107
|
+
assertPosixPath(filePathForEnvCheck);
|
|
108
|
+
if (!filesEnvMap.has(filePathForEnvCheck)) {
|
|
109
|
+
filesEnvMap.set(filePathForEnvCheck, []);
|
|
110
|
+
}
|
|
111
|
+
const fileEnv = filesEnvMap.get(filePathForEnvCheck);
|
|
112
|
+
fileEnv.push({ configEnv, configName });
|
|
113
|
+
const configDifferentEnv = fileEnv.filter((c) => !deepEqual(c.configEnv, configEnv))[0];
|
|
114
|
+
if (configDifferentEnv) {
|
|
115
|
+
assertUsage(false, [
|
|
116
|
+
`${filePathForEnvCheck} defines the value of configs living in different environments:`,
|
|
117
|
+
...[configDifferentEnv, { configName, configEnv }].map((c) => ` - config ${pc.cyan(c.configName)} which value lives in environment ${pc.cyan(JSON.stringify(c.configEnv))}`),
|
|
118
|
+
'Defining config values in the same file is allowed only if they live in the same environment, see https://vike.dev/header-file'
|
|
119
|
+
].join('\n'));
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
function clearFilesEnvMap() {
|
|
123
|
+
filesEnvMap.clear();
|
|
124
|
+
}
|
|
125
|
+
function getVitePathFromAbsolutePath(filePathAbsoluteFilesystem, root) {
|
|
126
|
+
assertPosixPath(filePathAbsoluteFilesystem);
|
|
127
|
+
assertPosixPath(root);
|
|
128
|
+
assert(filePathAbsoluteFilesystem.startsWith(root));
|
|
129
|
+
let vitePath = path.posix.relative(root, filePathAbsoluteFilesystem);
|
|
130
|
+
assert(!vitePath.startsWith('/') && !vitePath.startsWith('.'));
|
|
131
|
+
vitePath = '/' + vitePath;
|
|
132
|
+
return vitePath;
|
|
133
|
+
}
|
|
@@ -5,7 +5,7 @@ export { isImportData };
|
|
|
5
5
|
// Import attributes support: https://github.com/acornjs/acorn/issues/983
|
|
6
6
|
// - Isn't stage 4 yet: https://github.com/tc39/proposal-import-attributes
|
|
7
7
|
import { parse } from 'acorn';
|
|
8
|
-
import { assert, assertUsage, assertWarning, styleFileRE } from '
|
|
8
|
+
import { assert, assertUsage, assertWarning, styleFileRE } from '../../../../utils.js';
|
|
9
9
|
import pc from '@brillout/picocolors';
|
|
10
10
|
function transformImports(code, filePathToShowToUser2,
|
|
11
11
|
// For ./transformImports.spec.ts
|
|
@@ -23,13 +23,13 @@ skipWarnings) {
|
|
|
23
23
|
return;
|
|
24
24
|
const importPath = node.source.value;
|
|
25
25
|
assert(typeof importPath === 'string');
|
|
26
|
-
// - This doesn't work
|
|
26
|
+
// - This doesn't work. To make it work we would need to run esbuild twice: esbuild for TypeScript to JavaScript => transformImports() => esbuild for bundling.
|
|
27
27
|
// - Or we use an esbuild plugin to apply transformImports(). Maybe we can completely skip the need for acorn?
|
|
28
28
|
// - ?real breaks TypeScript, and TypeScript isn't working on supporting query params: https://github.com/microsoft/TypeScript/issues/10988#issuecomment-867135453
|
|
29
29
|
// - Import attributes would be the best.
|
|
30
30
|
// - But it only works with Node.js >=21: https://nodejs.org/api/esm.html#import-attributes
|
|
31
31
|
// - But it's probably ok to tell users "to use real imports you need Node.js 21 or above".
|
|
32
|
-
// - It
|
|
32
|
+
// - It works well with TypeScript: it doesn't complain upon `with { type: 'unknown-to-typescript' }` and go-to-definition & types are preserved: https://www.typescriptlang.org/docs/handbook/release-notes/typescript-5-3.html#import-attributes
|
|
33
33
|
// - Esbuid seems to support it: https://esbuild.github.io/plugins/#on-load-arguments:~:text=This%20contains%20a%20map%20of%20the%20import%20attributes%20that
|
|
34
34
|
// - acorn supports it over an acorn plugin: https://github.com/acornjs/acorn/issues/983
|
|
35
35
|
// - Maybe we can use an esbuild plugin instead of acorn to apply transformImports()?
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
export { transpileAndExecuteFile };
|
|
2
2
|
export { getConfigBuildErrorFormatted };
|
|
3
|
-
export { getConfigExecutionErrorIntroMsg
|
|
3
|
+
export { getConfigExecutionErrorIntroMsg };
|
|
4
4
|
export { isTmpFile };
|
|
5
5
|
import 'source-map-support/register.js';
|
|
6
|
-
import type { FilePathResolved } from '
|
|
6
|
+
import type { FilePathResolved } from '../../../../../../shared/page-configs/PageConfig.js';
|
|
7
7
|
declare function transpileAndExecuteFile(filePath: FilePathResolved, isValueFile: boolean, userRootDir: string, isConfigOfExtension?: boolean): Promise<{
|
|
8
8
|
fileExports: Record<string, unknown>;
|
|
9
9
|
}>;
|
|
@@ -1,29 +1,39 @@
|
|
|
1
1
|
export { transpileAndExecuteFile };
|
|
2
2
|
export { getConfigBuildErrorFormatted };
|
|
3
|
-
export { getConfigExecutionErrorIntroMsg
|
|
3
|
+
export { getConfigExecutionErrorIntroMsg };
|
|
4
4
|
export { isTmpFile };
|
|
5
5
|
import { build, formatMessages } from 'esbuild';
|
|
6
6
|
import fs from 'fs';
|
|
7
7
|
import path from 'path';
|
|
8
8
|
import pc from '@brillout/picocolors';
|
|
9
9
|
import { import_ } from '@brillout/import';
|
|
10
|
-
import { assertPosixPath, getRandomId, assertIsNotProductionRuntime, assert, unique, assertWarning, isObject, toPosixPath } from '
|
|
10
|
+
import { assertPosixPath, getRandomId, assertIsNotProductionRuntime, assert, unique, assertWarning, isObject, toPosixPath } from '../../../../utils.js';
|
|
11
11
|
import { isImportData, transformImports } from './transformImports.js';
|
|
12
|
-
import { vikeConfigDependencies } from '
|
|
12
|
+
import { vikeConfigDependencies } from '../getVikeConfig.js';
|
|
13
13
|
import 'source-map-support/register.js';
|
|
14
|
-
import { getConfigFileExport } from '
|
|
14
|
+
import { getConfigFileExport } from '../getConfigFileExport.js';
|
|
15
15
|
assertIsNotProductionRuntime();
|
|
16
16
|
async function transpileAndExecuteFile(filePath, isValueFile, userRootDir, isConfigOfExtension = false) {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
if (isConfigOfExtension) {
|
|
18
|
+
const fileExports = await executeFile(filePath.filePathAbsoluteFilesystem, filePath);
|
|
19
|
+
if (isHeaderFile(filePath.filePathAbsoluteFilesystem)) {
|
|
20
|
+
const filePathToShowToUser2 = getFilePathToShowToUser2(filePath);
|
|
21
|
+
assertWarning(false, `${filePathToShowToUser2} is a JavaScript header file (.h.js), but JavaScript header files don't apply to the config files of extensions`, { onlyOnce: true });
|
|
22
|
+
}
|
|
23
|
+
return { fileExports };
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
const { code, fileImportsTransformed } = await transpileFile(filePath, isValueFile, userRootDir);
|
|
27
|
+
const fileExports = await executeTranspiledFile(filePath, code, fileImportsTransformed, isValueFile);
|
|
28
|
+
return { fileExports };
|
|
29
|
+
}
|
|
20
30
|
}
|
|
21
|
-
async function transpileFile(filePath, isValueFile, userRootDir
|
|
31
|
+
async function transpileFile(filePath, isValueFile, userRootDir) {
|
|
22
32
|
const { filePathAbsoluteFilesystem } = filePath;
|
|
23
33
|
const filePathToShowToUser2 = getFilePathToShowToUser2(filePath);
|
|
24
34
|
assertPosixPath(filePathAbsoluteFilesystem);
|
|
25
35
|
vikeConfigDependencies.add(filePathAbsoluteFilesystem);
|
|
26
|
-
const importsAreTransformed = !
|
|
36
|
+
const importsAreTransformed = !isValueFile;
|
|
27
37
|
let code = await transpileWithEsbuild(filePath, userRootDir, importsAreTransformed, isValueFile);
|
|
28
38
|
let fileImportsTransformed = null;
|
|
29
39
|
if (importsAreTransformed) {
|
|
@@ -38,9 +48,6 @@ async function transpileFile(filePath, isValueFile, userRootDir, isConfigOfExten
|
|
|
38
48
|
if (isValueFile) {
|
|
39
49
|
assertWarning(false, `${filePathToShowToUser2} is a JavaScript header file (.h.js), but JavaScript header files only apply to +config.h.js, see https://vike.dev/header-file`, { onlyOnce: true });
|
|
40
50
|
}
|
|
41
|
-
else if (isConfigOfExtension) {
|
|
42
|
-
assertWarning(false, `${filePathToShowToUser2} is a JavaScript header file (.h.js), but JavaScript header files don't apply to the config files of extensions`, { onlyOnce: true });
|
|
43
|
-
}
|
|
44
51
|
else {
|
|
45
52
|
assert(false);
|
|
46
53
|
}
|
|
@@ -140,7 +147,7 @@ async function transpileWithEsbuild(filePath, userRootDir, importsAreTransformed
|
|
|
140
147
|
assert(typeof code === 'string');
|
|
141
148
|
return code;
|
|
142
149
|
}
|
|
143
|
-
async function
|
|
150
|
+
async function executeTranspiledFile(filePath, code, fileImportsTransformed, isValueFile) {
|
|
144
151
|
const { filePathAbsoluteFilesystem, filePathRelativeToUserRootDir } = filePath;
|
|
145
152
|
// Alternative to using a temporary file: https://github.com/vitejs/vite/pull/13269
|
|
146
153
|
// - But seems to break source maps, so I don't think it's worth it
|
|
@@ -149,28 +156,35 @@ async function executeFile(filePath, code, fileImportsTransformed, isValueFile)
|
|
|
149
156
|
const clean = () => fs.unlinkSync(filePathTmp);
|
|
150
157
|
let fileExports = {};
|
|
151
158
|
try {
|
|
152
|
-
fileExports = await
|
|
153
|
-
}
|
|
154
|
-
catch (err) {
|
|
155
|
-
triggerPrepareStackTrace(err);
|
|
156
|
-
const errIntroMsg = getErrIntroMsg('execute', filePath);
|
|
157
|
-
assert(isObject(err));
|
|
158
|
-
execErrIntroMsg.set(err, errIntroMsg);
|
|
159
|
-
throw err;
|
|
159
|
+
fileExports = await executeFile(filePathTmp, filePath);
|
|
160
160
|
}
|
|
161
161
|
finally {
|
|
162
162
|
clean();
|
|
163
163
|
}
|
|
164
|
-
// Return a plain JavaScript object
|
|
165
|
-
// - import() returns `[Module: null prototype] { default: { onRenderClient: '...' }}`
|
|
166
|
-
// - We don't need this special object
|
|
167
|
-
fileExports = { ...fileExports };
|
|
168
164
|
if (fileImportsTransformed && !isValueFile) {
|
|
169
165
|
assert(filePathRelativeToUserRootDir !== undefined);
|
|
170
166
|
const filePathToShowToUser2 = getFilePathToShowToUser2(filePath);
|
|
171
167
|
assertImportsAreReExported(fileImportsTransformed, fileExports, filePathToShowToUser2);
|
|
172
168
|
}
|
|
173
|
-
return
|
|
169
|
+
return fileExports;
|
|
170
|
+
}
|
|
171
|
+
async function executeFile(filePathToExecuteAbsoluteFilesystem, filePathSourceFile) {
|
|
172
|
+
let fileExports = {};
|
|
173
|
+
try {
|
|
174
|
+
fileExports = await import_(filePathToExecuteAbsoluteFilesystem);
|
|
175
|
+
}
|
|
176
|
+
catch (err) {
|
|
177
|
+
triggerPrepareStackTrace(err);
|
|
178
|
+
const errIntroMsg = getErrIntroMsg('execute', filePathSourceFile);
|
|
179
|
+
assert(isObject(err));
|
|
180
|
+
execErrIntroMsg.set(err, errIntroMsg);
|
|
181
|
+
throw err;
|
|
182
|
+
}
|
|
183
|
+
// Return a plain JavaScript object:
|
|
184
|
+
// - import() returns `[Module: null prototype] { default: { onRenderClient: '...' }}`
|
|
185
|
+
// - We don't need this special object.
|
|
186
|
+
fileExports = { ...fileExports };
|
|
187
|
+
return fileExports;
|
|
174
188
|
}
|
|
175
189
|
const formatted = '_formatted';
|
|
176
190
|
function getConfigBuildErrorFormatted(err) {
|
|
@@ -200,10 +214,10 @@ function getConfigExecutionErrorIntroMsg(err) {
|
|
|
200
214
|
return errIntroMsg ?? null;
|
|
201
215
|
}
|
|
202
216
|
const tmpPrefix = `[build-`;
|
|
203
|
-
function getFilePathTmp(
|
|
204
|
-
assertPosixPath(
|
|
205
|
-
const dirname = path.posix.dirname(
|
|
206
|
-
const filename = path.posix.basename(
|
|
217
|
+
function getFilePathTmp(filePathAbsoluteFilesystem) {
|
|
218
|
+
assertPosixPath(filePathAbsoluteFilesystem);
|
|
219
|
+
const dirname = path.posix.dirname(filePathAbsoluteFilesystem);
|
|
220
|
+
const filename = path.posix.basename(filePathAbsoluteFilesystem);
|
|
207
221
|
// Syntax with semicolon `[build:${/*...*/}]` doesn't work on Windows: https://github.com/vikejs/vike/issues/800#issuecomment-1517329455
|
|
208
222
|
const tag = `${tmpPrefix}${getRandomId(12)}]`;
|
|
209
223
|
const filePathTmp = path.posix.join(dirname, `${tag}${filename}.mjs`);
|
|
@@ -2,9 +2,22 @@ export { getVikeConfig };
|
|
|
2
2
|
export { reloadVikeConfig };
|
|
3
3
|
export { vikeConfigDependencies };
|
|
4
4
|
export { isVikeConfigFile };
|
|
5
|
-
|
|
5
|
+
export type { InterfaceValueFile };
|
|
6
|
+
import type { PageConfigGlobalBuildTime, PageConfigBuildTime, FilePathResolved } from '../../../../../shared/page-configs/PageConfig.js';
|
|
6
7
|
import type { ExtensionResolved } from '../../../../../shared/ConfigVike.js';
|
|
7
8
|
import type { ResolvedConfig } from 'vite';
|
|
9
|
+
type InterfaceFileCommons = {
|
|
10
|
+
filePath: FilePathResolved;
|
|
11
|
+
fileExportsByConfigName: Record<ConfigName, {
|
|
12
|
+
configValue?: unknown;
|
|
13
|
+
}>;
|
|
14
|
+
};
|
|
15
|
+
type InterfaceValueFile = InterfaceFileCommons & {
|
|
16
|
+
isConfigFile: false;
|
|
17
|
+
isValueFile: true;
|
|
18
|
+
configName: string;
|
|
19
|
+
};
|
|
20
|
+
type ConfigName = string;
|
|
8
21
|
type VikeConfig = {
|
|
9
22
|
pageConfigs: PageConfigBuildTime[];
|
|
10
23
|
pageConfigGlobal: PageConfigGlobalBuildTime;
|