@salesforce/storefront-next-dev 1.2.0 → 1.3.0-alpha.1
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/README.md +33 -0
- package/dist/cartridge-services/index.js +2 -1
- package/dist/cartridge-services/index.js.map +1 -1
- package/dist/commands/extensions/remove.js +6 -1
- package/dist/commands/locales/aggregate-extensions.js +18 -9
- package/dist/dependency-utils.js +19 -10
- package/dist/entry/server.js +5 -3
- package/dist/entry/server.js.map +1 -1
- package/dist/format-with-project-biome.js +32 -47
- package/dist/generate-cartridge.js +2 -1
- package/dist/index.d.ts +21 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +228 -10
- package/dist/index.js.map +1 -1
- package/dist/logger.js +1 -1
- package/dist/manage-extensions.js +11 -9
- package/dist/mrt/ssr.mjs +52 -51
- package/dist/mrt/ssr.mjs.map +1 -1
- package/dist/mrt/streamingHandler.mjs +58 -57
- package/dist/mrt/streamingHandler.mjs.map +1 -1
- package/dist/react-router/Scripts.d.ts.map +1 -1
- package/dist/react-router/Scripts.js +2 -1
- package/dist/react-router/Scripts.js.map +1 -1
- package/dist/server.js +5 -3
- package/package.json +5 -5
package/dist/index.js
CHANGED
|
@@ -1,17 +1,18 @@
|
|
|
1
|
-
import path, { resolve } from "node:path";
|
|
1
|
+
import path, { relative, resolve } from "node:path";
|
|
2
2
|
import fs from "fs-extra";
|
|
3
3
|
import chalk from "chalk";
|
|
4
4
|
import { createRequire } from "module";
|
|
5
|
-
import path$1, { basename, dirname, join, relative, resolve as resolve$1 } from "path";
|
|
5
|
+
import path$1, { basename, dirname, join, relative as relative$1, resolve as resolve$1 } from "path";
|
|
6
6
|
import { fileURLToPath } from "url";
|
|
7
7
|
import { parse } from "@babel/parser";
|
|
8
8
|
import { isArrayPattern, isClassDeclaration, isExportSpecifier, isFunctionDeclaration, isIdentifier, isJSXAttribute, isJSXElement, isJSXFragment, isJSXIdentifier, isMemberExpression, isObjectPattern, isObjectProperty, isRestElement, isVariableDeclaration, jsxClosingElement, jsxClosingFragment, jsxElement, jsxFragment, jsxIdentifier, jsxOpeningElement, jsxOpeningFragment, jsxText } from "@babel/types";
|
|
9
9
|
import { generate } from "@babel/generator";
|
|
10
10
|
import _traverse from "@babel/traverse";
|
|
11
|
-
import { existsSync, readFileSync, writeFileSync } from "fs";
|
|
11
|
+
import { existsSync, mkdirSync, readFileSync, unlinkSync, writeFileSync } from "fs";
|
|
12
12
|
import { glob } from "glob";
|
|
13
13
|
import { Node, Project, ts } from "ts-morph";
|
|
14
14
|
import { spawnSync } from "child_process";
|
|
15
|
+
import { brotliCompressSync, constants, gzipSync } from "node:zlib";
|
|
15
16
|
import fs$1, { existsSync as existsSync$1, readFileSync as readFileSync$1 } from "node:fs";
|
|
16
17
|
import { deadCodeElimination, findReferencedIdentifiers } from "babel-dead-code-elimination";
|
|
17
18
|
import httpProxy from "http-proxy";
|
|
@@ -872,6 +873,165 @@ function resolveBiomeBin(filePath) {
|
|
|
872
873
|
return null;
|
|
873
874
|
}
|
|
874
875
|
|
|
876
|
+
//#endregion
|
|
877
|
+
//#region src/plugins/pageDesignerPreloadManifest.ts
|
|
878
|
+
const PAGE_DESIGNER_PRELOAD_MANIFEST_ID = "virtual:storefront-next/page-designer-preload-manifest";
|
|
879
|
+
const RESOLVED_PAGE_DESIGNER_PRELOAD_MANIFEST_ID = `\0${PAGE_DESIGNER_PRELOAD_MANIFEST_ID}`;
|
|
880
|
+
function correlateComponentRecords(source, viteManifest, bundle, projectRoot) {
|
|
881
|
+
const directMatches = Object.entries(viteManifest).filter(([key, record]) => normalizeSourceId(projectRoot, key) === source || normalizeSourceId(projectRoot, record.src ?? "") === source);
|
|
882
|
+
if (directMatches.length > 0) return directMatches;
|
|
883
|
+
const containingFiles = new Set(Object.values(bundle).filter((output) => output.type === "chunk" && Object.keys(output.modules ?? {}).some((moduleId) => normalizeSourceId(projectRoot, moduleId) === source)).map((chunk) => chunk.fileName));
|
|
884
|
+
return Object.entries(viteManifest).filter(([, record]) => containingFiles.has(record.file)).map(([key, record]) => [key, {
|
|
885
|
+
...record,
|
|
886
|
+
isDynamicEntry: !record.isEntry
|
|
887
|
+
}]);
|
|
888
|
+
}
|
|
889
|
+
function assertViteManifestStructure(value) {
|
|
890
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) throw new Error("Invalid standard Vite manifest: expected a top-level object");
|
|
891
|
+
for (const [key, record] of Object.entries(value)) {
|
|
892
|
+
if (!record || typeof record !== "object" || Array.isArray(record)) throw new Error(`Invalid standard Vite manifest: record "${key}" must be an object`);
|
|
893
|
+
if (!("file" in record) || typeof record.file !== "string" || record.file.length === 0) throw new Error(`Invalid standard Vite manifest: record "${key}" must have a non-empty string "file"`);
|
|
894
|
+
}
|
|
895
|
+
}
|
|
896
|
+
function integerInRange(value, path$2, min, max, fallback) {
|
|
897
|
+
if (value === void 0) return fallback;
|
|
898
|
+
if (!Number.isInteger(value) || value < min || value > max) throw new Error(`${path$2} must be an integer between ${min} and ${max}`);
|
|
899
|
+
return value;
|
|
900
|
+
}
|
|
901
|
+
function normalizePageDesignerPreloadManifestConfig(config) {
|
|
902
|
+
const options = typeof config === "object" ? config : {};
|
|
903
|
+
return {
|
|
904
|
+
path: options.path ?? "page-designer-preload-manifest.json",
|
|
905
|
+
requiredTypeIds: [...new Set(options.requiredTypeIds ?? [])].sort(),
|
|
906
|
+
compression: {
|
|
907
|
+
brotli: { quality: integerInRange(options.compression?.brotli?.quality, "preloadManifest.compression.brotli.quality", 0, 11, 9) },
|
|
908
|
+
gzip: { level: integerInRange(options.compression?.gzip?.level, "preloadManifest.compression.gzip.level", 0, 9, 6) }
|
|
909
|
+
}
|
|
910
|
+
};
|
|
911
|
+
}
|
|
912
|
+
function createEmptyPageDesignerPreloadManifest(config) {
|
|
913
|
+
return {
|
|
914
|
+
version: 1,
|
|
915
|
+
compression: config.compression,
|
|
916
|
+
resources: [],
|
|
917
|
+
components: {}
|
|
918
|
+
};
|
|
919
|
+
}
|
|
920
|
+
function normalizeSourceId(projectRoot, id) {
|
|
921
|
+
const withoutQuery = id.split("?", 1)[0].replace(/\\/g, "/");
|
|
922
|
+
const normalizedRoot = projectRoot.replace(/\\/g, "/").replace(/\/$/, "");
|
|
923
|
+
if (withoutQuery === normalizedRoot) return "";
|
|
924
|
+
if (withoutQuery.startsWith(`${normalizedRoot}/`)) return withoutQuery.slice(normalizedRoot.length + 1);
|
|
925
|
+
return withoutQuery.startsWith("/") ? relative(projectRoot, withoutQuery).replace(/\\/g, "/") : withoutQuery;
|
|
926
|
+
}
|
|
927
|
+
function outputBytes(output) {
|
|
928
|
+
if (output.type === "chunk") return Buffer.from(output.code);
|
|
929
|
+
return Buffer.isBuffer(output.source) ? output.source : Buffer.from(output.source);
|
|
930
|
+
}
|
|
931
|
+
function describeResource(file, kind, bundle, config) {
|
|
932
|
+
const output = bundle[file];
|
|
933
|
+
if (!output) throw new Error(`Vite manifest references missing emitted resource "${file}"`);
|
|
934
|
+
const bytes = outputBytes(output);
|
|
935
|
+
return {
|
|
936
|
+
file,
|
|
937
|
+
kind,
|
|
938
|
+
bytes: bytes.byteLength,
|
|
939
|
+
estimatedBrotliBytes: brotliCompressSync(bytes, { params: { [constants.BROTLI_PARAM_QUALITY]: config.compression.brotli.quality } }).byteLength,
|
|
940
|
+
estimatedGzipBytes: gzipSync(bytes, { level: config.compression.gzip.level }).byteLength
|
|
941
|
+
};
|
|
942
|
+
}
|
|
943
|
+
function assertUniqueTypeIds(components) {
|
|
944
|
+
const seen = /* @__PURE__ */ new Map();
|
|
945
|
+
for (const component of components) {
|
|
946
|
+
const previous = seen.get(component.id);
|
|
947
|
+
if (previous) throw new Error(`Duplicate Page Designer typeId "${component.id}" found in "${previous}" and "${component.filePath}"`);
|
|
948
|
+
seen.set(component.id, component.filePath);
|
|
949
|
+
}
|
|
950
|
+
}
|
|
951
|
+
function buildPageDesignerPreloadManifest(components, viteManifest, bundle, projectRoot, config, warn) {
|
|
952
|
+
assertUniqueTypeIds(components);
|
|
953
|
+
const required = new Set(config.requiredTypeIds);
|
|
954
|
+
const componentFiles = {};
|
|
955
|
+
const resourceKinds = /* @__PURE__ */ new Map();
|
|
956
|
+
const addResource = (file, kind) => {
|
|
957
|
+
const existingKind = resourceKinds.get(file);
|
|
958
|
+
if (existingKind && existingKind !== kind) throw new Error(`Emitted resource "${file}" was classified as both ${existingKind} and ${kind}`);
|
|
959
|
+
resourceKinds.set(file, kind);
|
|
960
|
+
};
|
|
961
|
+
for (const component of [...components].sort((a, b) => a.id.localeCompare(b.id))) {
|
|
962
|
+
const source = normalizeSourceId(projectRoot, component.filePath);
|
|
963
|
+
const matches = correlateComponentRecords(source, viteManifest, bundle, projectRoot);
|
|
964
|
+
if (matches.length > 1) throw new Error(`Ambiguous Vite manifest correlation for Page Designer typeId "${component.id}" (${source}): ${matches.map(([key]) => key).join(", ")}`);
|
|
965
|
+
if (matches.length === 0) {
|
|
966
|
+
const message = `No Vite manifest record found for Page Designer typeId "${component.id}" (${source})`;
|
|
967
|
+
if (required.has(component.id)) throw new Error(`${message}; it is listed in preloadManifest.requiredTypeIds`);
|
|
968
|
+
warn(message);
|
|
969
|
+
continue;
|
|
970
|
+
}
|
|
971
|
+
const [, entryRecord] = matches[0];
|
|
972
|
+
if (!entryRecord.isDynamicEntry) {
|
|
973
|
+
componentFiles[component.id] = {};
|
|
974
|
+
continue;
|
|
975
|
+
}
|
|
976
|
+
const visited = /* @__PURE__ */ new Set();
|
|
977
|
+
const scripts = /* @__PURE__ */ new Map();
|
|
978
|
+
const styles = /* @__PURE__ */ new Set();
|
|
979
|
+
const visit = (record, isComponentEntry) => {
|
|
980
|
+
if (visited.has(record.file)) return;
|
|
981
|
+
visited.add(record.file);
|
|
982
|
+
scripts.set(record.file, isComponentEntry ? "entry" : "dependency");
|
|
983
|
+
for (const importedKey of record.imports ?? []) {
|
|
984
|
+
const imported = viteManifest[importedKey];
|
|
985
|
+
if (!imported) throw new Error(`Vite manifest record "${record.file}" imports missing record "${importedKey}"`);
|
|
986
|
+
visit(imported, false);
|
|
987
|
+
}
|
|
988
|
+
for (const css of record.css ?? []) styles.add(css);
|
|
989
|
+
};
|
|
990
|
+
visit(entryRecord, true);
|
|
991
|
+
const styleFiles = [...styles];
|
|
992
|
+
const entryFiles = [...scripts].filter(([, role]) => role === "entry").map(([file]) => file).sort();
|
|
993
|
+
const dependencyFiles = [...scripts].filter(([, role]) => role === "dependency").map(([file]) => file).sort();
|
|
994
|
+
for (const file of styleFiles) addResource(file, "style");
|
|
995
|
+
for (const file of [...entryFiles, ...dependencyFiles]) addResource(file, "module");
|
|
996
|
+
componentFiles[component.id] = {
|
|
997
|
+
...styleFiles.length > 0 ? { styles: styleFiles } : {},
|
|
998
|
+
entries: entryFiles,
|
|
999
|
+
...dependencyFiles.length > 0 ? { dependencies: dependencyFiles } : {}
|
|
1000
|
+
};
|
|
1001
|
+
}
|
|
1002
|
+
for (const typeId of required) if (!(typeId in componentFiles)) throw new Error(`Required Page Designer typeId "${typeId}" was not discovered by the static registry scan`);
|
|
1003
|
+
const resourceFiles = [...resourceKinds.keys()].sort();
|
|
1004
|
+
const resourceIndices = Object.fromEntries(resourceFiles.map((file, index) => [file, index]));
|
|
1005
|
+
const toIndices = (files) => files.map((file) => resourceIndices[file]);
|
|
1006
|
+
return {
|
|
1007
|
+
version: 1,
|
|
1008
|
+
compression: config.compression,
|
|
1009
|
+
resources: resourceFiles.map((file) => describeResource(file, resourceKinds.get(file), bundle, config)),
|
|
1010
|
+
components: Object.fromEntries(Object.entries(componentFiles).map(([typeId, files]) => [typeId, {
|
|
1011
|
+
...files.styles ? { styles: toIndices(files.styles) } : {},
|
|
1012
|
+
...files.entries ? { entries: toIndices(files.entries) } : {},
|
|
1013
|
+
...files.dependencies ? { dependencies: toIndices(files.dependencies) } : {}
|
|
1014
|
+
}]))
|
|
1015
|
+
};
|
|
1016
|
+
}
|
|
1017
|
+
function parseViteManifestAsset(bundle) {
|
|
1018
|
+
const candidates = Object.values(bundle).filter((output) => output.type === "asset" && /(^|\/)manifest\.json$/.test(output.fileName));
|
|
1019
|
+
if (candidates.length !== 1) throw new Error(`Expected exactly one standard Vite manifest asset, found ${candidates.length}`);
|
|
1020
|
+
let parsed;
|
|
1021
|
+
try {
|
|
1022
|
+
parsed = JSON.parse(String(candidates[0].source));
|
|
1023
|
+
} catch (error) {
|
|
1024
|
+
throw new Error(`Could not parse the standard Vite manifest: ${error.message}`);
|
|
1025
|
+
}
|
|
1026
|
+
assertViteManifestStructure(parsed);
|
|
1027
|
+
return parsed;
|
|
1028
|
+
}
|
|
1029
|
+
function validateEmbeddedPageDesignerPreloadManifest(value) {
|
|
1030
|
+
if (!value || typeof value !== "object" || value.version !== 1) throw new Error("Page Designer preload manifest is missing, malformed, or uses an unsupported version");
|
|
1031
|
+
const candidate = value;
|
|
1032
|
+
if (!candidate.compression || !Array.isArray(candidate.resources) || !candidate.components || typeof candidate.components !== "object") throw new Error("Page Designer preload manifest is incomplete");
|
|
1033
|
+
}
|
|
1034
|
+
|
|
875
1035
|
//#endregion
|
|
876
1036
|
//#region src/plugins/staticRegistry.ts
|
|
877
1037
|
const DEFAULT_COMPONENT_GROUP = "storefrontnext_base";
|
|
@@ -958,7 +1118,7 @@ async function scanComponents(project, projectRoot, componentPath, registryPath)
|
|
|
958
1118
|
for (const decorator of decorators) if (decorator.getName() === "Component") {
|
|
959
1119
|
const componentInfo = extractComponentInfo(decorator);
|
|
960
1120
|
if (componentInfo) {
|
|
961
|
-
let relativePath = relative(registryDir, filePath).replace(/\\/g, "/").replace(/\.(ts|tsx)$/, "");
|
|
1121
|
+
let relativePath = relative$1(registryDir, filePath).replace(/\\/g, "/").replace(/\.(ts|tsx)$/, "");
|
|
962
1122
|
if (!relativePath.startsWith(".")) relativePath = `./${relativePath}`;
|
|
963
1123
|
const hasLoaderExport = hasNamedExport(sourceFile, "loader");
|
|
964
1124
|
const hasClientLoaderExport = hasNamedExport(sourceFile, "clientLoader");
|
|
@@ -1000,6 +1160,14 @@ function generateRegistryCode(components, registryIdentifier = "registry") {
|
|
|
1000
1160
|
export function initializeRegistry(targetRegistry = ${registryIdentifier}): void {
|
|
1001
1161
|
// No components found with @Component decorators
|
|
1002
1162
|
}
|
|
1163
|
+
|
|
1164
|
+
/** Load selected component modules and register their concrete exports before SSR. */
|
|
1165
|
+
export async function loadAndRegisterRegistryComponents(
|
|
1166
|
+
typeIds: Iterable<string>,
|
|
1167
|
+
targetRegistry = ${registryIdentifier}
|
|
1168
|
+
): Promise<void> {
|
|
1169
|
+
await Promise.all([...new Set(typeIds)].map((id) => targetRegistry.loadAndRegister(id)));
|
|
1170
|
+
}
|
|
1003
1171
|
`;
|
|
1004
1172
|
const registrations = sorted.map(({ id, relativePath, hasLoader, hasClientLoader, hasFallback }) => {
|
|
1005
1173
|
if (hasLoader || hasClientLoader || hasFallback) {
|
|
@@ -1022,6 +1190,18 @@ export function initializeRegistry(targetRegistry = ${registryIdentifier}): void
|
|
|
1022
1190
|
export function initializeRegistry(targetRegistry = ${registryIdentifier}): void {
|
|
1023
1191
|
${registrations}
|
|
1024
1192
|
}
|
|
1193
|
+
|
|
1194
|
+
/**
|
|
1195
|
+
* Load selected component modules and register their concrete exports before SSR.
|
|
1196
|
+
* This keeps the component boundary out of the initial Suspense shell while
|
|
1197
|
+
* preserving nested data-loading Suspense boundaries and their fallbacks.
|
|
1198
|
+
*/
|
|
1199
|
+
export async function loadAndRegisterRegistryComponents(
|
|
1200
|
+
typeIds: Iterable<string>,
|
|
1201
|
+
targetRegistry = ${registryIdentifier}
|
|
1202
|
+
): Promise<void> {
|
|
1203
|
+
await Promise.all([...new Set(typeIds)].map((id) => targetRegistry.loadAndRegister(id)));
|
|
1204
|
+
}
|
|
1025
1205
|
`;
|
|
1026
1206
|
}
|
|
1027
1207
|
/**
|
|
@@ -1089,11 +1269,16 @@ export const registry = new ComponentRegistry();
|
|
|
1089
1269
|
* })
|
|
1090
1270
|
*/
|
|
1091
1271
|
const staticRegistryPlugin = (config = {}) => {
|
|
1092
|
-
const { componentPath = "src/components", registryPath = "src/lib/static-registry.ts", registryIdentifier = "registry", failOnError = true } = config;
|
|
1272
|
+
const { componentPath = "src/components", registryPath = "src/lib/static-registry.ts", registryIdentifier = "registry", failOnError = true, preloadManifest = false } = config;
|
|
1093
1273
|
let projectRoot;
|
|
1274
|
+
let isProductionBuild = false;
|
|
1275
|
+
let components = [];
|
|
1276
|
+
let embeddedManifest;
|
|
1277
|
+
let intermediateManifestPath;
|
|
1278
|
+
const normalizedPreloadConfig = preloadManifest ? normalizePageDesignerPreloadManifestConfig(preloadManifest) : void 0;
|
|
1094
1279
|
const runRegistryGeneration = async () => {
|
|
1095
1280
|
logger.debug("🚀 Starting static registry generation...");
|
|
1096
|
-
|
|
1281
|
+
components = await scanComponents(new Project({ compilerOptions: {
|
|
1097
1282
|
target: ts.ScriptTarget.Latest,
|
|
1098
1283
|
module: ts.ModuleKind.ESNext,
|
|
1099
1284
|
jsx: ts.JsxEmit.ReactJSX,
|
|
@@ -1113,9 +1298,25 @@ const staticRegistryPlugin = (config = {}) => {
|
|
|
1113
1298
|
};
|
|
1114
1299
|
return {
|
|
1115
1300
|
name: "storefrontnext:static-registry",
|
|
1301
|
+
config(_userConfig, env) {
|
|
1302
|
+
isProductionBuild = env.command === "build" && env.mode === "production";
|
|
1303
|
+
},
|
|
1304
|
+
configEnvironment(name) {
|
|
1305
|
+
if (normalizedPreloadConfig && name === "client") return { build: { manifest: true } };
|
|
1306
|
+
},
|
|
1116
1307
|
configResolved(resolvedConfig) {
|
|
1117
1308
|
projectRoot = resolvedConfig.root;
|
|
1118
1309
|
},
|
|
1310
|
+
resolveId(id) {
|
|
1311
|
+
if (normalizedPreloadConfig && id === PAGE_DESIGNER_PRELOAD_MANIFEST_ID) return RESOLVED_PAGE_DESIGNER_PRELOAD_MANIFEST_ID;
|
|
1312
|
+
},
|
|
1313
|
+
load(id) {
|
|
1314
|
+
if (!normalizedPreloadConfig || id !== RESOLVED_PAGE_DESIGNER_PRELOAD_MANIFEST_ID) return;
|
|
1315
|
+
if (!isProductionBuild) return `export default ${JSON.stringify(createEmptyPageDesignerPreloadManifest(normalizedPreloadConfig))};`;
|
|
1316
|
+
if (this.environment?.name === "client") return `export default ${JSON.stringify(createEmptyPageDesignerPreloadManifest(normalizedPreloadConfig))};`;
|
|
1317
|
+
validateEmbeddedPageDesignerPreloadManifest(embeddedManifest);
|
|
1318
|
+
return `export default ${JSON.stringify(embeddedManifest)};`;
|
|
1319
|
+
},
|
|
1119
1320
|
async buildStart() {
|
|
1120
1321
|
try {
|
|
1121
1322
|
await runRegistryGeneration();
|
|
@@ -1125,6 +1326,23 @@ const staticRegistryPlugin = (config = {}) => {
|
|
|
1125
1326
|
logger.warn("⚠️ Continuing build without static registry...");
|
|
1126
1327
|
}
|
|
1127
1328
|
},
|
|
1329
|
+
writeBundle(options, bundle) {
|
|
1330
|
+
if (!normalizedPreloadConfig) return;
|
|
1331
|
+
if (this.environment?.name !== "client") return;
|
|
1332
|
+
const viteManifest = parseViteManifestAsset(bundle);
|
|
1333
|
+
embeddedManifest = buildPageDesignerPreloadManifest(components, viteManifest, bundle, projectRoot, normalizedPreloadConfig, (message) => this.warn(message));
|
|
1334
|
+
validateEmbeddedPageDesignerPreloadManifest(embeddedManifest);
|
|
1335
|
+
intermediateManifestPath = resolve$1(options.dir ?? resolve$1(projectRoot, "dist"), normalizedPreloadConfig.path);
|
|
1336
|
+
mkdirSync(dirname(intermediateManifestPath), { recursive: true });
|
|
1337
|
+
writeFileSync(intermediateManifestPath, `${JSON.stringify(embeddedManifest, null, 2)}\n`, "utf8");
|
|
1338
|
+
},
|
|
1339
|
+
buildApp: normalizedPreloadConfig ? {
|
|
1340
|
+
order: "post",
|
|
1341
|
+
handler() {
|
|
1342
|
+
if (intermediateManifestPath && existsSync(intermediateManifestPath)) unlinkSync(intermediateManifestPath);
|
|
1343
|
+
return Promise.resolve();
|
|
1344
|
+
}
|
|
1345
|
+
} : void 0,
|
|
1128
1346
|
async handleHotUpdate({ file, server }) {
|
|
1129
1347
|
const normalizedComponentPath = componentPath.replace(/\\/g, "/");
|
|
1130
1348
|
const normalizedFile = file.replace(/\\/g, "/");
|
|
@@ -1546,10 +1764,10 @@ function platformEntryPlugin() {
|
|
|
1546
1764
|
const appDir = appDirectory;
|
|
1547
1765
|
const watcher = server.watcher;
|
|
1548
1766
|
const checkEntryChange = (filePath) => {
|
|
1549
|
-
const relative$
|
|
1550
|
-
const basename$1 = path.basename(relative$
|
|
1551
|
-
if (path.dirname(relative$
|
|
1552
|
-
const ext = path.extname(relative$
|
|
1767
|
+
const relative$2 = path.relative(appDir, filePath);
|
|
1768
|
+
const basename$1 = path.basename(relative$2, path.extname(relative$2));
|
|
1769
|
+
if (path.dirname(relative$2) !== "." || basename$1 !== "entry.server" && basename$1 !== "entry.client") return;
|
|
1770
|
+
const ext = path.extname(relative$2);
|
|
1553
1771
|
if (!ENTRY_EXTENSIONS.includes(ext)) return;
|
|
1554
1772
|
const nowHasServer = findUserEntry(appDir, "entry.server") !== void 0;
|
|
1555
1773
|
const nowHasClient = findUserEntry(appDir, "entry.client") !== void 0;
|