vike 0.4.167 → 0.4.168-commit-7678a7d

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.
Files changed (40) hide show
  1. package/dist/cjs/node/plugin/plugins/buildConfig.js +8 -0
  2. package/dist/cjs/node/plugin/plugins/distFileNames.js +6 -0
  3. package/dist/cjs/node/plugin/plugins/extractAssetsPlugin.js +1 -1
  4. package/dist/cjs/node/plugin/plugins/importUserCode/index.js +6 -3
  5. package/dist/cjs/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/crawlPlusFiles.js +9 -1
  6. package/dist/cjs/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/loadFileAtConfigTime.js +0 -8
  7. package/dist/cjs/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/resolveImportPath.js +14 -35
  8. package/dist/cjs/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/transpileAndExecuteFile.js +121 -95
  9. package/dist/cjs/node/plugin/plugins/importUserCode/v1-design/getVikeConfig.js +27 -8
  10. package/dist/cjs/node/plugin/shared/getFilePath.js +6 -1
  11. package/dist/cjs/node/runtime/renderPage/analyzePage.js +1 -1
  12. package/dist/cjs/node/runtime/renderPage/logErrorHint.js +13 -1
  13. package/dist/cjs/node/shared/prependEntriesDir.js +1 -0
  14. package/dist/cjs/utils/assertPathIsFilesystemAbsolute.js +3 -3
  15. package/dist/cjs/utils/isDev.js +12 -4
  16. package/dist/cjs/utils/projectInfo.js +1 -1
  17. package/dist/esm/client/client-routing-runtime/history.d.ts +1 -0
  18. package/dist/esm/client/client-routing-runtime/history.js +23 -19
  19. package/dist/esm/node/plugin/plugins/buildConfig.js +8 -0
  20. package/dist/esm/node/plugin/plugins/distFileNames.js +6 -0
  21. package/dist/esm/node/plugin/plugins/extractAssetsPlugin.js +1 -1
  22. package/dist/esm/node/plugin/plugins/importUserCode/index.js +7 -4
  23. package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/crawlPlusFiles.js +9 -1
  24. package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/loadFileAtConfigTime.js +1 -9
  25. package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/resolveImportPath.js +14 -35
  26. package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/transformFileImports.d.ts +1 -1
  27. package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/transpileAndExecuteFile.d.ts +2 -2
  28. package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/transpileAndExecuteFile.js +121 -95
  29. package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig.js +28 -9
  30. package/dist/esm/node/plugin/shared/getFilePath.js +6 -1
  31. package/dist/esm/node/runtime/renderPage/analyzePage.js +1 -1
  32. package/dist/esm/node/runtime/renderPage/logErrorHint.js +13 -1
  33. package/dist/esm/node/shared/prependEntriesDir.js +1 -0
  34. package/dist/esm/shared/addUrlComputedProps.d.ts +2 -2
  35. package/dist/esm/utils/assertPathIsFilesystemAbsolute.js +3 -3
  36. package/dist/esm/utils/isDev.d.ts +3 -0
  37. package/dist/esm/utils/isDev.js +11 -3
  38. package/dist/esm/utils/projectInfo.d.ts +2 -2
  39. package/dist/esm/utils/projectInfo.js +1 -1
  40. package/package.json +2 -2
@@ -232,7 +232,15 @@ function getEntryFromPageConfig(pageConfig, isForClientSide) {
232
232
  let { pageId } = pageConfig;
233
233
  const entryTarget = (0, virtualFilePageConfigValuesAll_js_1.getVirtualFileIdPageConfigValuesAll)(pageId, isForClientSide);
234
234
  let entryName = pageId;
235
+ // Avoid:
236
+ // ```
237
+ // dist/client/assets/entries/.Dp9wM6PK.js
238
+ // dist/server/entries/.mjs
239
+ // ```
240
+ if (entryName === '/')
241
+ entryName = 'root';
235
242
  entryName = (0, prependEntriesDir_js_1.prependEntriesDir)(entryName);
243
+ (0, utils_js_1.assert)(!entryName.endsWith('/'));
236
244
  return { entryName, entryTarget };
237
245
  }
238
246
  function resolve(filePath) {
@@ -116,6 +116,12 @@ function clean(name, removePathSep, fixGlob) {
116
116
  }
117
117
  name = removeLeadingUnderscoreInFilename(name);
118
118
  name = removeUnderscoreDoublets(name);
119
+ // Avoid:
120
+ // ```
121
+ // dist/client/assets/entries/.Dp9wM6PK.js
122
+ // dist/server/entries/.mjs
123
+ // ```
124
+ (0, utils_js_1.assert)(!name.endsWith('/'));
119
125
  return name;
120
126
  }
