rwsdk 0.3.1 → 0.3.3
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.
|
@@ -50,15 +50,64 @@ class VitePluginResolverPlugin {
|
|
|
50
50
|
if (!resolveIdHandler)
|
|
51
51
|
continue;
|
|
52
52
|
let handlerFn;
|
|
53
|
+
let shouldApplyFilter = false;
|
|
54
|
+
let filter = null;
|
|
53
55
|
if (typeof resolveIdHandler === "function") {
|
|
54
56
|
handlerFn = resolveIdHandler;
|
|
55
57
|
}
|
|
56
58
|
else if (typeof resolveIdHandler === "object" &&
|
|
57
59
|
typeof resolveIdHandler.handler === "function") {
|
|
58
60
|
handlerFn = resolveIdHandler.handler;
|
|
61
|
+
shouldApplyFilter = true;
|
|
62
|
+
filter = resolveIdHandler.filter;
|
|
59
63
|
}
|
|
60
64
|
if (!handlerFn)
|
|
61
65
|
continue;
|
|
66
|
+
if (shouldApplyFilter && filter?.id) {
|
|
67
|
+
const idFilter = filter.id;
|
|
68
|
+
let shouldSkip = false;
|
|
69
|
+
if (idFilter instanceof RegExp) {
|
|
70
|
+
shouldSkip = !idFilter.test(currentRequest.request);
|
|
71
|
+
}
|
|
72
|
+
else if (Array.isArray(idFilter)) {
|
|
73
|
+
// Handle array of filters - matches if ANY filter matches
|
|
74
|
+
shouldSkip = !idFilter.some((f) => f instanceof RegExp
|
|
75
|
+
? f.test(currentRequest.request)
|
|
76
|
+
: f === currentRequest.request);
|
|
77
|
+
}
|
|
78
|
+
else if (typeof idFilter === "string") {
|
|
79
|
+
shouldSkip = idFilter !== currentRequest.request;
|
|
80
|
+
}
|
|
81
|
+
else if (typeof idFilter === "object" && idFilter !== null) {
|
|
82
|
+
// Handle include/exclude object pattern
|
|
83
|
+
const { include, exclude } = idFilter;
|
|
84
|
+
let matches = true;
|
|
85
|
+
// Check include patterns (if any)
|
|
86
|
+
if (include) {
|
|
87
|
+
const includePatterns = Array.isArray(include)
|
|
88
|
+
? include
|
|
89
|
+
: [include];
|
|
90
|
+
matches = includePatterns.some((pattern) => pattern instanceof RegExp
|
|
91
|
+
? pattern.test(currentRequest.request)
|
|
92
|
+
: pattern === currentRequest.request);
|
|
93
|
+
}
|
|
94
|
+
// Check exclude patterns (if any) - exclude overrides include
|
|
95
|
+
if (matches && exclude) {
|
|
96
|
+
const excludePatterns = Array.isArray(exclude)
|
|
97
|
+
? exclude
|
|
98
|
+
: [exclude];
|
|
99
|
+
const isExcluded = excludePatterns.some((pattern) => pattern instanceof RegExp
|
|
100
|
+
? pattern.test(currentRequest.request)
|
|
101
|
+
: pattern === currentRequest.request);
|
|
102
|
+
matches = !isExcluded;
|
|
103
|
+
}
|
|
104
|
+
shouldSkip = !matches;
|
|
105
|
+
}
|
|
106
|
+
if (shouldSkip) {
|
|
107
|
+
debug("Skipping plugin '%s' due to filter mismatch for '%s'", plugin.name, currentRequest.request);
|
|
108
|
+
continue;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
62
111
|
try {
|
|
63
112
|
debug("Calling plugin '%s' for '%s'", plugin.name, currentRequest.request);
|
|
64
113
|
const result = await handlerFn.call(pluginContext, currentRequest.request, currentRequest.path, { scan: true });
|
|
@@ -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,20 +88,73 @@ 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 };
|
|
106
153
|
});
|
|
107
154
|
build.onLoad({ filter: /\.(m|c)?[jt]sx?$/ }, async (args) => {
|
|
108
155
|
log("onLoad called for:", args.path);
|
|
156
|
+
const inheritedEnv = args.pluginData?.inheritedEnv || "worker";
|
|
157
|
+
log("Inherited environment for", args.path, "is", inheritedEnv);
|
|
109
158
|
if (!args.path.startsWith("/") ||
|
|
110
159
|
args.path.includes("virtual:") ||
|
|
111
160
|
isExternalUrl(args.path)) {
|
|
@@ -117,7 +166,8 @@ export const runDirectivesScan = async ({ rootConfig, environment, clientFiles,
|
|
|
117
166
|
return null;
|
|
118
167
|
}
|
|
119
168
|
try {
|
|
120
|
-
const contents = await
|
|
169
|
+
const contents = await readFileWithCache(args.path);
|
|
170
|
+
// The environment is determined in onResolve. Here we just populate the output sets.
|
|
121
171
|
if (hasDirective(contents, "use client")) {
|
|
122
172
|
log("Discovered 'use client' in:", args.path);
|
|
123
173
|
clientFiles.add(normalizeModulePath(args.path, rootConfig.root));
|