rwsdk 0.3.2 → 0.3.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/vite/runDirectivesScan.mjs +92 -28
- package/package.json +1 -1
|
@@ -5,7 +5,8 @@ import debug from "debug";
|
|
|
5
5
|
import { getViteEsbuild } from "./getViteEsbuild.mjs";
|
|
6
6
|
import { normalizeModulePath } from "../lib/normalizeModulePath.mjs";
|
|
7
7
|
import { externalModules } from "./constants.mjs";
|
|
8
|
-
import { createViteAwareResolver } from "./createViteAwareResolver.mjs";
|
|
8
|
+
import { createViteAwareResolver, mapViteResolveToEnhancedResolveOptions, } from "./createViteAwareResolver.mjs";
|
|
9
|
+
import resolve from "enhanced-resolve";
|
|
9
10
|
const log = debug("rwsdk:vite:run-directives-scan");
|
|
10
11
|
// Copied from Vite's source code.
|
|
11
12
|
// https://github.com/vitejs/vite/blob/main/packages/vite/src/shared/utils.ts
|
|
@@ -41,28 +42,23 @@ export const runDirectivesScan = async ({ rootConfig, environment, clientFiles,
|
|
|
41
42
|
const absoluteEntries = entries.map((entry) => path.resolve(rootConfig.root, entry));
|
|
42
43
|
log("Starting directives scan for environment '%s' with entries:", environment.name, absoluteEntries);
|
|
43
44
|
// Use enhanced-resolve with Vite plugin integration for full compatibility
|
|
44
|
-
const
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
}
|
|
62
|
-
resolve(null);
|
|
63
|
-
}
|
|
64
|
-
});
|
|
65
|
-
});
|
|
45
|
+
const workerResolver = createViteAwareResolver(rootConfig, environment.name, environment);
|
|
46
|
+
// Create a client resolver with browser conditions
|
|
47
|
+
// We'll use the mapViteResolveToEnhancedResolveOptions function directly
|
|
48
|
+
// to create a resolver with browser conditions
|
|
49
|
+
const clientResolveOptions = mapViteResolveToEnhancedResolveOptions(rootConfig, environment.name);
|
|
50
|
+
// Override the conditions to use browser conditions for client resolution
|
|
51
|
+
clientResolveOptions.conditionNames = ["browser", "module"];
|
|
52
|
+
const clientResolver = resolve.create(clientResolveOptions);
|
|
53
|
+
const moduleEnvironments = new Map();
|
|
54
|
+
const fileContentCache = new Map();
|
|
55
|
+
const readFileWithCache = async (path) => {
|
|
56
|
+
if (fileContentCache.has(path)) {
|
|
57
|
+
return fileContentCache.get(path);
|
|
58
|
+
}
|
|
59
|
+
const contents = await fsp.readFile(path, "utf-8");
|
|
60
|
+
fileContentCache.set(path, contents);
|
|
61
|
+
return contents;
|
|
66
62
|
};
|
|
67
63
|
const esbuildScanPlugin = {
|
|
68
64
|
name: "rwsdk:esbuild-scan-plugin",
|
|
@@ -92,14 +88,65 @@ export const runDirectivesScan = async ({ rootConfig, environment, clientFiles,
|
|
|
92
88
|
return { external: true };
|
|
93
89
|
}
|
|
94
90
|
log("onResolve called for:", args.path, "from:", args.importer);
|
|
95
|
-
|
|
91
|
+
let importerEnv = moduleEnvironments.get(args.importer);
|
|
92
|
+
// If we don't know the importer's environment yet, check its content
|
|
93
|
+
if (!importerEnv &&
|
|
94
|
+
args.importer &&
|
|
95
|
+
/\.(m|c)?[jt]sx?$/.test(args.importer)) {
|
|
96
|
+
try {
|
|
97
|
+
const importerContents = await readFileWithCache(args.importer);
|
|
98
|
+
if (hasDirective(importerContents, "use client")) {
|
|
99
|
+
importerEnv = "client";
|
|
100
|
+
log("Pre-detected importer 'use client' in:", args.importer);
|
|
101
|
+
}
|
|
102
|
+
else if (hasDirective(importerContents, "use server")) {
|
|
103
|
+
importerEnv = "worker";
|
|
104
|
+
log("Pre-detected importer 'use server' in:", args.importer);
|
|
105
|
+
}
|
|
106
|
+
else {
|
|
107
|
+
importerEnv = "worker"; // Default for entry points
|
|
108
|
+
}
|
|
109
|
+
moduleEnvironments.set(args.importer, importerEnv);
|
|
110
|
+
}
|
|
111
|
+
catch (e) {
|
|
112
|
+
importerEnv = "worker"; // Default fallback
|
|
113
|
+
log("Could not pre-read importer, using worker environment:", args.importer);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
else if (!importerEnv) {
|
|
117
|
+
importerEnv = "worker"; // Default for entry points or non-script files
|
|
118
|
+
}
|
|
119
|
+
log("Importer:", args.importer, "environment:", importerEnv);
|
|
120
|
+
const resolver = importerEnv === "client" ? clientResolver : workerResolver;
|
|
121
|
+
const resolved = await new Promise((resolve) => {
|
|
122
|
+
resolver({}, args.importer || rootConfig.root, args.path, {}, (err, result) => {
|
|
123
|
+
if (!err && result) {
|
|
124
|
+
resolve({ id: result });
|
|
125
|
+
}
|
|
126
|
+
else {
|
|
127
|
+
if (err) {
|
|
128
|
+
const errorMessage = err.message || String(err);
|
|
129
|
+
if (errorMessage.includes("Package path . is not exported")) {
|
|
130
|
+
log("Package exports error for %s, marking as external", args.path);
|
|
131
|
+
}
|
|
132
|
+
else {
|
|
133
|
+
log("Resolution failed for %s: %s", args.path, errorMessage);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
resolve(null);
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
});
|
|
96
140
|
log("Resolution result:", resolved);
|
|
97
141
|
const resolvedPath = resolved?.id;
|
|
98
142
|
if (resolvedPath && path.isAbsolute(resolvedPath)) {
|
|
99
143
|
// Normalize the path for esbuild compatibility
|
|
100
144
|
const normalizedPath = normalizeModulePath(resolvedPath, rootConfig.root, { absolute: true });
|
|
101
145
|
log("Normalized path:", normalizedPath);
|
|
102
|
-
return {
|
|
146
|
+
return {
|
|
147
|
+
path: normalizedPath,
|
|
148
|
+
pluginData: { inheritedEnv: importerEnv },
|
|
149
|
+
};
|
|
103
150
|
}
|
|
104
151
|
log("Marking as external:", args.path, "resolved to:", resolvedPath);
|
|
105
152
|
return { external: true };
|
|
@@ -117,12 +164,29 @@ export const runDirectivesScan = async ({ rootConfig, environment, clientFiles,
|
|
|
117
164
|
return null;
|
|
118
165
|
}
|
|
119
166
|
try {
|
|
120
|
-
const contents = await
|
|
121
|
-
|
|
167
|
+
const contents = await readFileWithCache(args.path);
|
|
168
|
+
const inheritedEnv = args.pluginData?.inheritedEnv || "worker";
|
|
169
|
+
let currentEnv = inheritedEnv;
|
|
170
|
+
const isClient = hasDirective(contents, "use client");
|
|
171
|
+
const isServer = hasDirective(contents, "use server");
|
|
172
|
+
// A file's own directive takes precedence over the inherited environment.
|
|
173
|
+
if (isClient) {
|
|
174
|
+
currentEnv = "client";
|
|
175
|
+
}
|
|
176
|
+
else if (isServer) {
|
|
177
|
+
// `else if` handles cases where a file might have both directives.
|
|
178
|
+
// "use client" takes precedence.
|
|
179
|
+
currentEnv = "worker";
|
|
180
|
+
}
|
|
181
|
+
// Store the definitive environment for this module, so it can be used when it becomes an importer.
|
|
182
|
+
moduleEnvironments.set(args.path, currentEnv);
|
|
183
|
+
log("Set environment for", args.path, "to", currentEnv);
|
|
184
|
+
// Finally, populate the output sets if the file has a directive.
|
|
185
|
+
if (isClient) {
|
|
122
186
|
log("Discovered 'use client' in:", args.path);
|
|
123
187
|
clientFiles.add(normalizeModulePath(args.path, rootConfig.root));
|
|
124
188
|
}
|
|
125
|
-
if (
|
|
189
|
+
if (isServer) {
|
|
126
190
|
log("Discovered 'use server' in:", args.path);
|
|
127
191
|
serverFiles.add(normalizeModulePath(args.path, rootConfig.root));
|
|
128
192
|
}
|