121
127
  function fixExtractAssetsQuery(name) {
@@ -189,7 +189,7 @@ function analyzeImport(importStatement) {
189
189
  if (rawRE.test(moduleName)) {
190
190
  return { moduleName, skip: true };
191
191
  }
192
- /* We should not do this because of aliased imports
192
+ /* We shouldn't do this because of aliased imports
193
193
  if (!moduleName.startsWith('.')) {
194
194
  return { moduleName, skip: true }
195
195
  }
@@ -18,9 +18,11 @@ const getFilePath_js_1 = require("../../shared/getFilePath.js");
18
18
  function importUserCode() {
19
19
  let config;
20
20
  let configVike;
21
+ let isDev_;
21
22
  return {
22
23
  name: 'vike:importUserCode',
23
- config() {
24
+ config(_, env) {
25
+ isDev_ = (0, utils_js_1.isDev3)(env);
24
26
  return {
25
27
  experimental: {
26
28
  // TODO/v1-release: remove
@@ -48,7 +50,7 @@ function importUserCode() {
48
50
  }
49
51
  },
50
52
  async load(id, options) {
51
- const isDev = (0, utils_js_1.isDev1)();
53
+ const isDev = isDev_ !== null ? isDev_ : (0, utils_js_1.isDev1)();
52
54
  if (!(0, utils_js_1.isVirtualFileId)(id))
53
55
  return undefined;
54
56
  id = (0, utils_js_1.getVirtualFileId)(id);
@@ -62,7 +64,8 @@ function importUserCode() {
62
64
  }
63
65
  },
64
66
  configureServer(server) {
65
- (0, utils_js_1.isDev1_onConfigureServer)();
67
+ if (isDev_ === null)
68
+ (0, utils_js_1.isDev1_onConfigureServer)();
66
69
  handleFileAddRemove(server, config);
67
70
  }
68
71
  };
@@ -10,6 +10,7 @@ const fast_glob_1 = __importDefault(require("fast-glob"));
10
10
  const child_process_1 = require("child_process");
11
11
  const util_1 = require("util");
12
12
  const picocolors_1 = __importDefault(require("@brillout/picocolors"));
13
+ const transpileAndExecuteFile_js_1 = require("./transpileAndExecuteFile.js");
13
14
  const execA = (0, util_1.promisify)(child_process_1.exec);
14
15
  (0, utils_js_1.assertIsNotProductionRuntime)();
15
16
  (0, utils_js_1.assertIsSingleModuleInstance)('crawlPlusFiles.ts');
@@ -22,7 +23,13 @@ async function crawlPlusFiles(userRootDir, outDirAbsoluteFilesystem, isDev) {
22
23
  // config.outDir is outside of config.root => it's going to be ignored anyways
23
24
  outDirRelativeFromUserRootDir = null;
24
25
  }
25
- (0, utils_js_1.assert)(outDirRelativeFromUserRootDir === null || !outDirRelativeFromUserRootDir.startsWith('.'));
26
+ (0, utils_js_1.assert)(outDirRelativeFromUserRootDir === null ||
27
+ /* Not true if outDirRelativeFromUserRootDir starts with a hidden directory (i.e. a directory with a name that starts with `.`)
28
+ !outDirRelativeFromUserRootDir.startsWith('.') &&
29
+ */
30
+ (!outDirRelativeFromUserRootDir.startsWith('./') &&
31
+ //
32
+ !outDirRelativeFromUserRootDir.startsWith('../')));
26
33
  const timeBefore = new Date().getTime();
27
34
  let files = [];
28
35
  const res = await gitLsFiles(userRootDir, outDirRelativeFromUserRootDir);
@@ -34,6 +41,7 @@ async function crawlPlusFiles(userRootDir, outDirAbsoluteFilesystem, isDev) {
34
41
  else {
35
42
  files = await fastGlob(userRootDir, outDirRelativeFromUserRootDir);
36
43
  }
44
+ files = files.filter((file) => !(0, transpileAndExecuteFile_js_1.isTemporaryBuildFile)(file));
37
45
  {
38
46
  const timeAfter = new Date().getTime();
39
47
  const timeSpent = timeAfter - timeBefore;
@@ -68,7 +68,6 @@ async function loadExtendsConfigs(configFileExports, configFilePath, userRootDir
68
68
  const { importPath: importPathAbsolute } = importData;
69
69
  const filePathAbsoluteFilesystem = (0, resolveImportPath_js_1.resolveImportPath)(importData, configFilePath);
70
70
  (0, resolveImportPath_js_1.assertImportPath)(filePathAbsoluteFilesystem, importData, configFilePath);
71
- warnUserLandExtension(importPathAbsolute, configFilePath);
72
71
  const filePath = (0, getFilePath_js_1.getFilePathResolved)({ filePathAbsoluteFilesystem, userRootDir, importPathAbsolute });
73
72
  extendsConfigFiles.push(filePath);
74
73
  });
@@ -81,13 +80,6 @@ async function loadExtendsConfigs(configFileExports, configFilePath, userRootDir
81
80
  const extendsFilePaths = extendsConfigFiles.map((f) => f.filePathAbsoluteFilesystem);
82
81
  return { extendsConfigs, extendsFilePaths };
83
82
  }
84
- function warnUserLandExtension(importPath, configFilePath) {
85
- // We preserve this feature because we may need it for eject
86
- (0, utils_js_1.assertWarning)((0, utils_js_1.isNpmPackageImport)(importPath, {
87
- // Vike config files don't support path aliases. (If they do one day, then Vike will/should be able to resolve path aliases.)
88
- cannotBePathAlias: true
89
- }) || importPath.includes('/node_modules/'), `${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 });
90
- }
91
83
  function getExtendsImportData(configFileExports, configFilePath) {
92
84
  const { filePathToShowToUser } = configFilePath;
93
85
  const configFileExport = (0, getConfigFileExport_js_1.getConfigFileExport)(configFileExports, filePathToShowToUser);
@@ -22,13 +22,22 @@ function resolveImport(configValue, importerFilePath, userRootDir, configEnv, co
22
22
  const fileExportPathToShowToUser = exportName === 'default' || exportName === configName ? [] : [exportName];
23
23
  let filePath;
24
24
  if (importPath.startsWith('.')) {
25
- // We need to resolve relative paths into absolute paths. Because the import paths are included in virtual files:
25
+ (0, utils_js_1.assert)(importPath.startsWith('./') || importPath.startsWith('../'));
26
+ assertImportPath(filePathAbsoluteFilesystem, importData, importerFilePath);
27
+ filePath = (0, getFilePath_js_1.getFilePathResolved)({ filePathAbsoluteFilesystem, userRootDir });
28
+ // Imports are included in virtual files, thus the relative path of imports need to resolved.
26
29
  // ```
27
30
  // [vite] Internal server error: Failed to resolve import "./onPageTransitionHooks" from "virtual:vike:pageConfigValuesAll:client:/pages/index". Does the file exist?
28
31
  // ```
29
- assertImportPath(filePathAbsoluteFilesystem, importData, importerFilePath);
30
- const filePathAbsoluteUserRootDir = resolveImportPath_absoluteUserRootDir(filePathAbsoluteFilesystem, importData, importerFilePath, userRootDir);
31
- filePath = (0, getFilePath_js_1.getFilePathResolved)({ filePathAbsoluteUserRootDir, userRootDir });
32
+ (0, utils_js_1.assertUsage)(filePath.filePathAbsoluteUserRootDir, `${importerFilePath.filePathToShowToUser} imports a relative path ${picocolors_1.default.cyan(importPath)} resolving outside of ${userRootDir} which is forbidden: import from a relative path inside ${userRootDir}, or import from a dependency's package.json#exports entry instead`);
33
+ // Alternativey, we can try one of the following but last time we tried none of the following worked.
34
+ // /*
35
+ // assert(filePathAbsoluteFilesystem.startsWith('/'))
36
+ // filePath = `/@fs${filePathAbsoluteFilesystem}`
37
+ // /*/
38
+ // assert(filePathAbsoluteUserRootDir.startsWith('../'))
39
+ // filePathAbsoluteUserRootDir = '/' + filePathAbsoluteUserRootDir
40
+ // //*/
32
41
  }
33
42
  else {
34
43
  // importPath can be:
@@ -54,28 +63,6 @@ function resolveImport(configValue, importerFilePath, userRootDir, configEnv, co
54
63
  };
55
64
  }
56
65
  exports.resolveImport = resolveImport;
57
- function resolveImportPath_absoluteUserRootDir(filePathAbsoluteFilesystem, importData, configFilePath, userRootDir) {
58
- (0, utils_js_1.assertPosixPath)(userRootDir);
59
- let filePathAbsoluteUserRootDir;
60
- if (filePathAbsoluteFilesystem.startsWith(userRootDir)) {
61
- filePathAbsoluteUserRootDir = getVitePathFromAbsolutePath(filePathAbsoluteFilesystem, userRootDir);
62
- }
63
- else {
64
- (0, utils_js_1.assertUsage)(false, `${configFilePath.filePathToShowToUser} imports from a relative path ${picocolors_1.default.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`);
65
- // None of the following works. Seems to be a Vite bug?
66
- // /*
67
- // assert(filePathAbsoluteFilesystem.startsWith('/'))
68
- // filePath = `/@fs${filePathAbsoluteFilesystem}`
69
- // /*/
70
- // filePathAbsoluteUserRootDir = path.posix.relative(userRootDir, filePathAbsoluteFilesystem)
71
- // assert(filePathAbsoluteUserRootDir.startsWith('../'))
72
- // filePathAbsoluteUserRootDir = '/' + filePathAbsoluteUserRootDir
73
- // //*/
74
- }
75
- (0, utils_js_1.assertPosixPath)(filePathAbsoluteUserRootDir);
76
- (0, utils_js_1.assert)(filePathAbsoluteUserRootDir.startsWith('/'));
77
- return filePathAbsoluteUserRootDir;
78
- }
79
66
  function resolveImportPath(importData, importerFilePath) {
80
67
  const importerFilePathAbsolute = importerFilePath.filePathAbsoluteFilesystem;
81
68
  (0, utils_js_1.assertPosixPath)(importerFilePathAbsolute);
@@ -97,6 +84,7 @@ function assertImportPath(filePathAbsoluteFilesystem, importData, importerFilePa
97
84
  : `The import ${picocolors_1.default.cyan(importString)} defined in ${filePathToShowToUser}`;
98
85
  const errIntro2 = `${errIntro} couldn't be resolved: does ${importPathString}`;
99
86
  if (importPath.startsWith('.')) {
87
+ (0, utils_js_1.assert)(importPath.startsWith('./') || importPath.startsWith('../'));
100
88
  (0, utils_js_1.assertUsage)(false, `${errIntro2} point to an existing file?`);
101
89
  }
102
90
  else {
@@ -125,12 +113,3 @@ function clearFilesEnvMap() {
125
113
  filesEnvMap.clear();
126
114
  }
127
115
  exports.clearFilesEnvMap = clearFilesEnvMap;
128
- function getVitePathFromAbsolutePath(filePathAbsoluteFilesystem, root) {
129
- (0, utils_js_1.assertPosixPath)(filePathAbsoluteFilesystem);
130
- (0, utils_js_1.assertPosixPath)(root);
131
- (0, utils_js_1.assert)(filePathAbsoluteFilesystem.startsWith(root));
132
- let vitePath = path_1.default.posix.relative(root, filePathAbsoluteFilesystem);
133
- (0, utils_js_1.assert)(!vitePath.startsWith('/') && !vitePath.startsWith('.'));
134
- vitePath = '/' + vitePath;
135
- return vitePath;
136
- }
@@ -3,7 +3,7 @@ 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.isTmpFile = exports.getConfigExecutionErrorIntroMsg = exports.getConfigBuildErrorFormatted = exports.transpileAndExecuteFile = void 0;
6
+ exports.isTemporaryBuildFile = exports.getConfigExecutionErrorIntroMsg = exports.getConfigBuildErrorFormatted = exports.transpileAndExecuteFile = void 0;
7
7
  const esbuild_1 = require("esbuild");
8
8
  const fs_1 = __importDefault(require("fs"));
9
9
  const path_1 = __importDefault(require("path"));
@@ -82,87 +82,96 @@ async function transpileWithEsbuild(filePath, userRootDir, transformImports) {
82
82
  // Esbuild still sometimes removes unused imports because of TypeScript: https://github.com/evanw/esbuild/issues/3034
83
83
  treeShaking: false,
84
84
  minify: false,
85
- metafile: transformImports !== 'all',
86
- bundle: transformImports !== 'all'
85
+ metafile: true,
86
+ bundle: true
87
87
  };
88
- let pointerImports;
89
- if (transformImports === 'all') {
90
- pointerImports = 'all';
91
- options.packages = 'external';
92
- }
93
- else {
94
- const pointerImports_ = (pointerImports = {});
95
- options.plugins = [
96
- // Determine what import should be externalized (and then transformed to a pointer/fake import)
97
- {
98
- name: 'vike:externalize-heuristic',
99
- setup(build) {
100
- // https://github.com/evanw/esbuild/issues/3095#issuecomment-1546916366
88
+ let pointerImports = {};
89
+ options.plugins = [
90
+ // Determine whether an import should be:
91
+ // - A pointer import
92
+ // - Externalized
93
+ {
94
+ name: 'vike-esbuild',
95
+ setup(build) {
96
+ // https://github.com/brillout/esbuild-playground
97
+ build.onResolve({ filter: /.*/ }, async (args) => {
98
+ if (args.kind !== 'import-statement')
99
+ return;
100
+ // Avoid infinite loop: https://github.com/evanw/esbuild/issues/3095#issuecomment-1546916366
101
101
  const useEsbuildResolver = 'useEsbuildResolver';
102
- // https://github.com/brillout/esbuild-playground
103
- build.onResolve({ filter: /.*/ }, async (args) => {
104
- if (args.kind !== 'import-statement')
105
- return;
106
- if (args.pluginData?.[useEsbuildResolver])
107
- return;
108
- const { path, ...opts } = args;
109
- opts.pluginData = { [useEsbuildResolver]: true };
110
- const resolved = await build.resolve(path, opts);
111
- resolved.path = (0, utils_js_1.toPosixPath)(resolved.path);
112
- // vike-{react,vue,solid} follow the convention that their config export resolves to a file named +config.js
113
- // - This is temporary, see comment below.
114
- const isVikeExtensionConfigImport = resolved.path.endsWith('+config.js');
115
- const isPointerImport =
102
+ if (args.pluginData?.[useEsbuildResolver])
103
+ return;
104
+ const { path, ...opts } = args;
105
+ opts.pluginData = { [useEsbuildResolver]: true };
106
+ const resolved = await build.resolve(path, opts);
107
+ if (resolved.errors.length > 0) {
108
+ /* We could do the following to let Node.js throw the error, but we don't because the error shown by esbuild is prettier: the Node.js error refers to the transpiled [build-f7i251e0iwnw]+config.ts.mjs file which isn't that nice, whereas esbuild refers to the source +config.ts file.
109
+ pointerImports[args.path] = false
110
+ return { external: true }
111
+ */
112
+ // Let esbuild throw the error. (It throws a nice & pretty error.)
113
+ cleanEsbuildErrors(resolved.errors);
114
+ return resolved;
115
+ }
116
+ (0, utils_js_1.assert)(resolved.path);
117
+ resolved.path = (0, utils_js_1.toPosixPath)(resolved.path);
118
+ // vike-{react,vue,solid} follow the convention that their config export resolves to a file named +config.js
119
+ // - This is temporary, see comment below.
120
+ const isVikeExtensionConfigImport = resolved.path.endsWith('+config.js');
121
+ const isPointerImport = transformImports === 'all' ||
116
122
  // .jsx, .vue, .svg, ... => obviously not config code
117
123
  !(0, utils_js_1.isJavaScriptFile)(resolved.path) ||
118
- // Import of a Vike extension config => make it a pointer import because we want to show nice error messages (that can display whether a configas been set by the user or by a Vike extension).
119
- // - We should have Node.js directly load vike-{react,vue,solid} while enforcing Vike extensions to set 'name' in their +config.js file.
120
- // - vike@0.4.162 already started soft-requiring Vike extensions to set the name config
121
- isVikeExtensionConfigImport ||
122
- // Cannot be resolved by esbuild => take a leap of faith and make it a pointer import.
123
- // - For example if esbuild cannot resolve a path alias while Vite can.
124
- // - When tsconfig.js#compilerOptions.paths is set, then esbuild is able to resolve the path alias.
125
- resolved.errors.length > 0;
126
- pointerImports_[resolved.path] = isPointerImport;
127
- (0, utils_js_1.assertPosixPath)(resolved.path);
128
- const isExternal = isPointerImport ||
129
- // npm package imports that aren't pointer imports (e.g. importing a Vite plugin)
130
- resolved.path.includes('/node_modules/');
131
- if (debug.isActivated)
132
- debug('onResolved()', { args, resolved, isPointerImport, isExternal });
133
- if (isExternal) {
134
- return { external: true, path: resolved.path };
135
- }
136
- else {
137
- return resolved;
138
- }
139
- });
140
- }
141
- },
142
- // Track dependencies
143
- {
144
- name: 'vike:dependency-tracker',
145
- setup(b) {
146
- b.onLoad({ filter: /./ }, (args) => {
147
- // We collect the dependency `args.path` in case the bulid fails (upon build error => error is thrown => no metafile)
148
- let { path } = args;
149
- path = (0, utils_js_1.toPosixPath)(path);
150
- getVikeConfig_js_1.vikeConfigDependencies.add(path);
151
- return undefined;
152
- });
153
- /* To exhaustively collect all dependencies upon build failure, we would also need to use onResolve().
154
- * - Because onLoad() isn't call if the config dependency can't be resolved.
155
- * - For example, the following breaks auto-reload (the config is stuck in its error state and the user needs to touch the importer for the config to reload):
156
- * ```bash
157
- * mv ./some-config-dependency.js /tmp/ && mv /tmp/some-config-dependency.js .
158
- * ```
159
- * - But implementing a fix is complex and isn't worth it.
160
- b.onResolve(...)
161
- */
162
- }
124
+ // Import of a Vike extension config => make it a pointer import because we want to show nice error messages (that can display whether a configas been set by the user or by a Vike extension).
125
+ // - We should have Node.js directly load vike-{react,vue,solid} while enforcing Vike extensions to set 'name' in their +config.js file.
126
+ // - vike@0.4.162 already started soft-requiring Vike extensions to set the name config
127
+ isVikeExtensionConfigImport ||
128
+ // Cannot be resolved by esbuild => take a leap of faith and make it a pointer import.
129
+ // - For example if esbuild cannot resolve a path alias while Vite can.
130
+ // - When tsconfig.js#compilerOptions.paths is set, then esbuild is able to resolve the path alias.
131
+ resolved.errors.length > 0;
132
+ pointerImports[resolved.path] = isPointerImport;
133
+ (0, utils_js_1.assertPosixPath)(resolved.path);
134
+ const isExternal = isPointerImport ||
135
+ // Performance: npm package imports that aren't pointer imports can be externalized. For example, if Vike eventually adds support for setting Vite configs in the vike.config.js file, then the user may import a Vite plugin in his vike.config.js file. (We could as well let esbuild always transpile /node_modules/ code but it would be useless and would unnecessarily slow down transpilation.)
136
+ resolved.path.includes('/node_modules/');
137
+ if (debug.isActivated)
138
+ debug('onResolved()', { args, resolved, isPointerImport, isExternal });
139
+ // We need esbuild to resolve path aliases so that we can use:
140
+ // isNpmPackageImport(str, { cannotBePathAlias: true })
141
+ // assertIsNpmPackageImport()
142
+ (0, utils_js_1.assertPathIsFilesystemAbsolute)(resolved.path);
143
+ if (isExternal) {
144
+ return { external: true, path: resolved.path };
145
+ }
146
+ else {
147
+ return resolved;
148
+ }
149
+ });
163
150
  }
164
- ];
165
- }
151
+ },
152
+ // Track dependencies
153
+ {
154
+ name: 'vike:dependency-tracker',
155
+ setup(b) {
156
+ b.onLoad({ filter: /./ }, (args) => {
157
+ // We collect the dependency `args.path` in case the bulid fails (upon build error => error is thrown => no metafile)
158
+ let { path } = args;
159
+ path = (0, utils_js_1.toPosixPath)(path);
160
+ getVikeConfig_js_1.vikeConfigDependencies.add(path);
161
+ return undefined;
162
+ });
163
+ /* To exhaustively collect all dependencies upon build failure, we would also need to use onResolve().
164
+ * - Because onLoad() isn't call if the config dependency can't be resolved.
165
+ * - For example, the following breaks auto-reload (the config is stuck in its error state and the user needs to touch the importer for the config to reload):
166
+ * ```bash
167
+ * mv ./some-config-dependency.js /tmp/ && mv /tmp/some-config-dependency.js .
168
+ * ```
169
+ * - But implementing a fix is complex and isn't worth it.
170
+ b.onResolve(...)
171
+ */
172
+ }
173
+ }
174
+ ];
166
175
  let result;
167
176
  try {
168
177
  result = await (0, esbuild_1.build)(options);
@@ -172,15 +181,13 @@ async function transpileWithEsbuild(filePath, userRootDir, transformImports) {
172
181
  throw err;
173
182
  }
174
183
  // Track dependencies
175
- if (transformImports !== 'all') {
176
- (0, utils_js_1.assert)(result.metafile);
177
- Object.keys(result.metafile.inputs).forEach((filePathRelative) => {
178
- filePathRelative = (0, utils_js_1.toPosixPath)(filePathRelative);
179
- (0, utils_js_1.assertPosixPath)(userRootDir);
180
- const filePathAbsoluteFilesystem = path_1.default.posix.join(userRootDir, filePathRelative);
181
- getVikeConfig_js_1.vikeConfigDependencies.add(filePathAbsoluteFilesystem);
182
- });
183
- }
184
+ (0, utils_js_1.assert)(result.metafile);
185
+ Object.keys(result.metafile.inputs).forEach((filePathRelative) => {
186
+ filePathRelative = (0, utils_js_1.toPosixPath)(filePathRelative);
187
+ (0, utils_js_1.assertPosixPath)(userRootDir);
188
+ const filePathAbsoluteFilesystem = path_1.default.posix.join(userRootDir, filePathRelative);
189
+ getVikeConfig_js_1.vikeConfigDependencies.add(filePathAbsoluteFilesystem);
190
+ });
184
191
  const code = result.outputFiles[0].text;
185
192
  (0, utils_js_1.assert)(typeof code === 'string');
186
193
  return { code, pointerImports };
@@ -189,7 +196,7 @@ async function executeTranspiledFile(filePath, code) {
189
196
  const { filePathAbsoluteFilesystem } = filePath;
190
197
  // Alternative to using a temporary file: https://github.com/vitejs/vite/pull/13269
191
198
  // - But seems to break source maps, so I don't think it's worth it
192
- const filePathTmp = getFilePathTmp(filePathAbsoluteFilesystem);
199
+ const filePathTmp = getTemporaryBuildFilePath(filePathAbsoluteFilesystem);
193
200
  fs_1.default.writeFileSync(filePathTmp, code);
194
201
  const clean = () => fs_1.default.unlinkSync(filePathTmp);
195
202
  let fileExports = {};
@@ -248,22 +255,21 @@ function getConfigExecutionErrorIntroMsg(err) {
248
255
  return errIntroMsg ?? null;
249
256
  }
250
257
  exports.getConfigExecutionErrorIntroMsg = getConfigExecutionErrorIntroMsg;
251
- const tmpPrefix = `[build-`;
252
- function getFilePathTmp(filePathAbsoluteFilesystem) {
258
+ function getTemporaryBuildFilePath(filePathAbsoluteFilesystem) {
253
259
  (0, utils_js_1.assertPosixPath)(filePathAbsoluteFilesystem);
254
260
  const dirname = path_1.default.posix.dirname(filePathAbsoluteFilesystem);
255
261
  const filename = path_1.default.posix.basename(filePathAbsoluteFilesystem);
256
- // Syntax with semicolon `[build:${/*...*/}]` doesn't work on Windows: https://github.com/vikejs/vike/issues/800#issuecomment-1517329455
257
- const tag = `${tmpPrefix}${(0, utils_js_1.getRandomId)(12)}]`;
258
- const filePathTmp = path_1.default.posix.join(dirname, `${tag}${filename}.mjs`);
262
+ // Syntax with semicolon `build:${/*...*/}` doesn't work on Windows: https://github.com/vikejs/vike/issues/800#issuecomment-1517329455
263
+ const filePathTmp = path_1.default.posix.join(dirname, `${filename}.build-${(0, utils_js_1.getRandomId)(12)}.mjs`);
264
+ (0, utils_js_1.assert)(isTemporaryBuildFile(filePathTmp));
259
265
  return filePathTmp;
260
266
  }
261
- function isTmpFile(filePath) {
267
+ function isTemporaryBuildFile(filePath) {
262
268
  (0, utils_js_1.assertPosixPath)(filePath);
263
269
  const fileName = path_1.default.posix.basename(filePath);
264
- return fileName.startsWith(tmpPrefix);
270
+ return /\.build-[a-z0-9]{12}\.mjs$/.test(fileName);
265
271
  }
266
- exports.isTmpFile = isTmpFile;
272
+ exports.isTemporaryBuildFile = isTemporaryBuildFile;
267
273
  function isHeaderFile(filePath) {
268
274
  (0, utils_js_1.assertPosixPath)(filePath);
269
275
  const fileExtensions = getFileExtensions(filePath);
@@ -306,3 +312,23 @@ function getErrIntroMsg(operation, filePath) {
306
312
  ].join(' ');
307
313
  return msg;
308
314
  }
315
+ function cleanEsbuildErrors(errors) {
316
+ errors.forEach((e) => (e.notes = e.notes.filter((note) =>
317
+ // Remove note:
318
+ // ```shell
319
+ // You can mark the path "#root/renderer/onRenderHtml_typo" as external to exclude it from the bundle, which will remove this error and leave the unresolved path in the bundle.
320
+ // ```
321
+ //
322
+ // From error:
323
+ // ```shell
324
+ // ✘ [ERROR] Could not resolve "#root/renderer/onRenderHtml_typo" [plugin vike-esbuild]
325
+ //
326
+ // renderer/+config.h.js:1:29:
327
+ // 1 │ import { onRenderHtml } from "#root/renderer/onRenderHtml_typo"
328
+ // ╵ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
329
+ //
330
+ // You can mark the path "#root/renderer/onRenderHtml_typo" as external to exclude it from the bundle, which will remove this error and leave the unresolved path in the bundle.
331
+ //
332
+ // ```
333
+ !note.text.includes('as external to exclude it from the bundle'))));
334
+ }
@@ -750,7 +750,7 @@ async function findPlusFiles(userRootDir, outDirRoot, isDev) {
750
750
  }
751
751
  function getConfigName(filePath) {
752
752
  (0, utils_js_1.assertPosixPath)(filePath);
753
- if ((0, transpileAndExecuteFile_js_1.isTmpFile)(filePath))
753
+ if ((0, transpileAndExecuteFile_js_1.isTemporaryBuildFile)(filePath))
754
754
  return null;
755
755
  const fileName = path_1.default.posix.basename(filePath);
756
756
  // assertNoUnexpectedPlusSign(filePath, fileName)
@@ -781,7 +781,30 @@ function assertNoUnexpectedPlusSign(filePath: string, fileName: string) {
781
781
  }
782
782
  */
783
783
  function handleUnknownConfig(configName, configNames, filePathToShowToUser) {
784
- let errMsg = `${filePathToShowToUser} defines an unknown config ${picocolors_1.default.cyan(configName)}`;
784
+ {
785
+ const ui = ['vike-react', 'vike-vue', 'vike-solid'];
786
+ const knownVikeExntensionConfigs = {
787
+ description: ui,
788
+ favicon: ui,
789
+ Head: ui,
790
+ Layout: ui,
791
+ onCreateApp: ['vike-vue'],
792
+ title: ui,
793
+ ssr: ui,
794
+ stream: ui,
795
+ Wrapper: ui
796
+ };
797
+ if (configName in knownVikeExntensionConfigs) {
798
+ const requiredVikeExtension = knownVikeExntensionConfigs[configName];
799
+ (0, utils_js_1.assertUsage)(false, [
800
+ `${filePathToShowToUser} uses the config ${picocolors_1.default.cyan(configName)} (https://vike.dev/${configName})`,
801
+ `which requires the Vike extension ${requiredVikeExtension.map((e) => picocolors_1.default.bold(e)).join('/')}.`,
802
+ `Make sure to install the Vike extension,`,
803
+ `and make sure it applies to ${filePathToShowToUser} as explained at https://vike.dev/extends#inheritance.`
804
+ ].join(' '));
805
+ }
806
+ }
807
+ let errMsg = `${filePathToShowToUser} sets an unknown config ${picocolors_1.default.cyan(configName)}`;
785
808
  let configNameSimilar = null;
786
809
  if (configName === 'page') {
787
810
  configNameSimilar = 'Page';
@@ -789,17 +812,13 @@ function handleUnknownConfig(configName, configNames, filePathToShowToUser) {
789
812
  else {
790
813
  configNameSimilar = (0, utils_js_1.getMostSimilar)(configName, configNames);
791
814
  }
792
- if (configNameSimilar || configName === 'page') {
793
- (0, utils_js_1.assert)(configNameSimilar);
815
+ if (configNameSimilar) {
794
816
  (0, utils_js_1.assert)(configNameSimilar !== configName);
795
- errMsg += `, did you mean to define ${picocolors_1.default.cyan(configNameSimilar)} instead?`;
817
+ errMsg += `, did you mean to set ${picocolors_1.default.cyan(configNameSimilar)} instead?`;
796
818
  if (configName === 'page') {
797
819
  errMsg += ` (The name of the config ${picocolors_1.default.cyan('Page')} starts with a capital letter ${picocolors_1.default.cyan('P')} because it usually defines a UI component: a ubiquitous JavaScript convention is to start the name of UI components with a capital letter.)`;
798
820
  }
799
821
  }
800
- else {
801
- errMsg += `, you need to define the config ${picocolors_1.default.cyan(configName)} by using ${picocolors_1.default.cyan('config.meta')} https://vike.dev/meta`;
802
- }
803
822
  (0, utils_js_1.assertUsage)(false, errMsg);
804
823
  }
805
824
  function determineRouteFilesystem(locationId, configValueSources) {
@@ -90,7 +90,12 @@ function getFilePathAbsoluteUserRootDir({ filePathAbsoluteFilesystem, userRootDi
90
90
  (0, utils_js_1.assert)(filePathRelative.startsWith('../'));
91
91
  return null;
92
92
  }
93
- (0, utils_js_1.assert)(!filePathRelative.startsWith('.') && !filePathRelative.startsWith('/'));
93
+ (0, utils_js_1.assert)(!filePathRelative.startsWith('/') &&
94
+ /* Not true if filePathRelative starts with a hidden directory (i.e. a directory with a name that starts with `.`)
95
+ !filePathRelative.startsWith('.') &&
96
+ */
97
+ !filePathRelative.startsWith('./') &&
98
+ !filePathRelative.startsWith('../'));
94
99
  const filePathAbsoluteUserRootDir = `/${filePathRelative}`;
95
100
  (0, utils_js_1.assert)(filePathAbsoluteUserRootDir === getFilePathAbsoluteUserRootDir2(filePathAbsoluteFilesystem, userRootDir));
96
101
  return filePathAbsoluteUserRootDir;
@@ -15,7 +15,7 @@ function analyzePage(pageFilesAll, pageConfig, pageId) {
15
15
  const clientDependencies = [];
16
16
  clientDependencies.push({
17
17
  id: (0, virtualFilePageConfigValuesAll_js_1.getVirtualFileIdPageConfigValuesAll)(pageConfig.pageId, true),
18
- onlyAssets: false,
18
+ onlyAssets: isClientSideRenderable ? false : true,
19
19
  eagerlyImported: false
20
20
  });
21
21
  // In production we inject the import of the server virtual module with ?extractAssets inside the client virtual module
@@ -21,6 +21,10 @@ const knownErrors = [
21
21
  // ```
22
22
  errMsg: 'assets.json',
23
23
  link: 'https://vike.dev/getGlobalContext'
24
+ },
25
+ {
26
+ errMsg: /Named export.*not found/i,
27
+ link: 'https://vike.dev/broken-npm-package#named-export-not-found'
24
28
  }
25
29
  ];
26
30
  function logErrorHint(error) {
@@ -290,7 +294,15 @@ function extractFromNodeModulesPath(str) {
290
294
  return packageName;
291
295
  }
292
296
  function includes(str1, str2) {
293
- return !!str1 && str1.toLowerCase().includes(str2.toLowerCase());
297
+ if (!str1)
298
+ return false;
299
+ if (str2 instanceof RegExp) {
300
+ return str2.test(str1.toLowerCase());
301
+ }
302
+ if (typeof str2 === 'string') {
303
+ return str1.toLowerCase().includes(str2.toLowerCase());
304
+ }
305
+ return false;
294
306
  }
295
307
  function includesNodeModules(str) {
296
308
  if (!str)
@@ -7,6 +7,7 @@ function prependEntriesDir(entryName) {
7
7
  entryName = entryName.slice(1);
8
8
  }
9
9
  (0, utils_js_1.assert)(!entryName.startsWith('/'));
10
+ (0, utils_js_1.assert)(entryName);
10
11
  entryName = `entries/${entryName}`;
11
12
  return entryName;
12
13
  }
@@ -11,11 +11,11 @@ const filesystemPathHandling_js_1 = require("./filesystemPathHandling.js");
11
11
  function assertPathIsFilesystemAbsolute(p) {
12
12
  (0, filesystemPathHandling_js_1.assertPosixPath)(p);
13
13
  (0, assert_js_1.assert)(!p.startsWith('/@fs/'));
14
- if (process.platform === 'win32') {
15
- (0, assert_js_1.assert)(path_1.default.win32.isAbsolute(p));
14
+ if (process.platform !== 'win32') {
15
+ (0, assert_js_1.assert)(p.startsWith('/'));
16
16
  }
17
17
  else {
18
- (0, assert_js_1.assert)(p.startsWith('/'));
18
+ (0, assert_js_1.assert)(path_1.default.win32.isAbsolute(p));
19
19
  }
20
20
  }
21
21
  exports.assertPathIsFilesystemAbsolute = assertPathIsFilesystemAbsolute;