vike 0.4.159 → 0.4.160-commit-30d535e
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/index.js +20 -1
- package/dist/cjs/node/plugin/plugins/autoFullBuild.js +2 -2
- package/dist/cjs/node/plugin/plugins/buildConfig.js +9 -0
- package/dist/cjs/node/plugin/plugins/commonConfig.js +1 -1
- package/dist/cjs/node/plugin/plugins/config/stemUtils.js +1 -1
- package/dist/cjs/node/plugin/plugins/devConfig/index.js +1 -1
- package/dist/cjs/node/plugin/plugins/importBuild/index.js +1 -1
- package/dist/cjs/node/plugin/plugins/importUserCode/v1-design/getConfigFileExport.js +18 -0
- package/dist/cjs/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/crawlPlusFiles.js +1 -5
- package/dist/cjs/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/filesystemRouting.js +28 -46
- package/dist/cjs/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/loadFileAtConfigTime.js +129 -0
- package/dist/cjs/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/resolveFilePath.js +33 -0
- package/dist/cjs/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/resolveImportPath.js +139 -0
- package/dist/cjs/node/plugin/plugins/importUserCode/v1-design/{replaceImportStatements.js → getVikeConfig/transformFileImports.js} +44 -13
- package/dist/cjs/node/plugin/plugins/importUserCode/v1-design/{transpileAndExecuteFile.js → getVikeConfig/transpileAndExecuteFile.js} +105 -78
- package/dist/cjs/node/plugin/plugins/importUserCode/v1-design/getVikeConfig.js +201 -382
- package/dist/cjs/node/plugin/plugins/previewConfig.js +1 -1
- package/dist/cjs/node/plugin/shared/getHttpRequestAsyncStore.js +1 -1
- package/dist/cjs/node/plugin/shared/loggerNotProd/log.js +3 -3
- package/dist/cjs/node/plugin/shared/loggerNotProd.js +1 -1
- package/dist/cjs/node/plugin/utils.js +1 -2
- package/dist/cjs/node/prerender/runPrerender.js +12 -5
- package/dist/cjs/node/runtime/globalContext.js +7 -3
- package/dist/cjs/node/runtime/html/injectAssets/getHtmlTags.js +2 -2
- package/dist/cjs/node/runtime/html/renderHtml.js +1 -1
- package/dist/cjs/node/runtime/html/stream.js +2 -2
- package/dist/cjs/node/runtime/renderPage/executeOnRenderHtmlHook.js +2 -2
- package/dist/cjs/node/runtime/renderPage/getHttpResponseBody.js +1 -1
- package/dist/cjs/node/runtime/renderPage/loadUserFilesServerSide.js +1 -1
- package/dist/cjs/node/runtime/renderPage/{logHintForCjsEsmError.js → logErrorHint.js} +81 -43
- package/dist/cjs/node/runtime/renderPage/loggerProd.js +3 -3
- package/dist/cjs/node/runtime/utils.js +1 -1
- package/dist/cjs/shared/page-configs/assertPlusFileExport.js +44 -0
- package/dist/cjs/shared/page-configs/serialize/parseConfigValuesImported.js +54 -27
- package/dist/cjs/shared/route/abort.js +1 -1
- package/dist/cjs/shared/route/executeGuardHook.js +3 -2
- package/dist/cjs/shared/utils.js +0 -1
- package/dist/cjs/utils/assert.js +5 -6
- package/dist/cjs/utils/assertIsNotProductionRuntime.js +35 -17
- package/dist/cjs/utils/{findUserPackageJsonPath.js → findFile.js} +11 -8
- package/dist/cjs/utils/nodeEnv.js +33 -1
- package/dist/cjs/utils/objectKeys.js +19 -3
- package/dist/cjs/utils/projectInfo.js +2 -4
- package/dist/cjs/utils/sorter.js +62 -1
- package/dist/esm/node/plugin/index.js +21 -2
- package/dist/esm/node/plugin/plugins/autoFullBuild.js +2 -2
- package/dist/esm/node/plugin/plugins/buildConfig.js +10 -1
- package/dist/esm/node/plugin/plugins/commonConfig.js +2 -2
- package/dist/esm/node/plugin/plugins/config/stemUtils.js +2 -2
- package/dist/esm/node/plugin/plugins/devConfig/index.js +2 -2
- package/dist/esm/node/plugin/plugins/importBuild/index.js +2 -2
- package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getConfigFileExport.d.ts +2 -0
- package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getConfigFileExport.js +12 -0
- package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/configDefinitionsBuiltIn.d.ts +8 -1
- package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/crawlPlusFiles.d.ts +0 -1
- package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/crawlPlusFiles.js +1 -5
- package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/filesystemRouting.d.ts +39 -12
- package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/filesystemRouting.js +29 -47
- package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/loadFileAtConfigTime.d.ts +21 -0
- package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/loadFileAtConfigTime.js +123 -0
- package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/resolveFilePath.d.ts +5 -0
- package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/resolveFilePath.js +27 -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/{replaceImportStatements.d.ts → getVikeConfig/transformFileImports.d.ts} +5 -5
- package/dist/esm/node/plugin/plugins/importUserCode/v1-design/{replaceImportStatements.js → getVikeConfig/transformFileImports.js} +43 -12
- package/dist/esm/node/plugin/plugins/importUserCode/v1-design/{transpileAndExecuteFile.d.ts → getVikeConfig/transpileAndExecuteFile.d.ts} +3 -3
- package/dist/esm/node/plugin/plugins/importUserCode/v1-design/{transpileAndExecuteFile.js → getVikeConfig/transpileAndExecuteFile.js} +105 -78
- package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig.d.ts +16 -1
- package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig.js +199 -380
- package/dist/esm/node/plugin/plugins/previewConfig.js +2 -2
- package/dist/esm/node/plugin/shared/getHttpRequestAsyncStore.js +1 -1
- package/dist/esm/node/plugin/shared/loggerNotProd/log.js +3 -3
- package/dist/esm/node/plugin/shared/loggerNotProd.js +1 -1
- package/dist/esm/node/plugin/utils.d.ts +1 -2
- package/dist/esm/node/plugin/utils.js +1 -2
- package/dist/esm/node/prerender/runPrerender.js +13 -6
- package/dist/esm/node/runtime/globalContext.js +8 -4
- package/dist/esm/node/runtime/html/injectAssets/getHtmlTags.js +2 -2
- package/dist/esm/node/runtime/html/renderHtml.js +1 -1
- package/dist/esm/node/runtime/html/stream.js +2 -2
- package/dist/esm/node/runtime/renderPage/executeOnRenderHtmlHook.js +2 -2
- package/dist/esm/node/runtime/renderPage/getHttpResponseBody.js +1 -1
- package/dist/esm/node/runtime/renderPage/loadUserFilesServerSide.js +1 -1
- package/dist/esm/node/runtime/renderPage/logErrorHint.d.ts +8 -0
- package/dist/esm/node/runtime/renderPage/{logHintForCjsEsmError.js → logErrorHint.js} +80 -42
- package/dist/esm/node/runtime/renderPage/loggerProd.js +3 -3
- package/dist/esm/node/runtime/utils.d.ts +1 -1
- package/dist/esm/node/runtime/utils.js +1 -1
- package/dist/esm/shared/page-configs/Config.d.ts +1 -1
- package/dist/esm/shared/page-configs/PageConfig.d.ts +6 -0
- package/dist/esm/shared/page-configs/assertPlusFileExport.d.ts +2 -0
- package/dist/esm/shared/page-configs/assertPlusFileExport.js +38 -0
- package/dist/esm/shared/page-configs/serialize/parseConfigValuesImported.js +54 -27
- package/dist/esm/shared/route/abort.js +2 -2
- package/dist/esm/shared/route/executeGuardHook.js +3 -2
- package/dist/esm/shared/utils.d.ts +0 -1
- package/dist/esm/shared/utils.js +0 -1
- package/dist/esm/utils/assert.js +5 -6
- package/dist/esm/utils/assertIsNotProductionRuntime.d.ts +8 -6
- package/dist/esm/utils/assertIsNotProductionRuntime.js +35 -17
- package/dist/esm/utils/debug.d.ts +1 -1
- package/dist/esm/utils/findFile.d.ts +3 -0
- package/dist/esm/utils/findFile.js +21 -0
- package/dist/esm/utils/nodeEnv.d.ts +6 -0
- package/dist/esm/utils/nodeEnv.js +29 -0
- package/dist/esm/utils/objectKeys.d.ts +10 -1
- package/dist/esm/utils/objectKeys.js +20 -3
- package/dist/esm/utils/projectInfo.d.ts +2 -8
- package/dist/esm/utils/projectInfo.js +2 -4
- package/dist/esm/utils/sorter.d.ts +59 -0
- package/dist/esm/utils/sorter.js +61 -0
- package/package.json +1 -1
- package/dist/cjs/shared/page-configs/assertExports.js +0 -67
- package/dist/cjs/utils/objectEntries.js +0 -8
- package/dist/esm/node/runtime/renderPage/logHintForCjsEsmError.d.ts +0 -13
- package/dist/esm/shared/page-configs/assertExports.d.ts +0 -6
- package/dist/esm/shared/page-configs/assertExports.js +0 -61
- package/dist/esm/utils/findUserPackageJsonPath.d.ts +0 -2
- package/dist/esm/utils/findUserPackageJsonPath.js +0 -18
- package/dist/esm/utils/objectEntries.d.ts +0 -4
- package/dist/esm/utils/objectEntries.js +0 -5
- /package/dist/cjs/node/runtime/renderPage/{logHintForCjsEsmError → logErrorHint}/errors.js +0 -0
- /package/dist/esm/node/runtime/renderPage/{logHintForCjsEsmError → logErrorHint}/errors.d.ts +0 -0
- /package/dist/esm/node/runtime/renderPage/{logHintForCjsEsmError → logErrorHint}/errors.js +0 -0
|
@@ -1,21 +1,50 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { transformFileImports };
|
|
2
2
|
export { parseImportData };
|
|
3
3
|
export { isImportData };
|
|
4
4
|
// Playground: https://github.com/brillout/acorn-playground
|
|
5
|
+
// Import attributes support: https://github.com/acornjs/acorn/issues/983
|
|
6
|
+
// - Isn't stage 4 yet: https://github.com/tc39/proposal-import-attributes
|
|
5
7
|
import { parse } from 'acorn';
|
|
6
|
-
import { assert, assertUsage, assertWarning, styleFileRE } from '
|
|
8
|
+
import { assert, assertUsage, assertWarning, styleFileRE } from '../../../../utils.js';
|
|
7
9
|
import pc from '@brillout/picocolors';
|
|
8
|
-
function
|
|
10
|
+
function transformFileImports(code, filePathToShowToUser2,
|
|
11
|
+
// For ./transformFileImports.spec.ts
|
|
12
|
+
skipWarnings) {
|
|
9
13
|
const spliceOperations = [];
|
|
10
|
-
const
|
|
14
|
+
const fileImportsTransformed = [];
|
|
15
|
+
// Performance trick
|
|
16
|
+
if (!code.includes('import'))
|
|
17
|
+
return { noTransformation: true };
|
|
11
18
|
const imports = getImports(code);
|
|
12
19
|
if (imports.length === 0)
|
|
13
|
-
return {
|
|
20
|
+
return { noTransformation: true };
|
|
14
21
|
imports.forEach((node) => {
|
|
15
22
|
if (node.type !== 'ImportDeclaration')
|
|
16
23
|
return;
|
|
17
24
|
const importPath = node.source.value;
|
|
18
25
|
assert(typeof importPath === 'string');
|
|
26
|
+
// - This doesn't work. To make it work we would need to run esbuild twice: esbuild for TypeScript to JavaScript => transformFileImports() => esbuild for bundling.
|
|
27
|
+
// - Or we use an esbuild plugin to apply transformFileImports(). Maybe we can completely skip the need for acorn?
|
|
28
|
+
// - ?real breaks TypeScript, and TypeScript isn't working on supporting query params: https://github.com/microsoft/TypeScript/issues/10988#issuecomment-867135453
|
|
29
|
+
// - Import attributes would be the best.
|
|
30
|
+
// - But it only works with Node.js >=21: https://nodejs.org/api/esm.html#import-attributes
|
|
31
|
+
// - But it's probably ok to tell users "to use real imports you need Node.js 21 or above".
|
|
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
|
+
// - Esbuid seems to support it: https://esbuild.github.io/plugins/#on-load-arguments:~:text=This%20contains%20a%20map%20of%20the%20import%20attributes%20that
|
|
34
|
+
// - acorn supports it over an acorn plugin: https://github.com/acornjs/acorn/issues/983
|
|
35
|
+
// - Maybe we can use an esbuild plugin instead of acorn to apply transformFileImports()?
|
|
36
|
+
// - Using a magic comment `// @vike-real-import` is tricky:
|
|
37
|
+
// - Esbuild removes comments: https://github.com/evanw/esbuild/issues/1439#issuecomment-877656182
|
|
38
|
+
// - Using source maps to track these magic comments is brittle (source maps can easily break)
|
|
39
|
+
if (importPath.endsWith('?real')) {
|
|
40
|
+
const { start, end } = node.source;
|
|
41
|
+
spliceOperations.push({
|
|
42
|
+
start,
|
|
43
|
+
end,
|
|
44
|
+
replacement: importPath.slice(0, -1 * '?real'.length)
|
|
45
|
+
});
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
19
48
|
const { start, end } = node;
|
|
20
49
|
const importStatementCode = code.slice(start, end);
|
|
21
50
|
// No variable imported
|
|
@@ -29,13 +58,15 @@ function replaceImportStatements(code, filePathToShowToUser) {
|
|
|
29
58
|
quote = pc.bold(pc.red(quote));
|
|
30
59
|
}
|
|
31
60
|
const errMsg = [
|
|
32
|
-
`As explained in https://vike.dev/header-file the following import in ${
|
|
61
|
+
`As explained in https://vike.dev/header-file the following import in ${filePathToShowToUser2} has no effect:`,
|
|
33
62
|
quote
|
|
34
63
|
].join('\n');
|
|
35
|
-
if (!
|
|
36
|
-
|
|
64
|
+
if (!skipWarnings) {
|
|
65
|
+
if (!isWarning) {
|
|
66
|
+
assertUsage(false, errMsg);
|
|
67
|
+
}
|
|
68
|
+
assertWarning(false, errMsg, { onlyOnce: true });
|
|
37
69
|
}
|
|
38
|
-
assertWarning(false, errMsg, { onlyOnce: true });
|
|
39
70
|
}
|
|
40
71
|
let replacement = '';
|
|
41
72
|
node.specifiers.forEach((specifier) => {
|
|
@@ -57,7 +88,7 @@ function replaceImportStatements(code, filePathToShowToUser) {
|
|
|
57
88
|
})();
|
|
58
89
|
const importString = serializeImportData({ importPath, exportName, importStringWasGenerated: true });
|
|
59
90
|
replacement += `const ${importLocalName} = '${importString}';`;
|
|
60
|
-
|
|
91
|
+
fileImportsTransformed.push({
|
|
61
92
|
importStatementCode,
|
|
62
93
|
importString,
|
|
63
94
|
importLocalName
|
|
@@ -70,7 +101,7 @@ function replaceImportStatements(code, filePathToShowToUser) {
|
|
|
70
101
|
});
|
|
71
102
|
});
|
|
72
103
|
const codeMod = spliceMany(code, spliceOperations);
|
|
73
|
-
return { code: codeMod,
|
|
104
|
+
return { code: codeMod, fileImportsTransformed, noTransformation: false };
|
|
74
105
|
}
|
|
75
106
|
function getImports(code) {
|
|
76
107
|
const { body } = parse(code, {
|
|
@@ -137,7 +168,7 @@ function spliceMany(str, operations) {
|
|
|
137
168
|
.join('');
|
|
138
169
|
endPrev = end;
|
|
139
170
|
});
|
|
140
|
-
strMod += str.slice(endPrev, str.length
|
|
171
|
+
strMod += str.slice(endPrev, str.length);
|
|
141
172
|
return strMod;
|
|
142
173
|
}
|
|
143
174
|
function indent(str) {
|
|
@@ -1,10 +1,10 @@
|
|
|
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 '
|
|
7
|
-
declare function transpileAndExecuteFile(filePath: FilePathResolved,
|
|
6
|
+
import type { FilePathResolved } from '../../../../../../shared/page-configs/PageConfig.js';
|
|
7
|
+
declare function transpileAndExecuteFile(filePath: FilePathResolved, transformImports: boolean, userRootDir: string, doNotTranspile?: boolean): Promise<{
|
|
8
8
|
fileExports: Record<string, unknown>;
|
|
9
9
|
}>;
|
|
10
10
|
declare function getConfigBuildErrorFormatted(err: unknown): null | string;
|
|
@@ -1,63 +1,73 @@
|
|
|
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 '
|
|
11
|
-
import { isImportData,
|
|
12
|
-
import { vikeConfigDependencies } from '
|
|
10
|
+
import { assertPosixPath, getRandomId, assertIsNotProductionRuntime, assert, unique, assertWarning, isObject, toPosixPath } from '../../../../utils.js';
|
|
11
|
+
import { isImportData, transformFileImports } from './transformFileImports.js';
|
|
12
|
+
import { vikeConfigDependencies } from '../getVikeConfig.js';
|
|
13
13
|
import 'source-map-support/register.js';
|
|
14
|
-
import {
|
|
14
|
+
import { getConfigFileExport } from '../getConfigFileExport.js';
|
|
15
15
|
assertIsNotProductionRuntime();
|
|
16
|
-
async function transpileAndExecuteFile(filePath,
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
16
|
+
async function transpileAndExecuteFile(filePath, transformImports, userRootDir, doNotTranspile = false) {
|
|
17
|
+
if (doNotTranspile) {
|
|
18
|
+
assert(!transformImports);
|
|
19
|
+
const fileExports = await executeFile(filePath.filePathAbsoluteFilesystem, filePath);
|
|
20
|
+
if (isHeaderFile(filePath.filePathAbsoluteFilesystem)) {
|
|
21
|
+
const filePathToShowToUser2 = getFilePathToShowToUser2(filePath);
|
|
22
|
+
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 });
|
|
23
|
+
}
|
|
24
|
+
return { fileExports };
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
const { code, fileImportsTransformed } = await transpileFile(filePath, transformImports, userRootDir);
|
|
28
|
+
const fileExports = await executeTranspiledFile(filePath, code, fileImportsTransformed);
|
|
29
|
+
return { fileExports };
|
|
30
|
+
}
|
|
20
31
|
}
|
|
21
|
-
async function transpileFile(filePath,
|
|
32
|
+
async function transpileFile(filePath, transformImports, userRootDir) {
|
|
22
33
|
const { filePathAbsoluteFilesystem } = filePath;
|
|
34
|
+
const filePathToShowToUser2 = getFilePathToShowToUser2(filePath);
|
|
23
35
|
assertPosixPath(filePathAbsoluteFilesystem);
|
|
24
36
|
vikeConfigDependencies.add(filePathAbsoluteFilesystem);
|
|
25
|
-
let code = await transpileWithEsbuild(filePath,
|
|
26
|
-
let
|
|
27
|
-
{
|
|
28
|
-
const res =
|
|
37
|
+
let code = await transpileWithEsbuild(filePath, userRootDir, transformImports);
|
|
38
|
+
let fileImportsTransformed = null;
|
|
39
|
+
if (transformImports) {
|
|
40
|
+
const res = transformFileImports_(code, filePath);
|
|
29
41
|
if (res) {
|
|
30
42
|
code = res.code;
|
|
31
|
-
|
|
43
|
+
fileImportsTransformed = res.fileImportsTransformed;
|
|
32
44
|
}
|
|
33
45
|
}
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
const { filePathAbsoluteFilesystem, filePathToShowToUser } = filePath;
|
|
39
|
-
assertPosixPath(filePathAbsoluteFilesystem);
|
|
40
|
-
const isHeader = isHeaderFile(filePathAbsoluteFilesystem);
|
|
41
|
-
const isPageConfigFile = !isValueFile;
|
|
42
|
-
if (!isHeader && !isPageConfigFile) {
|
|
43
|
-
return null;
|
|
46
|
+
else {
|
|
47
|
+
if (isHeaderFile(filePathAbsoluteFilesystem)) {
|
|
48
|
+
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 });
|
|
49
|
+
}
|
|
44
50
|
}
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
51
|
+
return { code, fileImportsTransformed };
|
|
52
|
+
}
|
|
53
|
+
function transformFileImports_(codeOriginal, filePath) {
|
|
54
|
+
const { filePathAbsoluteFilesystem } = filePath;
|
|
55
|
+
const filePathToShowToUser2 = getFilePathToShowToUser2(filePath);
|
|
56
|
+
// Replace import statements with import strings
|
|
57
|
+
const res = transformFileImports(codeOriginal, filePathToShowToUser2);
|
|
58
|
+
if (res.noTransformation) {
|
|
49
59
|
return null;
|
|
50
60
|
}
|
|
51
|
-
const { code,
|
|
52
|
-
if (!
|
|
53
|
-
const filePathCorrect = appendHeaderFileExtension(
|
|
54
|
-
assertWarning(false, `Rename ${
|
|
61
|
+
const { code, fileImportsTransformed } = res;
|
|
62
|
+
if (!isHeaderFile(filePathAbsoluteFilesystem)) {
|
|
63
|
+
const filePathCorrect = appendHeaderFileExtension(filePathToShowToUser2);
|
|
64
|
+
assertWarning(false, `Rename ${filePathToShowToUser2} to ${filePathCorrect}, see https://vike.dev/header-file`, {
|
|
55
65
|
onlyOnce: true
|
|
56
66
|
});
|
|
57
67
|
}
|
|
58
|
-
return { code,
|
|
68
|
+
return { code, fileImportsTransformed };
|
|
59
69
|
}
|
|
60
|
-
async function transpileWithEsbuild(filePath,
|
|
70
|
+
async function transpileWithEsbuild(filePath, userRootDir, transformImports) {
|
|
61
71
|
const entryFilePath = filePath.filePathAbsoluteFilesystem;
|
|
62
72
|
const entryFileDir = path.posix.dirname(entryFilePath);
|
|
63
73
|
const options = {
|
|
@@ -73,22 +83,26 @@ async function transpileWithEsbuild(filePath, bundle, userRootDir) {
|
|
|
73
83
|
'NEVER_EMITTED.js'),
|
|
74
84
|
logLevel: 'silent',
|
|
75
85
|
format: 'esm',
|
|
76
|
-
|
|
86
|
+
absWorkingDir: userRootDir,
|
|
87
|
+
// Disable tree-shaking to avoid dead-code elimination, so that unused imports aren't removed.
|
|
88
|
+
// Esbuild still sometimes removes unused imports because of TypeScript: https://github.com/evanw/esbuild/issues/3034
|
|
89
|
+
treeShaking: false,
|
|
77
90
|
minify: false,
|
|
78
|
-
metafile:
|
|
79
|
-
|
|
91
|
+
metafile: !transformImports,
|
|
92
|
+
// We cannot bundle imports that are meant to be transformed
|
|
93
|
+
bundle: !transformImports
|
|
80
94
|
};
|
|
81
|
-
|
|
82
|
-
|
|
95
|
+
// Track dependencies
|
|
96
|
+
if (!transformImports) {
|
|
83
97
|
options.packages = 'external';
|
|
84
98
|
options.plugins = [
|
|
85
99
|
{
|
|
86
|
-
name: 'vike:
|
|
100
|
+
name: 'vike:dependency-tracker',
|
|
87
101
|
setup(b) {
|
|
88
102
|
b.onLoad({ filter: /./ }, (args) => {
|
|
103
|
+
// We collect the dependency `args.path` in case the bulid fails (upon build error => error is thrown => no metafile)
|
|
89
104
|
let { path } = args;
|
|
90
105
|
path = toPosixPath(path);
|
|
91
|
-
// We collect the dependency args.path in case it fails to build (upon build error => error is thrown => no metafile)
|
|
92
106
|
vikeConfigDependencies.add(path);
|
|
93
107
|
return undefined;
|
|
94
108
|
});
|
|
@@ -105,11 +119,6 @@ async function transpileWithEsbuild(filePath, bundle, userRootDir) {
|
|
|
105
119
|
}
|
|
106
120
|
];
|
|
107
121
|
}
|
|
108
|
-
else {
|
|
109
|
-
// Avoid dead-code elimination to ensure unused imports aren't removed.
|
|
110
|
-
// Esbuild still sometimes removes unused imports because of TypeScript: https://github.com/evanw/esbuild/issues/3034
|
|
111
|
-
options.treeShaking = false;
|
|
112
|
-
}
|
|
113
122
|
let result;
|
|
114
123
|
try {
|
|
115
124
|
result = await build(options);
|
|
@@ -118,7 +127,8 @@ async function transpileWithEsbuild(filePath, bundle, userRootDir) {
|
|
|
118
127
|
await formatBuildErr(err, filePath);
|
|
119
128
|
throw err;
|
|
120
129
|
}
|
|
121
|
-
|
|
130
|
+
// Track dependencies
|
|
131
|
+
if (!transformImports) {
|
|
122
132
|
assert(result.metafile);
|
|
123
133
|
Object.keys(result.metafile.inputs).forEach((filePathRelative) => {
|
|
124
134
|
filePathRelative = toPosixPath(filePathRelative);
|
|
@@ -131,7 +141,7 @@ async function transpileWithEsbuild(filePath, bundle, userRootDir) {
|
|
|
131
141
|
assert(typeof code === 'string');
|
|
132
142
|
return code;
|
|
133
143
|
}
|
|
134
|
-
async function
|
|
144
|
+
async function executeTranspiledFile(filePath, code, fileImportsTransformed) {
|
|
135
145
|
const { filePathAbsoluteFilesystem, filePathRelativeToUserRootDir } = filePath;
|
|
136
146
|
// Alternative to using a temporary file: https://github.com/vitejs/vite/pull/13269
|
|
137
147
|
// - But seems to break source maps, so I don't think it's worth it
|
|
@@ -140,28 +150,35 @@ async function executeFile(filePath, code, fileImports, isValueFile) {
|
|
|
140
150
|
const clean = () => fs.unlinkSync(filePathTmp);
|
|
141
151
|
let fileExports = {};
|
|
142
152
|
try {
|
|
143
|
-
fileExports = await
|
|
153
|
+
fileExports = await executeFile(filePathTmp, filePath);
|
|
154
|
+
}
|
|
155
|
+
finally {
|
|
156
|
+
clean();
|
|
157
|
+
}
|
|
158
|
+
if (fileImportsTransformed) {
|
|
159
|
+
assert(filePathRelativeToUserRootDir !== undefined);
|
|
160
|
+
const filePathToShowToUser2 = getFilePathToShowToUser2(filePath);
|
|
161
|
+
assertImportsAreReExported(fileImportsTransformed, fileExports, filePathToShowToUser2);
|
|
162
|
+
}
|
|
163
|
+
return fileExports;
|
|
164
|
+
}
|
|
165
|
+
async function executeFile(filePathToExecuteAbsoluteFilesystem, filePathSourceFile) {
|
|
166
|
+
let fileExports = {};
|
|
167
|
+
try {
|
|
168
|
+
fileExports = await import_(filePathToExecuteAbsoluteFilesystem);
|
|
144
169
|
}
|
|
145
170
|
catch (err) {
|
|
146
171
|
triggerPrepareStackTrace(err);
|
|
147
|
-
const errIntroMsg = getErrIntroMsg('execute',
|
|
172
|
+
const errIntroMsg = getErrIntroMsg('execute', filePathSourceFile);
|
|
148
173
|
assert(isObject(err));
|
|
149
174
|
execErrIntroMsg.set(err, errIntroMsg);
|
|
150
175
|
throw err;
|
|
151
176
|
}
|
|
152
|
-
|
|
153
|
-
clean();
|
|
154
|
-
}
|
|
155
|
-
// Return a plain JavaScript object
|
|
177
|
+
// Return a plain JavaScript object:
|
|
156
178
|
// - import() returns `[Module: null prototype] { default: { onRenderClient: '...' }}`
|
|
157
|
-
// - We don't need this special object
|
|
179
|
+
// - We don't need this special object.
|
|
158
180
|
fileExports = { ...fileExports };
|
|
159
|
-
|
|
160
|
-
assert(filePathRelativeToUserRootDir !== undefined);
|
|
161
|
-
const filePathToShowToUser = filePathRelativeToUserRootDir ?? filePathAbsoluteFilesystem;
|
|
162
|
-
assertImportsAreReExported(fileImports, fileExports, filePathToShowToUser);
|
|
163
|
-
}
|
|
164
|
-
return { fileExports };
|
|
181
|
+
return fileExports;
|
|
165
182
|
}
|
|
166
183
|
const formatted = '_formatted';
|
|
167
184
|
function getConfigBuildErrorFormatted(err) {
|
|
@@ -191,10 +208,10 @@ function getConfigExecutionErrorIntroMsg(err) {
|
|
|
191
208
|
return errIntroMsg ?? null;
|
|
192
209
|
}
|
|
193
210
|
const tmpPrefix = `[build-`;
|
|
194
|
-
function getFilePathTmp(
|
|
195
|
-
assertPosixPath(
|
|
196
|
-
const dirname = path.posix.dirname(
|
|
197
|
-
const filename = path.posix.basename(
|
|
211
|
+
function getFilePathTmp(filePathAbsoluteFilesystem) {
|
|
212
|
+
assertPosixPath(filePathAbsoluteFilesystem);
|
|
213
|
+
const dirname = path.posix.dirname(filePathAbsoluteFilesystem);
|
|
214
|
+
const filename = path.posix.basename(filePathAbsoluteFilesystem);
|
|
198
215
|
// Syntax with semicolon `[build:${/*...*/}]` doesn't work on Windows: https://github.com/vikejs/vike/issues/800#issuecomment-1517329455
|
|
199
216
|
const tag = `${tmpPrefix}${getRandomId(12)}]`;
|
|
200
217
|
const filePathTmp = path.posix.join(dirname, `${tag}${filename}.mjs`);
|
|
@@ -205,29 +222,29 @@ function isTmpFile(filePath) {
|
|
|
205
222
|
const fileName = path.posix.basename(filePath);
|
|
206
223
|
return fileName.startsWith(tmpPrefix);
|
|
207
224
|
}
|
|
208
|
-
function assertImportsAreReExported(
|
|
209
|
-
|
|
210
|
-
const exportedStrings = getExportedStrings(
|
|
225
|
+
function assertImportsAreReExported(fileImportsTransformed, fileExports, filePathToShowToUser2) {
|
|
226
|
+
const fileExport = getConfigFileExport(fileExports, filePathToShowToUser2);
|
|
227
|
+
const exportedStrings = getExportedStrings(fileExport);
|
|
211
228
|
Object.values(exportedStrings).forEach((exportVal) => {
|
|
212
229
|
if (typeof exportVal !== 'string')
|
|
213
230
|
return;
|
|
214
231
|
if (!isImportData(exportVal))
|
|
215
232
|
return;
|
|
216
233
|
const importString = exportVal;
|
|
217
|
-
|
|
234
|
+
fileImportsTransformed.forEach((fileImport) => {
|
|
218
235
|
if (fileImport.importString === importString) {
|
|
219
236
|
fileImport.isReExported = true;
|
|
220
237
|
}
|
|
221
238
|
});
|
|
222
239
|
});
|
|
223
|
-
const
|
|
224
|
-
if (
|
|
240
|
+
const fileImportsTransformedUnused = fileImportsTransformed.filter((fi) => !fi.isReExported);
|
|
241
|
+
if (fileImportsTransformedUnused.length === 0)
|
|
225
242
|
return;
|
|
226
|
-
const importStatements = unique(
|
|
227
|
-
const importNamesUnused =
|
|
228
|
-
const singular =
|
|
229
|
-
assertWarning(
|
|
230
|
-
`${
|
|
243
|
+
const importStatements = unique(fileImportsTransformedUnused.map((fi) => fi.importStatementCode));
|
|
244
|
+
const importNamesUnused = fileImportsTransformedUnused.map((fi) => pc.cyan(fi.importLocalName)).join(', ');
|
|
245
|
+
const singular = fileImportsTransformedUnused.length === 1;
|
|
246
|
+
assertWarning(fileImportsTransformedUnused.length === 0, [
|
|
247
|
+
`${filePathToShowToUser2} imports the following:`,
|
|
231
248
|
...importStatements.map((s) => pc.cyan(` ${s}`)),
|
|
232
249
|
`But the import${singular ? '' : 's'} ${importNamesUnused} ${singular ? "isn't" : "aren't"} re-exported at ${pc.cyan('export default { ... }')} and therefore ${singular ? 'has' : 'have'} no effect, see explanation at https://vike.dev/header-file`
|
|
233
250
|
].join('\n'), { onlyOnce: true });
|
|
@@ -249,6 +266,7 @@ function getExportedStrings(obj) {
|
|
|
249
266
|
return exportedStrings;
|
|
250
267
|
}
|
|
251
268
|
function isHeaderFile(filePath) {
|
|
269
|
+
assertPosixPath(filePath);
|
|
252
270
|
const basenameParts = path.posix.basename(filePath).split('.');
|
|
253
271
|
return basenameParts.includes('h');
|
|
254
272
|
}
|
|
@@ -269,10 +287,19 @@ function triggerPrepareStackTrace(err) {
|
|
|
269
287
|
}
|
|
270
288
|
}
|
|
271
289
|
function getErrIntroMsg(operation, filePath) {
|
|
290
|
+
const filePathToShowToUser2 = getFilePathToShowToUser2(filePath);
|
|
272
291
|
const msg = [
|
|
292
|
+
// prettier ignore
|
|
273
293
|
pc.red(`Failed to ${operation}`),
|
|
274
|
-
pc.bold(pc.red(
|
|
294
|
+
pc.bold(pc.red(filePathToShowToUser2)),
|
|
275
295
|
pc.red(`because:`)
|
|
276
296
|
].join(' ');
|
|
277
297
|
return msg;
|
|
278
298
|
}
|
|
299
|
+
/** `filePath.filePathToShowToUser` may show the import path of a package, use `filePathToShowToUser2` instead always show a file path instead. */
|
|
300
|
+
function getFilePathToShowToUser2(filePath) {
|
|
301
|
+
const { filePathAbsoluteFilesystem, filePathRelativeToUserRootDir } = filePath;
|
|
302
|
+
const filePathToShowToUser2 = filePathRelativeToUserRootDir || filePathAbsoluteFilesystem;
|
|
303
|
+
assert(filePathToShowToUser2);
|
|
304
|
+
return filePathToShowToUser2;
|
|
305
|
+
}
|
|
@@ -2,9 +2,24 @@ 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';
|
|
8
|
+
import { type LocationId } from './getVikeConfig/filesystemRouting.js';
|
|
7
9
|
import type { ResolvedConfig } from 'vite';
|
|
10
|
+
type InterfaceFileCommons = {
|
|
11
|
+
locationId: LocationId;
|
|
12
|
+
filePath: FilePathResolved;
|
|
13
|
+
fileExportsByConfigName: Record<ConfigName, {
|
|
14
|
+
configValue?: unknown;
|
|
15
|
+
}>;
|
|
16
|
+
};
|
|
17
|
+
type InterfaceValueFile = InterfaceFileCommons & {
|
|
18
|
+
isConfigFile: false;
|
|
19
|
+
isValueFile: true;
|
|
20
|
+
configName: string;
|
|
21
|
+
};
|
|
22
|
+
type ConfigName = string;
|
|
8
23
|
type VikeConfig = {
|
|
9
24
|
pageConfigs: PageConfigBuildTime[];
|
|
10
25
|
pageConfigGlobal: PageConfigGlobalBuildTime;
|