@ecopages/core 0.2.0-alpha.17 → 0.2.0-alpha.18
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/CHANGELOG.md
CHANGED
|
@@ -24,6 +24,7 @@ All notable changes to `@ecopages/core` are documented here.
|
|
|
24
24
|
|
|
25
25
|
- Fixed mixed-integration page, layout, document, and component rendering to resolve foreign boundaries inside their owning renderer across the built-in integrations.
|
|
26
26
|
- Fixed host/runtime module loading, published build-helper exports, asset output normalization, explicit render flows, and static or preview build stability across Bun, Node, Vite, and Nitro.
|
|
27
|
+
- Fixed Node bootstrap runtime package linking to refresh dangling `.eco/node_modules` symlinks instead of failing with `EEXIST` during page transpilation.
|
|
27
28
|
- Fixed request-time and static-generation page inspection to preserve integration-specific page loading without reusing the normal render module identity.
|
|
28
29
|
- Fixed Node preview and static-generation React runtime resolution so app-owned page modules and server rendering share one React module identity.
|
|
29
30
|
- Fixed Bun browser output normalization so batched multi-entrypoint HMR rebuilds match emitted files to their expected served paths instead of Bun output order.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ecopages/core",
|
|
3
|
-
"version": "0.2.0-alpha.
|
|
3
|
+
"version": "0.2.0-alpha.18",
|
|
4
4
|
"description": "Core package for Ecopages",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ecopages",
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"directory": "packages/core"
|
|
18
18
|
},
|
|
19
19
|
"dependencies": {
|
|
20
|
-
"@ecopages/file-system": "0.2.0-alpha.
|
|
20
|
+
"@ecopages/file-system": "0.2.0-alpha.18",
|
|
21
21
|
"@ecopages/logger": "^0.2.3",
|
|
22
22
|
"@ecopages/scripts-injector": "^0.1.3",
|
|
23
23
|
"@worker-tools/html-rewriter": "0.1.0-pre.19",
|
|
@@ -16,7 +16,6 @@ export interface NodeBootstrapResolutionOptions {
|
|
|
16
16
|
* package roots so transpiled Node imports share one package graph.
|
|
17
17
|
*/
|
|
18
18
|
runtimeNodeModulesDir: string;
|
|
19
|
-
preserveImportMetaPaths?: string[];
|
|
20
19
|
}
|
|
21
20
|
/**
|
|
22
21
|
* Builds the user-facing error for Bun-native imports that cannot run on the
|
|
@@ -40,6 +39,4 @@ export declare function createNodeBootstrapPlugin(options: NodeBootstrapResoluti
|
|
|
40
39
|
* directory so transpiled server modules can externalize packages into one
|
|
41
40
|
* stable runtime node_modules graph.
|
|
42
41
|
*/
|
|
43
|
-
export declare function createAppNodeBootstrapPlugin(appConfig: Pick<EcoPagesAppConfig, 'rootDir' | 'workDir' | 'absolutePaths'
|
|
44
|
-
preserveImportMetaPaths?: string[];
|
|
45
|
-
}): EcoBuildPlugin;
|
|
42
|
+
export declare function createAppNodeBootstrapPlugin(appConfig: Pick<EcoPagesAppConfig, 'rootDir' | 'workDir' | 'absolutePaths'>): EcoBuildPlugin;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
|
-
import { existsSync, mkdirSync, readFileSync, realpathSync, rmSync, symlinkSync } from "node:fs";
|
|
2
|
+
import { existsSync, lstatSync, mkdirSync, readFileSync, realpathSync, rmSync, symlinkSync } from "node:fs";
|
|
3
3
|
import { createRequire } from "node:module";
|
|
4
4
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
5
5
|
import { resolveInternalExecutionDir } from "../../utils/resolve-work-dir.js";
|
|
@@ -27,18 +27,44 @@ function findPackageRoot(resolvedPath) {
|
|
|
27
27
|
currentPath = parentPath;
|
|
28
28
|
}
|
|
29
29
|
}
|
|
30
|
+
function pathEntryExists(filePath) {
|
|
31
|
+
try {
|
|
32
|
+
lstatSync(filePath);
|
|
33
|
+
return true;
|
|
34
|
+
} catch {
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
function linkPointsToPackage(linkPath, packageRoot) {
|
|
39
|
+
try {
|
|
40
|
+
return realpathSync(linkPath) === realpathSync(packageRoot);
|
|
41
|
+
} catch {
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
30
45
|
function ensureRuntimePackageLink(nodeModulesDir, specifier, resolvedPath) {
|
|
31
46
|
const packageName = getPackageNameFromSpecifier(specifier);
|
|
32
47
|
const packageRoot = findPackageRoot(resolvedPath);
|
|
33
48
|
const linkPath = path.join(nodeModulesDir, packageName);
|
|
34
|
-
|
|
35
|
-
|
|
49
|
+
mkdirSync(path.dirname(linkPath), { recursive: true });
|
|
50
|
+
if (pathEntryExists(linkPath)) {
|
|
51
|
+
if (linkPointsToPackage(linkPath, packageRoot)) {
|
|
36
52
|
return;
|
|
37
53
|
}
|
|
38
54
|
rmSync(linkPath, { recursive: true, force: true });
|
|
39
55
|
}
|
|
40
|
-
|
|
41
|
-
|
|
56
|
+
try {
|
|
57
|
+
symlinkSync(packageRoot, linkPath, "dir");
|
|
58
|
+
} catch (error) {
|
|
59
|
+
if (error.code !== "EEXIST") {
|
|
60
|
+
throw error;
|
|
61
|
+
}
|
|
62
|
+
if (linkPointsToPackage(linkPath, packageRoot)) {
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
rmSync(linkPath, { recursive: true, force: true });
|
|
66
|
+
symlinkSync(packageRoot, linkPath, "dir");
|
|
67
|
+
}
|
|
42
68
|
}
|
|
43
69
|
function getNodeUnsupportedBuiltinError(specifier, importer) {
|
|
44
70
|
return `Node bootstrap transpilation does not support Bun builtin specifier ${JSON.stringify(specifier)}${importer ? ` imported from ${importer}` : ""}.`;
|
|
@@ -86,26 +112,6 @@ function getBootstrapBuildLoaderForPath(filePath) {
|
|
|
86
112
|
return "js";
|
|
87
113
|
}
|
|
88
114
|
}
|
|
89
|
-
const REEXPORT_FROM_STATEMENT_PATTERN = /^\s*export\s+(?!type\b)(?:\*|\{[\s\S]*?\})\s+from\s+(['"][^'"]+['"])\s*;?\s*$/gm;
|
|
90
|
-
function injectBootstrapReexportImports(source) {
|
|
91
|
-
const sideEffectImports = [];
|
|
92
|
-
const importedSpecifiers = /* @__PURE__ */ new Set();
|
|
93
|
-
let importIndex = 0;
|
|
94
|
-
const rewrittenSource = source.replace(REEXPORT_FROM_STATEMENT_PATTERN, (statement, specifierLiteral) => {
|
|
95
|
-
if (!importedSpecifiers.has(specifierLiteral)) {
|
|
96
|
-
importedSpecifiers.add(specifierLiteral);
|
|
97
|
-
const importBinding = `__eco_bootstrap_reexport_${importIndex++}`;
|
|
98
|
-
sideEffectImports.push(`import * as ${importBinding} from ${specifierLiteral};`);
|
|
99
|
-
sideEffectImports.push(`void ${importBinding};`);
|
|
100
|
-
}
|
|
101
|
-
return statement;
|
|
102
|
-
});
|
|
103
|
-
if (sideEffectImports.length === 0) {
|
|
104
|
-
return source;
|
|
105
|
-
}
|
|
106
|
-
return `${sideEffectImports.join("\n")}
|
|
107
|
-
${rewrittenSource}`;
|
|
108
|
-
}
|
|
109
115
|
function shouldRewriteBootstrapSource(filePath, projectDir) {
|
|
110
116
|
const normalizedPath = path.resolve(filePath);
|
|
111
117
|
const normalizedProjectDir = path.resolve(projectDir);
|
|
@@ -154,9 +160,6 @@ function resolveNodeBootstrapDependency(args, options) {
|
|
|
154
160
|
}
|
|
155
161
|
function createNodeBootstrapPlugin(options) {
|
|
156
162
|
const projectDir = path.resolve(options.projectDir);
|
|
157
|
-
const importMetaRewritePaths = new Set(
|
|
158
|
-
(options.preserveImportMetaPaths ?? []).map((filePath) => path.resolve(filePath))
|
|
159
|
-
);
|
|
160
163
|
return {
|
|
161
164
|
name: "node-bootstrap-plugin",
|
|
162
165
|
setup(build) {
|
|
@@ -165,20 +168,12 @@ function createNodeBootstrapPlugin(options) {
|
|
|
165
168
|
});
|
|
166
169
|
build.onLoad({ filter: /\.[cm]?[jt]sx?$/ }, async (args) => {
|
|
167
170
|
const absolutePath = path.resolve(args.path);
|
|
168
|
-
const
|
|
169
|
-
|
|
170
|
-
const shouldRewriteReexports = isProjectSource;
|
|
171
|
-
if (!shouldPreserveImportMeta && !shouldRewriteReexports) {
|
|
171
|
+
const shouldRewriteImportMeta = shouldRewriteBootstrapSource(absolutePath, projectDir);
|
|
172
|
+
if (!shouldRewriteImportMeta) {
|
|
172
173
|
return void 0;
|
|
173
174
|
}
|
|
174
175
|
const originalContents = readFileSync(args.path, "utf8");
|
|
175
|
-
|
|
176
|
-
if (shouldPreserveImportMeta) {
|
|
177
|
-
contents = contents.replaceAll("import.meta.dirname", JSON.stringify(path.dirname(args.path))).replaceAll("import.meta.filename", JSON.stringify(args.path));
|
|
178
|
-
}
|
|
179
|
-
if (shouldRewriteReexports) {
|
|
180
|
-
contents = injectBootstrapReexportImports(contents);
|
|
181
|
-
}
|
|
176
|
+
const contents = originalContents.replaceAll("import.meta.dirname", JSON.stringify(path.dirname(args.path))).replaceAll("import.meta.filename", JSON.stringify(args.path));
|
|
182
177
|
if (contents === originalContents) {
|
|
183
178
|
return void 0;
|
|
184
179
|
}
|
|
@@ -194,11 +189,10 @@ function createNodeBootstrapPlugin(options) {
|
|
|
194
189
|
}
|
|
195
190
|
};
|
|
196
191
|
}
|
|
197
|
-
function createAppNodeBootstrapPlugin(appConfig
|
|
192
|
+
function createAppNodeBootstrapPlugin(appConfig) {
|
|
198
193
|
return createNodeBootstrapPlugin({
|
|
199
194
|
projectDir: appConfig.rootDir,
|
|
200
|
-
runtimeNodeModulesDir: getAppRuntimeNodeModulesDir(appConfig)
|
|
201
|
-
preserveImportMetaPaths: options?.preserveImportMetaPaths
|
|
195
|
+
runtimeNodeModulesDir: getAppRuntimeNodeModulesDir(appConfig)
|
|
202
196
|
});
|
|
203
197
|
}
|
|
204
198
|
export {
|