vike 0.4.159-commit-71760c7 → 0.4.159-commit-a6bc208

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.
@@ -9,7 +9,7 @@ const path_1 = __importDefault(require("path"));
9
9
  const configDefinitionsBuiltIn_js_1 = require("./getVikeConfig/configDefinitionsBuiltIn.js");
10
10
  const filesystemRouting_js_1 = require("./getVikeConfig/filesystemRouting.js");
11
11
  const transpileAndExecuteFile_js_1 = require("./transpileAndExecuteFile.js");
12
- const transformImportStatements_js_1 = require("./transformImportStatements.js");
12
+ const transformImports_js_1 = require("./transformImports.js");
13
13
  const isConfigInvalid_js_1 = require("../../../../runtime/renderPage/isConfigInvalid.js");
14
14
  const globalContext_js_1 = require("../../../../runtime/globalContext.js");
15
15
  const loggerNotProd_js_1 = require("../../../shared/loggerNotProd.js");
@@ -90,7 +90,7 @@ async function loadInterfaceFiles(userRootDir, outDirRoot, isDev, extensions) {
90
90
  let interfaceFilesByLocationId = {};
91
91
  // Config files
92
92
  await Promise.all(configFiles.map(async (filePath) => {
93
- const { configFile, extendsConfigs } = await loadConfigFile(filePath, userRootDir, []);
93
+ const { configFile, extendsConfigs } = await loadConfigFile(filePath, userRootDir, [], false);
94
94
  const interfaceFile = getInterfaceFileFromConfigFile(configFile, false);
95
95
  const locationId = (0, filesystemRouting_js_1.getLocationId)(filePath.filePathAbsoluteVite);
96
96
  interfaceFilesByLocationId[locationId] = interfaceFilesByLocationId[locationId] ?? [];
@@ -582,7 +582,7 @@ function isDefiningPageConfig(configName) {
582
582
  function resolveImport(configValue, importerFilePath, userRootDir, configEnv, configName) {
583
583
  if (typeof configValue !== 'string')
584
584
  return null;
585
- const importData = (0, transformImportStatements_js_1.parseImportData)(configValue);
585
+ const importData = (0, transformImports_js_1.parseImportData)(configValue);
586
586
  if (!importData)
587
587
  return null;
588
588
  const { importPath, exportName } = importData;
@@ -845,10 +845,10 @@ function getConfigName(filePath) {
845
845
  return configName;
846
846
  }
847
847
  }
848
- async function loadConfigFile(configFilePath, userRootDir, visited) {
848
+ async function loadConfigFile(configFilePath, userRootDir, visited, isConfigOfExtension) {
849
849
  const { filePathAbsoluteFilesystem } = configFilePath;
850
850
  assertNoInfiniteLoop(visited, filePathAbsoluteFilesystem);
851
- const { fileExports } = await (0, transpileAndExecuteFile_js_1.transpileAndExecuteFile)(configFilePath, false, userRootDir);
851
+ const { fileExports } = await (0, transpileAndExecuteFile_js_1.transpileAndExecuteFile)(configFilePath, false, userRootDir, isConfigOfExtension);
852
852
  const { extendsConfigs, extendsFilePaths } = await loadExtendsConfigs(fileExports, configFilePath, userRootDir, [
853
853
  ...visited,
854
854
  filePathAbsoluteFilesystem
@@ -875,7 +875,7 @@ async function loadExtendsConfigs(configFileExports, configFilePath, userRootDir
875
875
  const { importPath: importPath } = importData;
876
876
  const filePathAbsoluteFilesystem = resolveImportPath(importData, configFilePath);
877
877
  assertImportPath(filePathAbsoluteFilesystem, importData, configFilePath);
878
- assertExtendsImportPath(importPath, filePathAbsoluteFilesystem, configFilePath);
878
+ warnUserLandExtension(importPath, configFilePath);
879
879
  // - filePathRelativeToUserRootDir has no functionality beyond nicer error messages for user
880
880
  // - Using importPath would be visually nicer but it's ambigous => we rather pick filePathAbsoluteFilesystem for added clarity
881
881
  const filePathRelativeToUserRootDir = determineFilePathRelativeToUserDir(filePathAbsoluteFilesystem, userRootDir);
@@ -890,7 +890,7 @@ async function loadExtendsConfigs(configFileExports, configFilePath, userRootDir
890
890
  });
891
891
  const extendsConfigs = [];
892
892
  await Promise.all(extendsConfigFiles.map(async (configFilePath) => {
893
- const result = await loadConfigFile(configFilePath, userRootDir, visited);
893
+ const result = await loadConfigFile(configFilePath, userRootDir, visited, true);
894
894
  extendsConfigs.push(result.configFile);
895
895
  extendsConfigs.push(...result.extendsConfigs);
896
896
  }));
@@ -908,20 +908,8 @@ function determineFilePathRelativeToUserDir(filePathAbsoluteFilesystem, userRoot
908
908
  filePathRelativeToUserRootDir = '/' + filePathRelativeToUserRootDir;
909
909
  return filePathRelativeToUserRootDir;
910
910
  }
911
- function assertExtendsImportPath(importPath, filePath, configFilePath) {
912
- if ((0, utils_js_1.isNpmPackageImport)(importPath)) {
913
- const fileDir = path_1.default.posix.dirname(filePath) + '/';
914
- const fileName = path_1.default.posix.basename(filePath);
915
- const fileNameBaseCorrect = '+config';
916
- const [fileNameBase, ...fileNameRest] = fileName.split('.');
917
- const fileNameCorrect = [fileNameBaseCorrect, ...fileNameRest].join('.');
918
- (0, utils_js_1.assertWarning)(fileNameBase === fileNameBaseCorrect, `Rename ${fileName} to ${fileNameCorrect} in ${fileDir}`, {
919
- onlyOnce: true
920
- });
921
- }
922
- else {
923
- (0, utils_js_1.assertWarning)(false, `${configFilePath.filePathToShowToUser} uses ${picocolors_1.default.cyan('extends')} to inherit from ${picocolors_1.default.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 feature.`, { onlyOnce: true });
924
- }
911
+ function warnUserLandExtension(importPath, configFilePath) {
912
+ (0, utils_js_1.assertWarning)((0, utils_js_1.isNpmPackageImport)(importPath), `${configFilePath.filePathToShowToUser} uses ${picocolors_1.default.cyan('extends')} to inherit from ${picocolors_1.default.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 });
925
913
  }
926
914
  function getExtendsImportData(configFileExports, configFilePath) {
927
915
  const { filePathToShowToUser } = configFilePath;
@@ -941,7 +929,7 @@ function getExtendsImportData(configFileExports, configFilePath) {
941
929
  (0, utils_js_1.assertUsage)(false, wrongUsage);
942
930
  }
943
931
  const extendsImportData = extendList.map((importDataSerialized) => {
944
- const importData = (0, transformImportStatements_js_1.parseImportData)(importDataSerialized);
932
+ const importData = (0, transformImports_js_1.parseImportData)(importDataSerialized);
945
933
  (0, utils_js_1.assertUsage)(importData, wrongUsage);
946
934
  return importData;
947
935
  });
@@ -3,14 +3,16 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.isVikeRealImport = exports.isImportData = exports.parseImportData = exports.transformImportStatements = void 0;
6
+ exports.isImportData = exports.parseImportData = exports.transformImports = void 0;
7
7
  // Playground: https://github.com/brillout/acorn-playground
8
8
  // Import attributes support: https://github.com/acornjs/acorn/issues/983
9
9
  // - Isn't stage 4 yet: https://github.com/tc39/proposal-import-attributes
10
10
  const acorn_1 = require("acorn");
11
11
  const utils_js_1 = require("../../../utils.js");
12
12
  const picocolors_1 = __importDefault(require("@brillout/picocolors"));
13
- function transformImportStatements(code, filePathToShowToUser2) {
13
+ function transformImports(code, filePathToShowToUser2,
14
+ // For ./transformImports.spec.ts
15
+ skipWarnings) {
14
16
  const spliceOperations = [];
15
17
  const fileImportsTransformed = [];
16
18
  // Performance trick
@@ -24,9 +26,29 @@ function transformImportStatements(code, filePathToShowToUser2) {
24
26
  return;
25
27
  const importPath = node.source.value;
26
28
  (0, utils_js_1.assert)(typeof importPath === 'string');
27
- const { start, end } = node;
28
- if (isVikeRealImport(code, end))
29
+ // - This doesn't work. To make it work we would need to run esbuild twice: esbuild for TypeScript to JavaScript => transformImports() => esbuild for bundling.
30
+ // - Or we use an esbuild plugin to apply transformImports(). Maybe we can completely skip the need for acorn?
31
+ // - ?real breaks TypeScript, and TypeScript isn't working on supporting query params: https://github.com/microsoft/TypeScript/issues/10988#issuecomment-867135453
32
+ // - Import attributes would be the best.
33
+ // - But it only works with Node.js >=21: https://nodejs.org/api/esm.html#import-attributes
34
+ // - But it's probably ok to tell users "to use real imports you need Node.js 21 or above".
35
+ // - 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
36
+ // - Esbuid seems to support it: https://esbuild.github.io/plugins/#on-load-arguments:~:text=This%20contains%20a%20map%20of%20the%20import%20attributes%20that
37
+ // - acorn supports it over an acorn plugin: https://github.com/acornjs/acorn/issues/983
38
+ // - Maybe we can use an esbuild plugin instead of acorn to apply transformImports()?
39
+ // - Using a magic comment `// @vike-real-import` is tricky:
40
+ // - Esbuild removes comments: https://github.com/evanw/esbuild/issues/1439#issuecomment-877656182
41
+ // - Using source maps to track these magic comments is brittle (source maps can easily break)
42
+ if (importPath.endsWith('?real')) {
43
+ const { start, end } = node.source;
44
+ spliceOperations.push({
45
+ start,
46
+ end,
47
+ replacement: importPath.slice(0, -1 * '?real'.length)
48
+ });
29
49
  return;
50
+ }
51
+ const { start, end } = node;
30
52
  const importStatementCode = code.slice(start, end);
31
53
  // No variable imported
32
54
  if (node.specifiers.length === 0) {
@@ -42,10 +64,12 @@ function transformImportStatements(code, filePathToShowToUser2) {
42
64
  `As explained in https://vike.dev/header-file the following import in ${filePathToShowToUser2} has no effect:`,
43
65
  quote
44
66
  ].join('\n');
45
- if (!isWarning) {
46
- (0, utils_js_1.assertUsage)(false, errMsg);
67
+ if (!skipWarnings) {
68
+ if (!isWarning) {
69
+ (0, utils_js_1.assertUsage)(false, errMsg);
70
+ }
71
+ (0, utils_js_1.assertWarning)(false, errMsg, { onlyOnce: true });
47
72
  }
48
- (0, utils_js_1.assertWarning)(false, errMsg, { onlyOnce: true });
49
73
  }
50
74
  let replacement = '';
51
75
  node.specifiers.forEach((specifier) => {
@@ -82,7 +106,7 @@ function transformImportStatements(code, filePathToShowToUser2) {
82
106
  const codeMod = spliceMany(code, spliceOperations);
83
107
  return { code: codeMod, fileImportsTransformed, noTransformation: false };
84
108
  }
85
- exports.transformImportStatements = transformImportStatements;
109
+ exports.transformImports = transformImports;
86
110
  function getImports(code) {
87
111
  const { body } = (0, acorn_1.parse)(code, {
88
112
  ecmaVersion: 'latest',
@@ -150,7 +174,7 @@ function spliceMany(str, operations) {
150
174
  .join('');
151
175
  endPrev = end;
152
176
  });
153
- strMod += str.slice(endPrev, str.length - 1);
177
+ strMod += str.slice(endPrev, str.length);
154
178
  return strMod;
155
179
  }
156
180
  function indent(str) {
@@ -159,11 +183,3 @@ function indent(str) {
159
183
  .map((s) => ` ${s}`)
160
184
  .join('\n');
161
185
  }
162
- function isVikeRealImport(code, posStart) {
163
- let posEnd = code.indexOf('\n', posStart);
164
- if (posEnd === -1)
165
- posEnd = code.length;
166
- const lineEnd = code.slice(posStart, posEnd);
167
- return lineEnd.includes('@vike-real-import');
168
- }
169
- exports.isVikeRealImport = isVikeRealImport;
@@ -10,50 +10,64 @@ const path_1 = __importDefault(require("path"));
10
10
  const picocolors_1 = __importDefault(require("@brillout/picocolors"));
11
11
  const import_1 = require("@brillout/import");
12
12
  const utils_js_1 = require("../../../utils.js");
13
- const transformImportStatements_js_1 = require("./transformImportStatements.js");
13
+ const transformImports_js_1 = require("./transformImports.js");
14
14
  const getVikeConfig_js_1 = require("./getVikeConfig.js");
15
15
  require("source-map-support/register.js");
16
16
  const getConfigFileExport_js_1 = require("./getConfigFileExport.js");
17
17
  (0, utils_js_1.assertIsNotProductionRuntime)();
18
- async function transpileAndExecuteFile(filePath, isValueFile, userRootDir) {
19
- const { code, fileImportsTransformed } = await transpileFile(filePath, isValueFile, userRootDir);
20
- const { fileExports } = await executeFile(filePath, code, fileImportsTransformed, isValueFile);
21
- return { fileExports };
18
+ async function transpileAndExecuteFile(filePath, isValueFile, userRootDir, isConfigOfExtension = false) {
19
+ if (isConfigOfExtension) {
20
+ const fileExports = await executeFile(filePath.filePathAbsoluteFilesystem, filePath);
21
+ if (isHeaderFile(filePath.filePathAbsoluteFilesystem)) {
22
+ const filePathToShowToUser2 = getFilePathToShowToUser2(filePath);
23
+ (0, utils_js_1.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 });
24
+ }
25
+ return { fileExports };
26
+ }
27
+ else {
28
+ const { code, fileImportsTransformed } = await transpileFile(filePath, isValueFile, userRootDir);
29
+ const fileExports = await executeTranspiledFile(filePath, code, fileImportsTransformed, isValueFile);
30
+ return { fileExports };
31
+ }
22
32
  }
23
33
  exports.transpileAndExecuteFile = transpileAndExecuteFile;
24
34
  async function transpileFile(filePath, isValueFile, userRootDir) {
25
35
  const { filePathAbsoluteFilesystem } = filePath;
36
+ const filePathToShowToUser2 = getFilePathToShowToUser2(filePath);
26
37
  (0, utils_js_1.assertPosixPath)(filePathAbsoluteFilesystem);
27
38
  getVikeConfig_js_1.vikeConfigDependencies.add(filePathAbsoluteFilesystem);
28
- let code = await transpileWithEsbuild(filePath, isValueFile, userRootDir);
39
+ const importsAreTransformed = !isValueFile;
40
+ let code = await transpileWithEsbuild(filePath, userRootDir, importsAreTransformed, isValueFile);
29
41
  let fileImportsTransformed = null;
30
- {
31
- const res = transformImports(code, filePath, isValueFile);
42
+ if (importsAreTransformed) {
43
+ const res = transformImports_(code, filePath);
32
44
  if (res) {
33
45
  code = res.code;
34
46
  fileImportsTransformed = res.fileImportsTransformed;
35
47
  }
36
48
  }
49
+ else {
50
+ if (isHeaderFile(filePathAbsoluteFilesystem)) {
51
+ if (isValueFile) {
52
+ (0, utils_js_1.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 });
53
+ }
54
+ else {
55
+ (0, utils_js_1.assert)(false);
56
+ }
57
+ }
58
+ }
37
59
  return { code, fileImportsTransformed };
38
60
  }
39
- function transformImports(codeOriginal, filePath, isValueFile) {
40
- // Do we need to remove the imports?
61
+ function transformImports_(codeOriginal, filePath) {
41
62
  const { filePathAbsoluteFilesystem } = filePath;
42
63
  const filePathToShowToUser2 = getFilePathToShowToUser2(filePath);
43
- (0, utils_js_1.assertPosixPath)(filePathAbsoluteFilesystem);
44
- const isHeader = isHeaderFile(filePathAbsoluteFilesystem);
45
- const isPageConfigFile = !isValueFile;
46
- if (!isHeader && !isPageConfigFile) {
47
- return null;
48
- }
49
- (0, utils_js_1.assertWarning)(isPageConfigFile, `${filePathToShowToUser2} is a JavaScript header file (.h.js), but JavaScript header files should only be used for +config.h.js, see https://vike.dev/header-file`, { onlyOnce: true });
50
- // Remove the imports
51
- const res = (0, transformImportStatements_js_1.transformImportStatements)(codeOriginal, filePathToShowToUser2);
64
+ // Replace import statements with import strings
65
+ const res = (0, transformImports_js_1.transformImports)(codeOriginal, filePathToShowToUser2);
52
66
  if (res.noTransformation) {
53
67
  return null;
54
68
  }
55
69
  const { code, fileImportsTransformed } = res;
56
- if (!isHeader) {
70
+ if (!isHeaderFile(filePathAbsoluteFilesystem)) {
57
71
  const filePathCorrect = appendHeaderFileExtension(filePathToShowToUser2);
58
72
  (0, utils_js_1.assertWarning)(false, `Rename ${filePathToShowToUser2} to ${filePathCorrect}, see https://vike.dev/header-file`, {
59
73
  onlyOnce: true
@@ -61,7 +75,8 @@ function transformImports(codeOriginal, filePath, isValueFile) {
61
75
  }
62
76
  return { code, fileImportsTransformed };
63
77
  }
64
- async function transpileWithEsbuild(filePath, bundle, userRootDir) {
78
+ async function transpileWithEsbuild(filePath, userRootDir, importsAreTransformed, isValueFile) {
79
+ const isConfigFile = !isValueFile;
65
80
  const entryFilePath = filePath.filePathAbsoluteFilesystem;
66
81
  const entryFileDir = path_1.default.posix.dirname(entryFilePath);
67
82
  const options = {
@@ -77,22 +92,26 @@ async function transpileWithEsbuild(filePath, bundle, userRootDir) {
77
92
  'NEVER_EMITTED.js'),
78
93
  logLevel: 'silent',
79
94
  format: 'esm',
80
- bundle,
95
+ absWorkingDir: userRootDir,
96
+ // Disable tree-shaking to avoid dead-code elimination, so that unused imports aren't removed.
97
+ // Esbuild still sometimes removes unused imports because of TypeScript: https://github.com/evanw/esbuild/issues/3034
98
+ treeShaking: false,
81
99
  minify: false,
82
- metafile: bundle,
83
- absWorkingDir: userRootDir
100
+ metafile: isConfigFile,
101
+ // We cannot bundle imports that are meant to be transformed
102
+ bundle: !importsAreTransformed
84
103
  };
85
- if (bundle) {
86
- options.bundle = true;
104
+ // Track dependencies
105
+ if (isConfigFile) {
87
106
  options.packages = 'external';
88
107
  options.plugins = [
89
108
  {
90
- name: 'vike:import-hook',
109
+ name: 'vike:dependency-tracker',
91
110
  setup(b) {
92
111
  b.onLoad({ filter: /./ }, (args) => {
112
+ // We collect the dependency `args.path` in case the bulid fails (upon build error => error is thrown => no metafile)
93
113
  let { path } = args;
94
114
  path = (0, utils_js_1.toPosixPath)(path);
95
- // We collect the dependency args.path in case it fails to build (upon build error => error is thrown => no metafile)
96
115
  getVikeConfig_js_1.vikeConfigDependencies.add(path);
97
116
  return undefined;
98
117
  });
@@ -109,11 +128,6 @@ async function transpileWithEsbuild(filePath, bundle, userRootDir) {
109
128
  }
110
129
  ];
111
130
  }
112
- else {
113
- // Avoid dead-code elimination to ensure unused imports aren't removed.
114
- // Esbuild still sometimes removes unused imports because of TypeScript: https://github.com/evanw/esbuild/issues/3034
115
- options.treeShaking = false;
116
- }
117
131
  let result;
118
132
  try {
119
133
  result = await (0, esbuild_1.build)(options);
@@ -122,7 +136,8 @@ async function transpileWithEsbuild(filePath, bundle, userRootDir) {
122
136
  await formatBuildErr(err, filePath);
123
137
  throw err;
124
138
  }
125
- if (bundle) {
139
+ // Track dependencies
140
+ if (isConfigFile) {
126
141
  (0, utils_js_1.assert)(result.metafile);
127
142
  Object.keys(result.metafile.inputs).forEach((filePathRelative) => {
128
143
  filePathRelative = (0, utils_js_1.toPosixPath)(filePathRelative);
@@ -135,7 +150,7 @@ async function transpileWithEsbuild(filePath, bundle, userRootDir) {
135
150
  (0, utils_js_1.assert)(typeof code === 'string');
136
151
  return code;
137
152
  }
138
- async function executeFile(filePath, code, fileImportsTransformed, isValueFile) {
153
+ async function executeTranspiledFile(filePath, code, fileImportsTransformed, isValueFile) {
139
154
  const { filePathAbsoluteFilesystem, filePathRelativeToUserRootDir } = filePath;
140
155
  // Alternative to using a temporary file: https://github.com/vitejs/vite/pull/13269
141
156
  // - But seems to break source maps, so I don't think it's worth it
@@ -144,28 +159,35 @@ async function executeFile(filePath, code, fileImportsTransformed, isValueFile)
144
159
  const clean = () => fs_1.default.unlinkSync(filePathTmp);
145
160
  let fileExports = {};
146
161
  try {
147
- fileExports = await (0, import_1.import_)(filePathTmp);
148
- }
149
- catch (err) {
150
- triggerPrepareStackTrace(err);
151
- const errIntroMsg = getErrIntroMsg('execute', filePath);
152
- (0, utils_js_1.assert)((0, utils_js_1.isObject)(err));
153
- execErrIntroMsg.set(err, errIntroMsg);
154
- throw err;
162
+ fileExports = await executeFile(filePathTmp, filePath);
155
163
  }
156
164
  finally {
157
165
  clean();
158
166
  }
159
- // Return a plain JavaScript object
160
- // - import() returns `[Module: null prototype] { default: { onRenderClient: '...' }}`
161
- // - We don't need this special object
162
- fileExports = { ...fileExports };
163
167
  if (fileImportsTransformed && !isValueFile) {
164
168
  (0, utils_js_1.assert)(filePathRelativeToUserRootDir !== undefined);
165
169
  const filePathToShowToUser2 = getFilePathToShowToUser2(filePath);
166
170
  assertImportsAreReExported(fileImportsTransformed, fileExports, filePathToShowToUser2);
167
171
  }
168
- return { fileExports };
172
+ return fileExports;
173
+ }
174
+ async function executeFile(filePathToExecuteAbsoluteFilesystem, filePathSourceFile) {
175
+ let fileExports = {};
176
+ try {
177
+ fileExports = await (0, import_1.import_)(filePathToExecuteAbsoluteFilesystem);
178
+ }
179
+ catch (err) {
180
+ triggerPrepareStackTrace(err);
181
+ const errIntroMsg = getErrIntroMsg('execute', filePathSourceFile);
182
+ (0, utils_js_1.assert)((0, utils_js_1.isObject)(err));
183
+ execErrIntroMsg.set(err, errIntroMsg);
184
+ throw err;
185
+ }
186
+ // Return a plain JavaScript object:
187
+ // - import() returns `[Module: null prototype] { default: { onRenderClient: '...' }}`
188
+ // - We don't need this special object.
189
+ fileExports = { ...fileExports };
190
+ return fileExports;
169
191
  }
170
192
  const formatted = '_formatted';
171
193
  function getConfigBuildErrorFormatted(err) {
@@ -197,10 +219,10 @@ function getConfigExecutionErrorIntroMsg(err) {
197
219
  }
198
220
  exports.getConfigExecutionErrorIntroMsg = getConfigExecutionErrorIntroMsg;
199
221
  const tmpPrefix = `[build-`;
200
- function getFilePathTmp(filePath) {
201
- (0, utils_js_1.assertPosixPath)(filePath);
202
- const dirname = path_1.default.posix.dirname(filePath);
203
- const filename = path_1.default.posix.basename(filePath);
222
+ function getFilePathTmp(filePathAbsoluteFilesystem) {
223
+ (0, utils_js_1.assertPosixPath)(filePathAbsoluteFilesystem);
224
+ const dirname = path_1.default.posix.dirname(filePathAbsoluteFilesystem);
225
+ const filename = path_1.default.posix.basename(filePathAbsoluteFilesystem);
204
226
  // Syntax with semicolon `[build:${/*...*/}]` doesn't work on Windows: https://github.com/vikejs/vike/issues/800#issuecomment-1517329455
205
227
  const tag = `${tmpPrefix}${(0, utils_js_1.getRandomId)(12)}]`;
206
228
  const filePathTmp = path_1.default.posix.join(dirname, `${tag}${filename}.mjs`);
@@ -218,7 +240,7 @@ function assertImportsAreReExported(fileImportsTransformed, fileExports, filePat
218
240
  Object.values(exportedStrings).forEach((exportVal) => {
219
241
  if (typeof exportVal !== 'string')
220
242
  return;
221
- if (!(0, transformImportStatements_js_1.isImportData)(exportVal))
243
+ if (!(0, transformImports_js_1.isImportData)(exportVal))
222
244
  return;
223
245
  const importString = exportVal;
224
246
  fileImportsTransformed.forEach((fileImport) => {
@@ -256,6 +278,7 @@ function getExportedStrings(obj) {
256
278
  return exportedStrings;
257
279
  }
258
280
  function isHeaderFile(filePath) {
281
+ (0, utils_js_1.assertPosixPath)(filePath);
259
282
  const basenameParts = path_1.default.posix.basename(filePath).split('.');
260
283
  return basenameParts.includes('h');
261
284
  }
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.PROJECT_VERSION = exports.projectInfo = void 0;
4
4
  const assertSingleInstance_js_1 = require("./assertSingleInstance.js");
5
- const PROJECT_VERSION = '0.4.159-commit-71760c7';
5
+ const PROJECT_VERSION = '0.4.159-commit-a6bc208';
6
6
  exports.PROJECT_VERSION = PROJECT_VERSION;
7
7
  const projectInfo = {
8
8
  projectName: 'Vike',
@@ -7,7 +7,7 @@ import path from 'path';
7
7
  import { configDefinitionsBuiltIn, configDefinitionsBuiltInGlobal } from './getVikeConfig/configDefinitionsBuiltIn.js';
8
8
  import { getLocationId, getFilesystemRouteString, getFilesystemRouteDefinedBy, isInherited, sortAfterInheritanceOrder, isGlobalLocation, applyFilesystemRoutingRootEffect } from './getVikeConfig/filesystemRouting.js';
9
9
  import { isTmpFile, transpileAndExecuteFile } from './transpileAndExecuteFile.js';
10
- import { parseImportData } from './transformImportStatements.js';
10
+ import { parseImportData } from './transformImports.js';
11
11
  import { isConfigInvalid, isConfigInvalid_set } from '../../../../runtime/renderPage/isConfigInvalid.js';
12
12
  import { getViteDevServer } from '../../../../runtime/globalContext.js';
13
13
  import { logConfigError, logConfigErrorRecover } from '../../../shared/loggerNotProd.js';
@@ -85,7 +85,7 @@ async function loadInterfaceFiles(userRootDir, outDirRoot, isDev, extensions) {
85
85
  let interfaceFilesByLocationId = {};
86
86
  // Config files
87
87
  await Promise.all(configFiles.map(async (filePath) => {
88
- const { configFile, extendsConfigs } = await loadConfigFile(filePath, userRootDir, []);
88
+ const { configFile, extendsConfigs } = await loadConfigFile(filePath, userRootDir, [], false);
89
89
  const interfaceFile = getInterfaceFileFromConfigFile(configFile, false);
90
90
  const locationId = getLocationId(filePath.filePathAbsoluteVite);
91
91
  interfaceFilesByLocationId[locationId] = interfaceFilesByLocationId[locationId] ?? [];
@@ -840,10 +840,10 @@ function getConfigName(filePath) {
840
840
  return configName;
841
841
  }
842
842
  }
843
- async function loadConfigFile(configFilePath, userRootDir, visited) {
843
+ async function loadConfigFile(configFilePath, userRootDir, visited, isConfigOfExtension) {
844
844
  const { filePathAbsoluteFilesystem } = configFilePath;
845
845
  assertNoInfiniteLoop(visited, filePathAbsoluteFilesystem);
846
- const { fileExports } = await transpileAndExecuteFile(configFilePath, false, userRootDir);
846
+ const { fileExports } = await transpileAndExecuteFile(configFilePath, false, userRootDir, isConfigOfExtension);
847
847
  const { extendsConfigs, extendsFilePaths } = await loadExtendsConfigs(fileExports, configFilePath, userRootDir, [
848
848
  ...visited,
849
849
  filePathAbsoluteFilesystem
@@ -870,7 +870,7 @@ async function loadExtendsConfigs(configFileExports, configFilePath, userRootDir
870
870
  const { importPath: importPath } = importData;
871
871
  const filePathAbsoluteFilesystem = resolveImportPath(importData, configFilePath);
872
872
  assertImportPath(filePathAbsoluteFilesystem, importData, configFilePath);
873
- assertExtendsImportPath(importPath, filePathAbsoluteFilesystem, configFilePath);
873
+ warnUserLandExtension(importPath, configFilePath);
874
874
  // - filePathRelativeToUserRootDir has no functionality beyond nicer error messages for user
875
875
  // - Using importPath would be visually nicer but it's ambigous => we rather pick filePathAbsoluteFilesystem for added clarity
876
876
  const filePathRelativeToUserRootDir = determineFilePathRelativeToUserDir(filePathAbsoluteFilesystem, userRootDir);
@@ -885,7 +885,7 @@ async function loadExtendsConfigs(configFileExports, configFilePath, userRootDir
885
885
  });
886
886
  const extendsConfigs = [];
887
887
  await Promise.all(extendsConfigFiles.map(async (configFilePath) => {
888
- const result = await loadConfigFile(configFilePath, userRootDir, visited);
888
+ const result = await loadConfigFile(configFilePath, userRootDir, visited, true);
889
889
  extendsConfigs.push(result.configFile);
890
890
  extendsConfigs.push(...result.extendsConfigs);
891
891
  }));
@@ -903,20 +903,8 @@ function determineFilePathRelativeToUserDir(filePathAbsoluteFilesystem, userRoot
903
903
  filePathRelativeToUserRootDir = '/' + filePathRelativeToUserRootDir;
904
904
  return filePathRelativeToUserRootDir;
905
905
  }
906
- function assertExtendsImportPath(importPath, filePath, configFilePath) {
907
- if (isNpmPackageImport(importPath)) {
908
- const fileDir = path.posix.dirname(filePath) + '/';
909
- const fileName = path.posix.basename(filePath);
910
- const fileNameBaseCorrect = '+config';
911
- const [fileNameBase, ...fileNameRest] = fileName.split('.');
912
- const fileNameCorrect = [fileNameBaseCorrect, ...fileNameRest].join('.');
913
- assertWarning(fileNameBase === fileNameBaseCorrect, `Rename ${fileName} to ${fileNameCorrect} in ${fileDir}`, {
914
- onlyOnce: true
915
- });
916
- }
917
- else {
918
- assertWarning(false, `${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 feature.`, { onlyOnce: true });
919
- }
906
+ function warnUserLandExtension(importPath, configFilePath) {
907
+ 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 });
920
908
  }
921
909
  function getExtendsImportData(configFileExports, configFilePath) {
922
910
  const { filePathToShowToUser } = configFilePath;
@@ -1,15 +1,14 @@
1
- export { transformImportStatements };
1
+ export { transformImports };
2
2
  export { parseImportData };
3
3
  export { isImportData };
4
4
  export type { FileImport };
5
5
  export type { ImportData };
6
- export { isVikeRealImport };
7
6
  type FileImport = {
8
7
  importStatementCode: string;
9
8
  importString: string;
10
9
  importLocalName: string;
11
10
  };
12
- declare function transformImportStatements(code: string, filePathToShowToUser2: string): {
11
+ declare function transformImports(code: string, filePathToShowToUser2: string, skipWarnings?: true): {
13
12
  noTransformation: true;
14
13
  } | {
15
14
  noTransformation: false;
@@ -42,4 +41,3 @@ declare module 'estree' {
42
41
  end: number;
43
42
  }
44
43
  }
45
- declare function isVikeRealImport(code: string, posStart: number): boolean;
@@ -1,15 +1,15 @@
1
- export { transformImportStatements };
1
+ export { transformImports };
2
2
  export { parseImportData };
3
3
  export { isImportData };
4
- // For ./transformImportStatements.spec.ts
5
- export { isVikeRealImport };
6
4
  // Playground: https://github.com/brillout/acorn-playground
7
5
  // Import attributes support: https://github.com/acornjs/acorn/issues/983
8
6
  // - Isn't stage 4 yet: https://github.com/tc39/proposal-import-attributes
9
7
  import { parse } from 'acorn';
10
8
  import { assert, assertUsage, assertWarning, styleFileRE } from '../../../utils.js';
11
9
  import pc from '@brillout/picocolors';
12
- function transformImportStatements(code, filePathToShowToUser2) {
10
+ function transformImports(code, filePathToShowToUser2,
11
+ // For ./transformImports.spec.ts
12
+ skipWarnings) {
13
13
  const spliceOperations = [];
14
14
  const fileImportsTransformed = [];
15
15
  // Performance trick
@@ -23,9 +23,29 @@ function transformImportStatements(code, filePathToShowToUser2) {
23
23
  return;
24
24
  const importPath = node.source.value;
25
25
  assert(typeof importPath === 'string');
26
- const { start, end } = node;
27
- if (isVikeRealImport(code, end))
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
+ // - Or we use an esbuild plugin to apply transformImports(). 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 transformImports()?
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
+ });
28
46
  return;
47
+ }
48
+ const { start, end } = node;
29
49
  const importStatementCode = code.slice(start, end);
30
50
  // No variable imported
31
51
  if (node.specifiers.length === 0) {
@@ -41,10 +61,12 @@ function transformImportStatements(code, filePathToShowToUser2) {
41
61
  `As explained in https://vike.dev/header-file the following import in ${filePathToShowToUser2} has no effect:`,
42
62
  quote
43
63
  ].join('\n');
44
- if (!isWarning) {
45
- assertUsage(false, errMsg);
64
+ if (!skipWarnings) {
65
+ if (!isWarning) {
66
+ assertUsage(false, errMsg);
67
+ }
68
+ assertWarning(false, errMsg, { onlyOnce: true });
46
69
  }
47
- assertWarning(false, errMsg, { onlyOnce: true });
48
70
  }
49
71
  let replacement = '';
50
72
  node.specifiers.forEach((specifier) => {
@@ -146,7 +168,7 @@ function spliceMany(str, operations) {
146
168
  .join('');
147
169
  endPrev = end;
148
170
  });
149
- strMod += str.slice(endPrev, str.length - 1);
171
+ strMod += str.slice(endPrev, str.length);
150
172
  return strMod;
151
173
  }
152
174
  function indent(str) {
@@ -155,10 +177,3 @@ function indent(str) {
155
177
  .map((s) => ` ${s}`)
156
178
  .join('\n');
157
179
  }
158
- function isVikeRealImport(code, posStart) {
159
- let posEnd = code.indexOf('\n', posStart);
160
- if (posEnd === -1)
161
- posEnd = code.length;
162
- const lineEnd = code.slice(posStart, posEnd);
163
- return lineEnd.includes('@vike-real-import');
164
- }
@@ -4,7 +4,7 @@ export { getConfigExecutionErrorIntroMsg as getConfigExecutionErrorIntroMsg };
4
4
  export { isTmpFile };
5
5
  import 'source-map-support/register.js';
6
6
  import type { FilePathResolved } from '../../../../../shared/page-configs/PageConfig.js';
7
- declare function transpileAndExecuteFile(filePath: FilePathResolved, isValueFile: boolean, userRootDir: string): Promise<{
7
+ declare function transpileAndExecuteFile(filePath: FilePathResolved, isValueFile: boolean, userRootDir: string, isConfigOfExtension?: boolean): Promise<{
8
8
  fileExports: Record<string, unknown>;
9
9
  }>;
10
10
  declare function getConfigBuildErrorFormatted(err: unknown): null | string;
@@ -8,49 +8,63 @@ import path from 'path';
8
8
  import pc from '@brillout/picocolors';
9
9
  import { import_ } from '@brillout/import';
10
10
  import { assertPosixPath, getRandomId, assertIsNotProductionRuntime, assert, unique, assertWarning, isObject, toPosixPath } from '../../../utils.js';
11
- import { isImportData, transformImportStatements } from './transformImportStatements.js';
11
+ import { isImportData, transformImports } from './transformImports.js';
12
12
  import { vikeConfigDependencies } from './getVikeConfig.js';
13
13
  import 'source-map-support/register.js';
14
14
  import { getConfigFileExport } from './getConfigFileExport.js';
15
15
  assertIsNotProductionRuntime();
16
- async function transpileAndExecuteFile(filePath, isValueFile, userRootDir) {
17
- const { code, fileImportsTransformed } = await transpileFile(filePath, isValueFile, userRootDir);
18
- const { fileExports } = await executeFile(filePath, code, fileImportsTransformed, isValueFile);
19
- return { fileExports };
16
+ async function transpileAndExecuteFile(filePath, isValueFile, userRootDir, isConfigOfExtension = false) {
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
31
  async function transpileFile(filePath, isValueFile, userRootDir) {
22
32
  const { filePathAbsoluteFilesystem } = filePath;
33
+ const filePathToShowToUser2 = getFilePathToShowToUser2(filePath);
23
34
  assertPosixPath(filePathAbsoluteFilesystem);
24
35
  vikeConfigDependencies.add(filePathAbsoluteFilesystem);
25
- let code = await transpileWithEsbuild(filePath, isValueFile, userRootDir);
36
+ const importsAreTransformed = !isValueFile;
37
+ let code = await transpileWithEsbuild(filePath, userRootDir, importsAreTransformed, isValueFile);
26
38
  let fileImportsTransformed = null;
27
- {
28
- const res = transformImports(code, filePath, isValueFile);
39
+ if (importsAreTransformed) {
40
+ const res = transformImports_(code, filePath);
29
41
  if (res) {
30
42
  code = res.code;
31
43
  fileImportsTransformed = res.fileImportsTransformed;
32
44
  }
33
45
  }
46
+ else {
47
+ if (isHeaderFile(filePathAbsoluteFilesystem)) {
48
+ if (isValueFile) {
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 });
50
+ }
51
+ else {
52
+ assert(false);
53
+ }
54
+ }
55
+ }
34
56
  return { code, fileImportsTransformed };
35
57
  }
36
- function transformImports(codeOriginal, filePath, isValueFile) {
37
- // Do we need to remove the imports?
58
+ function transformImports_(codeOriginal, filePath) {
38
59
  const { filePathAbsoluteFilesystem } = filePath;
39
60
  const filePathToShowToUser2 = getFilePathToShowToUser2(filePath);
40
- assertPosixPath(filePathAbsoluteFilesystem);
41
- const isHeader = isHeaderFile(filePathAbsoluteFilesystem);
42
- const isPageConfigFile = !isValueFile;
43
- if (!isHeader && !isPageConfigFile) {
44
- return null;
45
- }
46
- assertWarning(isPageConfigFile, `${filePathToShowToUser2} is a JavaScript header file (.h.js), but JavaScript header files should only be used for +config.h.js, see https://vike.dev/header-file`, { onlyOnce: true });
47
- // Remove the imports
48
- const res = transformImportStatements(codeOriginal, filePathToShowToUser2);
61
+ // Replace import statements with import strings
62
+ const res = transformImports(codeOriginal, filePathToShowToUser2);
49
63
  if (res.noTransformation) {
50
64
  return null;
51
65
  }
52
66
  const { code, fileImportsTransformed } = res;
53
- if (!isHeader) {
67
+ if (!isHeaderFile(filePathAbsoluteFilesystem)) {
54
68
  const filePathCorrect = appendHeaderFileExtension(filePathToShowToUser2);
55
69
  assertWarning(false, `Rename ${filePathToShowToUser2} to ${filePathCorrect}, see https://vike.dev/header-file`, {
56
70
  onlyOnce: true
@@ -58,7 +72,8 @@ function transformImports(codeOriginal, filePath, isValueFile) {
58
72
  }
59
73
  return { code, fileImportsTransformed };
60
74
  }
61
- async function transpileWithEsbuild(filePath, bundle, userRootDir) {
75
+ async function transpileWithEsbuild(filePath, userRootDir, importsAreTransformed, isValueFile) {
76
+ const isConfigFile = !isValueFile;
62
77
  const entryFilePath = filePath.filePathAbsoluteFilesystem;
63
78
  const entryFileDir = path.posix.dirname(entryFilePath);
64
79
  const options = {
@@ -74,22 +89,26 @@ async function transpileWithEsbuild(filePath, bundle, userRootDir) {
74
89
  'NEVER_EMITTED.js'),
75
90
  logLevel: 'silent',
76
91
  format: 'esm',
77
- bundle,
92
+ absWorkingDir: userRootDir,
93
+ // Disable tree-shaking to avoid dead-code elimination, so that unused imports aren't removed.
94
+ // Esbuild still sometimes removes unused imports because of TypeScript: https://github.com/evanw/esbuild/issues/3034
95
+ treeShaking: false,
78
96
  minify: false,
79
- metafile: bundle,
80
- absWorkingDir: userRootDir
97
+ metafile: isConfigFile,
98
+ // We cannot bundle imports that are meant to be transformed
99
+ bundle: !importsAreTransformed
81
100
  };
82
- if (bundle) {
83
- options.bundle = true;
101
+ // Track dependencies
102
+ if (isConfigFile) {
84
103
  options.packages = 'external';
85
104
  options.plugins = [
86
105
  {
87
- name: 'vike:import-hook',
106
+ name: 'vike:dependency-tracker',
88
107
  setup(b) {
89
108
  b.onLoad({ filter: /./ }, (args) => {
109
+ // We collect the dependency `args.path` in case the bulid fails (upon build error => error is thrown => no metafile)
90
110
  let { path } = args;
91
111
  path = toPosixPath(path);
92
- // We collect the dependency args.path in case it fails to build (upon build error => error is thrown => no metafile)
93
112
  vikeConfigDependencies.add(path);
94
113
  return undefined;
95
114
  });
@@ -106,11 +125,6 @@ async function transpileWithEsbuild(filePath, bundle, userRootDir) {
106
125
  }
107
126
  ];
108
127
  }
109
- else {
110
- // Avoid dead-code elimination to ensure unused imports aren't removed.
111
- // Esbuild still sometimes removes unused imports because of TypeScript: https://github.com/evanw/esbuild/issues/3034
112
- options.treeShaking = false;
113
- }
114
128
  let result;
115
129
  try {
116
130
  result = await build(options);
@@ -119,7 +133,8 @@ async function transpileWithEsbuild(filePath, bundle, userRootDir) {
119
133
  await formatBuildErr(err, filePath);
120
134
  throw err;
121
135
  }
122
- if (bundle) {
136
+ // Track dependencies
137
+ if (isConfigFile) {
123
138
  assert(result.metafile);
124
139
  Object.keys(result.metafile.inputs).forEach((filePathRelative) => {
125
140
  filePathRelative = toPosixPath(filePathRelative);
@@ -132,7 +147,7 @@ async function transpileWithEsbuild(filePath, bundle, userRootDir) {
132
147
  assert(typeof code === 'string');
133
148
  return code;
134
149
  }
135
- async function executeFile(filePath, code, fileImportsTransformed, isValueFile) {
150
+ async function executeTranspiledFile(filePath, code, fileImportsTransformed, isValueFile) {
136
151
  const { filePathAbsoluteFilesystem, filePathRelativeToUserRootDir } = filePath;
137
152
  // Alternative to using a temporary file: https://github.com/vitejs/vite/pull/13269
138
153
  // - But seems to break source maps, so I don't think it's worth it
@@ -141,28 +156,35 @@ async function executeFile(filePath, code, fileImportsTransformed, isValueFile)
141
156
  const clean = () => fs.unlinkSync(filePathTmp);
142
157
  let fileExports = {};
143
158
  try {
144
- fileExports = await import_(filePathTmp);
145
- }
146
- catch (err) {
147
- triggerPrepareStackTrace(err);
148
- const errIntroMsg = getErrIntroMsg('execute', filePath);
149
- assert(isObject(err));
150
- execErrIntroMsg.set(err, errIntroMsg);
151
- throw err;
159
+ fileExports = await executeFile(filePathTmp, filePath);
152
160
  }
153
161
  finally {
154
162
  clean();
155
163
  }
156
- // Return a plain JavaScript object
157
- // - import() returns `[Module: null prototype] { default: { onRenderClient: '...' }}`
158
- // - We don't need this special object
159
- fileExports = { ...fileExports };
160
164
  if (fileImportsTransformed && !isValueFile) {
161
165
  assert(filePathRelativeToUserRootDir !== undefined);
162
166
  const filePathToShowToUser2 = getFilePathToShowToUser2(filePath);
163
167
  assertImportsAreReExported(fileImportsTransformed, fileExports, filePathToShowToUser2);
164
168
  }
165
- return { fileExports };
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;
166
188
  }
167
189
  const formatted = '_formatted';
168
190
  function getConfigBuildErrorFormatted(err) {
@@ -192,10 +214,10 @@ function getConfigExecutionErrorIntroMsg(err) {
192
214
  return errIntroMsg ?? null;
193
215
  }
194
216
  const tmpPrefix = `[build-`;
195
- function getFilePathTmp(filePath) {
196
- assertPosixPath(filePath);
197
- const dirname = path.posix.dirname(filePath);
198
- const filename = path.posix.basename(filePath);
217
+ function getFilePathTmp(filePathAbsoluteFilesystem) {
218
+ assertPosixPath(filePathAbsoluteFilesystem);
219
+ const dirname = path.posix.dirname(filePathAbsoluteFilesystem);
220
+ const filename = path.posix.basename(filePathAbsoluteFilesystem);
199
221
  // Syntax with semicolon `[build:${/*...*/}]` doesn't work on Windows: https://github.com/vikejs/vike/issues/800#issuecomment-1517329455
200
222
  const tag = `${tmpPrefix}${getRandomId(12)}]`;
201
223
  const filePathTmp = path.posix.join(dirname, `${tag}${filename}.mjs`);
@@ -250,6 +272,7 @@ function getExportedStrings(obj) {
250
272
  return exportedStrings;
251
273
  }
252
274
  function isHeaderFile(filePath) {
275
+ assertPosixPath(filePath);
253
276
  const basenameParts = path.posix.basename(filePath).split('.');
254
277
  return basenameParts.includes('h');
255
278
  }
@@ -1,7 +1,7 @@
1
1
  export { projectInfo };
2
2
  export { PROJECT_VERSION };
3
- declare const PROJECT_VERSION: "0.4.159-commit-71760c7";
3
+ declare const PROJECT_VERSION: "0.4.159-commit-a6bc208";
4
4
  declare const projectInfo: {
5
5
  projectName: "Vike";
6
- projectVersion: "0.4.159-commit-71760c7";
6
+ projectVersion: "0.4.159-commit-a6bc208";
7
7
  };
@@ -1,7 +1,7 @@
1
1
  export { projectInfo };
2
2
  export { PROJECT_VERSION };
3
3
  import { onProjectInfo } from './assertSingleInstance.js';
4
- const PROJECT_VERSION = '0.4.159-commit-71760c7';
4
+ const PROJECT_VERSION = '0.4.159-commit-a6bc208';
5
5
  const projectInfo = {
6
6
  projectName: 'Vike',
7
7
  projectVersion: PROJECT_VERSION
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vike",
3
- "version": "0.4.159-commit-71760c7",
3
+ "version": "0.4.159-commit-a6bc208",
4
4
  "scripts": {
5
5
  "dev": "tsc --watch",
6
6
  "build": "rimraf dist/ && pnpm run build:esm && pnpm run build:cjs",