extension-develop 3.15.1 → 3.16.0
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/0~branding.mjs +26 -0
- package/dist/0~dev-server.mjs +488 -0
- package/dist/0~rslib-runtime.mjs +40 -0
- package/dist/0~rspack-config.mjs +8648 -0
- package/dist/0~stats-handler.mjs +25 -0
- package/dist/0~zip.mjs +34 -0
- package/dist/314.mjs +35 -0
- package/dist/526.mjs +23 -0
- package/dist/946.mjs +1670 -0
- package/dist/962.mjs +1389 -0
- package/dist/ensure-hmr-for-scripts.js +12 -56
- package/dist/{ensure-hmr-for-scripts.cjs → ensure-hmr-for-scripts.mjs} +12 -56
- package/dist/feature-scripts-content-script-wrapper.js +23 -98
- package/dist/{feature-scripts-content-script-wrapper.cjs → feature-scripts-content-script-wrapper.mjs} +23 -98
- package/dist/main-world-bridge.js +0 -18
- package/dist/{main-world-bridge.cjs → main-world-bridge.mjs} +0 -18
- package/dist/minimum-chromium-file.js +0 -5
- package/dist/minimum-chromium-file.mjs +5 -0
- package/dist/minimum-firefox-file.js +0 -5
- package/dist/minimum-firefox-file.mjs +5 -0
- package/dist/minimum-script-file.js +0 -18
- package/dist/{minimum-script-file.cjs → minimum-script-file.mjs} +0 -18
- package/dist/module.mjs +3 -0
- package/dist/package.json +1 -1
- package/dist/preact-refresh-shim.mjs +7 -0
- package/dist/preview.mjs +2 -0
- package/dist/resolve-paths-loader.js +1043 -1093
- package/dist/resolve-paths-loader.mjs +1300 -0
- package/package.json +8 -8
- package/dist/221.cjs +0 -513
- package/dist/442.cjs +0 -9226
- package/dist/504.cjs +0 -65
- package/dist/787.cjs +0 -44
- package/dist/minimum-chromium-file.cjs +0 -10
- package/dist/minimum-firefox-file.cjs +0 -10
- package/dist/module.cjs +0 -3479
- package/dist/preact-refresh-shim.cjs +0 -25
- package/dist/preview.cjs +0 -1464
- package/dist/resolve-paths-loader.cjs +0 -1350
package/dist/962.mjs
ADDED
|
@@ -0,0 +1,1389 @@
|
|
|
1
|
+
import { createRequire as __extjsCreateRequire } from "node:module"; const require = __extjsCreateRequire(import.meta.url);
|
|
2
|
+
import { createRequire } from "module";
|
|
3
|
+
import { execFileSync, spawn, spawnSync as external_child_process_spawnSync } from "child_process";
|
|
4
|
+
import { EventEmitter } from "node:events";
|
|
5
|
+
import pintor from "pintor";
|
|
6
|
+
import { package_namespaceObject, buildSuccessWithWarnings, buildWarningsDetails, loadCommandConfig, needsInstall, getDirs, buildCommandFailed, sanitize, writingTypeDefinitions, buildWebpack, assertNoManagedDependencyConflicts, debugDirs, debugBrowser, normalizeBrowser, debugOutputPath, loadCustomConfig, buildSuccess, writingTypeDefinitionsError, getDistPath, getProjectStructure, loadBrowserConfig, authorInstallNotice, resolveCompanionExtensionsConfig, getSpecialFoldersDataForProjectRoot } from "./946.mjs";
|
|
7
|
+
import { getCanonicalContentScriptEntryName } from "./526.mjs";
|
|
8
|
+
import { fileURLToPath as __rspack_fileURLToPath } from "node:url";
|
|
9
|
+
import { dirname as __rspack_dirname } from "node:path";
|
|
10
|
+
import * as __rspack_external_fs from "fs";
|
|
11
|
+
import * as __rspack_external_path from "path";
|
|
12
|
+
import * as __rspack_external_fs_promises_400951f8 from "fs/promises";
|
|
13
|
+
function getBuildSummary(browser, info) {
|
|
14
|
+
const assets = info?.assets || [];
|
|
15
|
+
return {
|
|
16
|
+
browser,
|
|
17
|
+
total_assets: assets.length,
|
|
18
|
+
total_bytes: assets.reduce((n, a)=>n + (a.size || 0), 0),
|
|
19
|
+
largest_asset_bytes: assets.reduce((m, a)=>Math.max(m, a.size || 0), 0),
|
|
20
|
+
warnings_count: (info?.warnings || []).length,
|
|
21
|
+
errors_count: (info?.errors || []).length
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
function parseJsonSafe(text) {
|
|
25
|
+
const raw = 'string' == typeof text ? text : String(text || '');
|
|
26
|
+
const s = raw && 0xfeff === raw.charCodeAt(0) ? raw.slice(1) : raw;
|
|
27
|
+
return JSON.parse(s || '{}');
|
|
28
|
+
}
|
|
29
|
+
var develop_context_dirname = __rspack_dirname(__rspack_fileURLToPath(import.meta.url));
|
|
30
|
+
const cjsRequire = createRequire(import.meta.url);
|
|
31
|
+
if (!process.env.EXTENSION_JS_OPTIONAL_DEPS_VERSION) process.env.EXTENSION_JS_OPTIONAL_DEPS_VERSION = package_namespaceObject.rE;
|
|
32
|
+
function resolveDevelopRootFromDir(dir) {
|
|
33
|
+
try {
|
|
34
|
+
const packageJsonPath = __rspack_external_path.join(dir, 'package.json');
|
|
35
|
+
if (!__rspack_external_fs.existsSync(packageJsonPath)) return;
|
|
36
|
+
const pkg = parseJsonSafe(__rspack_external_fs.readFileSync(packageJsonPath, 'utf8'));
|
|
37
|
+
if (pkg?.name === 'extension-develop') return dir;
|
|
38
|
+
} catch {}
|
|
39
|
+
}
|
|
40
|
+
function findDevelopRootFrom(startDir) {
|
|
41
|
+
let currentDir = startDir;
|
|
42
|
+
const maxDepth = 6;
|
|
43
|
+
for(let i = 0; i < maxDepth; i++){
|
|
44
|
+
const root = resolveDevelopRootFromDir(currentDir);
|
|
45
|
+
if (root) return root;
|
|
46
|
+
const parent = __rspack_external_path.dirname(currentDir);
|
|
47
|
+
if (parent === currentDir) break;
|
|
48
|
+
currentDir = parent;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
function findExtensionDevelopRoot() {
|
|
52
|
+
const libDir = develop_context_dirname;
|
|
53
|
+
const buildDir = __rspack_external_path.resolve(libDir, '..');
|
|
54
|
+
const packageRoot = __rspack_external_path.resolve(buildDir, '..');
|
|
55
|
+
const packageJsonPath = __rspack_external_path.join(packageRoot, 'package.json');
|
|
56
|
+
if (__rspack_external_fs.existsSync(packageJsonPath)) try {
|
|
57
|
+
const pkg = JSON.parse(__rspack_external_fs.readFileSync(packageJsonPath, 'utf-8'));
|
|
58
|
+
if ('extension-develop' === pkg.name) return packageRoot;
|
|
59
|
+
} catch {}
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
function resolveDevelopInstallRoot() {
|
|
63
|
+
const envRoot = process.env.EXTENSION_DEVELOP_ROOT;
|
|
64
|
+
if (envRoot) {
|
|
65
|
+
const resolvedEnvRoot = resolveDevelopRootFromDir(__rspack_external_path.resolve(envRoot));
|
|
66
|
+
if (resolvedEnvRoot) return resolvedEnvRoot;
|
|
67
|
+
}
|
|
68
|
+
const directRoot = findExtensionDevelopRoot();
|
|
69
|
+
if (directRoot) return directRoot;
|
|
70
|
+
try {
|
|
71
|
+
const candidateRoot = findDevelopRootFrom(develop_context_dirname);
|
|
72
|
+
if (candidateRoot) return candidateRoot;
|
|
73
|
+
} catch {}
|
|
74
|
+
try {
|
|
75
|
+
const pkgPath = cjsRequire.resolve('extension-develop/package.json', {
|
|
76
|
+
paths: [
|
|
77
|
+
develop_context_dirname
|
|
78
|
+
]
|
|
79
|
+
});
|
|
80
|
+
return resolveDevelopRootFromDir(__rspack_external_path.dirname(pkgPath));
|
|
81
|
+
} catch {
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
function resolveDevelopDistFile(stem) {
|
|
86
|
+
const installRoot = resolveDevelopInstallRoot();
|
|
87
|
+
const distRoot = installRoot ? __rspack_external_path.join(installRoot, 'dist') : __rspack_external_path.resolve(develop_context_dirname, '..');
|
|
88
|
+
const base = __rspack_external_path.join(distRoot, stem);
|
|
89
|
+
const candidates = [
|
|
90
|
+
`${base}.js`,
|
|
91
|
+
`${base}.cjs`,
|
|
92
|
+
`${base}.mjs`,
|
|
93
|
+
base
|
|
94
|
+
];
|
|
95
|
+
for (const candidate of candidates)if (__rspack_external_fs.existsSync(candidate)) {
|
|
96
|
+
if ('1' === process.env.EXTENSION_DEBUG_DEVELOP_ROOT) console.log(`[extjs:develop-root] ${stem} -> ${candidate} (installRoot=${installRoot || '<none>'})`);
|
|
97
|
+
return candidate;
|
|
98
|
+
}
|
|
99
|
+
if ('1' === process.env.EXTENSION_DEBUG_DEVELOP_ROOT) console.log(`[extjs:develop-root] ${stem} -> ${base} (fallback, installRoot=${installRoot || '<none>'})`);
|
|
100
|
+
return base;
|
|
101
|
+
}
|
|
102
|
+
var package_manager_dirname = __rspack_dirname(__rspack_fileURLToPath(import.meta.url));
|
|
103
|
+
const package_manager_require = createRequire(import.meta.url);
|
|
104
|
+
function normalizePackageManager(value) {
|
|
105
|
+
if (!value) return;
|
|
106
|
+
const lower = value.toLowerCase().trim();
|
|
107
|
+
if ('pnpm' === lower) return 'pnpm';
|
|
108
|
+
if ('yarn' === lower) return 'yarn';
|
|
109
|
+
if ('bun' === lower) return 'bun';
|
|
110
|
+
if ('npm' === lower) return 'npm';
|
|
111
|
+
}
|
|
112
|
+
function inferPackageManagerFromPath(value) {
|
|
113
|
+
if (!value) return;
|
|
114
|
+
const lower = value.toLowerCase();
|
|
115
|
+
if (lower.includes('pnpm')) return 'pnpm';
|
|
116
|
+
if (lower.includes('yarn')) return 'yarn';
|
|
117
|
+
if (lower.includes('bun')) return 'bun';
|
|
118
|
+
if (lower.includes('npm')) return 'npm';
|
|
119
|
+
}
|
|
120
|
+
function getPackageManagerOverride() {
|
|
121
|
+
const name = normalizePackageManager(process.env.EXTENSION_JS_PACKAGE_MANAGER);
|
|
122
|
+
const execPath = process.env.EXTENSION_JS_PM_EXEC_PATH || process.env.npm_execpath || process.env.NPM_EXEC_PATH;
|
|
123
|
+
if (!name && !execPath) return;
|
|
124
|
+
const inferredName = name || inferPackageManagerFromPath(execPath) || 'npm';
|
|
125
|
+
return {
|
|
126
|
+
name: inferredName,
|
|
127
|
+
execPath
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
function detectPackageManagerFromEnv() {
|
|
131
|
+
const userAgent = process.env.npm_config_user_agent || '';
|
|
132
|
+
const execPath = process.env.npm_execpath || process.env.NPM_EXEC_PATH || '';
|
|
133
|
+
if (userAgent.includes('pnpm')) return {
|
|
134
|
+
name: 'pnpm',
|
|
135
|
+
execPath: execPath || void 0
|
|
136
|
+
};
|
|
137
|
+
if (userAgent.includes('yarn')) return {
|
|
138
|
+
name: 'yarn',
|
|
139
|
+
execPath: execPath || void 0
|
|
140
|
+
};
|
|
141
|
+
if (userAgent.includes('bun')) return {
|
|
142
|
+
name: 'bun',
|
|
143
|
+
execPath: execPath || void 0
|
|
144
|
+
};
|
|
145
|
+
if (userAgent.includes('npm')) return {
|
|
146
|
+
name: 'npm',
|
|
147
|
+
execPath: execPath || void 0
|
|
148
|
+
};
|
|
149
|
+
if (execPath) {
|
|
150
|
+
const inferred = inferPackageManagerFromPath(execPath) || 'npm';
|
|
151
|
+
return {
|
|
152
|
+
name: inferred,
|
|
153
|
+
execPath
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
function resolveNpmCliFromNode(execPath) {
|
|
158
|
+
const execDir = __rspack_external_path.dirname(execPath);
|
|
159
|
+
const candidates = [
|
|
160
|
+
__rspack_external_path.join(execDir, 'node_modules', 'npm', 'bin', 'npm-cli.js'),
|
|
161
|
+
__rspack_external_path.join(execDir, '..', 'lib', 'node_modules', 'npm', 'bin', 'npm-cli.js'),
|
|
162
|
+
__rspack_external_path.join(execDir, '..', 'node_modules', 'npm', 'bin', 'npm-cli.js')
|
|
163
|
+
];
|
|
164
|
+
for (const candidate of candidates)if (__rspack_external_fs.existsSync(candidate)) return candidate;
|
|
165
|
+
}
|
|
166
|
+
function resolveBundledNpmCliPath() {
|
|
167
|
+
if (process.env.EXTENSION_JS_PM_EXEC_PATH) {
|
|
168
|
+
const overridePath = process.env.EXTENSION_JS_PM_EXEC_PATH;
|
|
169
|
+
if (overridePath && __rspack_external_fs.existsSync(overridePath)) return overridePath;
|
|
170
|
+
}
|
|
171
|
+
try {
|
|
172
|
+
const resolved = package_manager_require.resolve('npm/bin/npm-cli.js', {
|
|
173
|
+
paths: [
|
|
174
|
+
process.cwd(),
|
|
175
|
+
package_manager_dirname
|
|
176
|
+
]
|
|
177
|
+
});
|
|
178
|
+
if (resolved && __rspack_external_fs.existsSync(resolved)) return resolved;
|
|
179
|
+
} catch {}
|
|
180
|
+
return resolveNpmCliFromNode(process.execPath);
|
|
181
|
+
}
|
|
182
|
+
function isWindowsExecutablePath(value) {
|
|
183
|
+
if (!value || 'win32' !== process.platform) return false;
|
|
184
|
+
return /\.(cmd|bat|exe)$/i.test(value);
|
|
185
|
+
}
|
|
186
|
+
function isNodeScriptPath(value) {
|
|
187
|
+
if (!value) return false;
|
|
188
|
+
return /\.(mjs|cjs|js)$/i.test(value);
|
|
189
|
+
}
|
|
190
|
+
function resolveWindowsCommandPath(command) {
|
|
191
|
+
if ('win32' !== process.platform) return;
|
|
192
|
+
try {
|
|
193
|
+
const systemRoot = process.env.SystemRoot || 'C:\\Windows';
|
|
194
|
+
const whereExe = __rspack_external_path.join(systemRoot, 'System32', 'where.exe');
|
|
195
|
+
const whereCommand = __rspack_external_fs.existsSync(whereExe) ? whereExe : 'where';
|
|
196
|
+
const output = execFileSync(whereCommand, [
|
|
197
|
+
command
|
|
198
|
+
], {
|
|
199
|
+
encoding: 'utf8',
|
|
200
|
+
stdio: [
|
|
201
|
+
'ignore',
|
|
202
|
+
'pipe',
|
|
203
|
+
'ignore'
|
|
204
|
+
],
|
|
205
|
+
windowsHide: true
|
|
206
|
+
});
|
|
207
|
+
const candidates = String(output).split(/\r?\n/).map((line)=>line.trim()).filter(Boolean);
|
|
208
|
+
const cmdMatch = candidates.find((line)=>/\.cmd$/i.test(line));
|
|
209
|
+
return cmdMatch || candidates[0];
|
|
210
|
+
} catch {
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
function resolveUnixCommandPath(command) {
|
|
215
|
+
if ('win32' === process.platform) return;
|
|
216
|
+
try {
|
|
217
|
+
const output = execFileSync('which', [
|
|
218
|
+
command
|
|
219
|
+
], {
|
|
220
|
+
encoding: 'utf8',
|
|
221
|
+
stdio: [
|
|
222
|
+
'ignore',
|
|
223
|
+
'pipe',
|
|
224
|
+
'ignore'
|
|
225
|
+
]
|
|
226
|
+
});
|
|
227
|
+
const candidate = String(output).trim();
|
|
228
|
+
return candidate || void 0;
|
|
229
|
+
} catch {
|
|
230
|
+
return;
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
function resolveCommandOnPath(command) {
|
|
234
|
+
return resolveWindowsCommandPath(command) || resolveUnixCommandPath(command) || void 0;
|
|
235
|
+
}
|
|
236
|
+
function canRunCorepack() {
|
|
237
|
+
try {
|
|
238
|
+
const spawnSync = external_child_process_spawnSync;
|
|
239
|
+
const result = spawnSync('corepack', [
|
|
240
|
+
'--version'
|
|
241
|
+
], {
|
|
242
|
+
stdio: 'ignore',
|
|
243
|
+
windowsHide: true
|
|
244
|
+
});
|
|
245
|
+
return result?.status === 0;
|
|
246
|
+
} catch {
|
|
247
|
+
return false;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
function detectByLockfile(cwd) {
|
|
251
|
+
if (!cwd) return;
|
|
252
|
+
const hasPnpmLock = __rspack_external_fs.existsSync(__rspack_external_path.join(cwd, 'pnpm-lock.yaml'));
|
|
253
|
+
const hasYarnLock = __rspack_external_fs.existsSync(__rspack_external_path.join(cwd, 'yarn.lock'));
|
|
254
|
+
const hasNpmLock = __rspack_external_fs.existsSync(__rspack_external_path.join(cwd, 'package-lock.json'));
|
|
255
|
+
if (hasPnpmLock) return 'pnpm';
|
|
256
|
+
if (hasYarnLock) return 'yarn';
|
|
257
|
+
if (hasNpmLock) return 'npm';
|
|
258
|
+
}
|
|
259
|
+
function hydrateResolvedPackageManager(name) {
|
|
260
|
+
const resolvedCommand = resolveCommandOnPath(name);
|
|
261
|
+
if (resolvedCommand) return {
|
|
262
|
+
name,
|
|
263
|
+
execPath: resolvedCommand
|
|
264
|
+
};
|
|
265
|
+
if ('npm' === name) {
|
|
266
|
+
const bundledNpmCli = resolveBundledNpmCliPath();
|
|
267
|
+
if (bundledNpmCli) return {
|
|
268
|
+
name: 'npm',
|
|
269
|
+
execPath: bundledNpmCli,
|
|
270
|
+
runnerCommand: process.execPath,
|
|
271
|
+
runnerArgs: [
|
|
272
|
+
bundledNpmCli
|
|
273
|
+
]
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
function resolvePackageManager(opts) {
|
|
278
|
+
const lockPm = detectByLockfile(opts?.cwd);
|
|
279
|
+
if (lockPm) {
|
|
280
|
+
const hydrated = hydrateResolvedPackageManager(lockPm);
|
|
281
|
+
if (hydrated) return hydrated;
|
|
282
|
+
return {
|
|
283
|
+
name: lockPm
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
const override = getPackageManagerOverride();
|
|
287
|
+
if (override) return override;
|
|
288
|
+
const envPm = detectPackageManagerFromEnv();
|
|
289
|
+
if (envPm) return envPm;
|
|
290
|
+
const candidates = [
|
|
291
|
+
'pnpm',
|
|
292
|
+
'yarn',
|
|
293
|
+
'bun'
|
|
294
|
+
];
|
|
295
|
+
for (const candidate of candidates){
|
|
296
|
+
const resolved = resolveCommandOnPath(candidate);
|
|
297
|
+
if (resolved) return {
|
|
298
|
+
name: candidate,
|
|
299
|
+
execPath: resolved
|
|
300
|
+
};
|
|
301
|
+
}
|
|
302
|
+
const corepackPath = resolveCommandOnPath('corepack');
|
|
303
|
+
if (corepackPath || canRunCorepack()) return {
|
|
304
|
+
name: 'pnpm',
|
|
305
|
+
runnerCommand: corepackPath || 'corepack',
|
|
306
|
+
runnerArgs: [
|
|
307
|
+
'pnpm'
|
|
308
|
+
]
|
|
309
|
+
};
|
|
310
|
+
const bundledNpmCli = resolveBundledNpmCliPath();
|
|
311
|
+
if (bundledNpmCli) return {
|
|
312
|
+
name: 'npm',
|
|
313
|
+
execPath: bundledNpmCli,
|
|
314
|
+
runnerCommand: process.execPath,
|
|
315
|
+
runnerArgs: [
|
|
316
|
+
bundledNpmCli
|
|
317
|
+
]
|
|
318
|
+
};
|
|
319
|
+
return {
|
|
320
|
+
name: 'npm'
|
|
321
|
+
};
|
|
322
|
+
}
|
|
323
|
+
function buildExecEnv() {
|
|
324
|
+
if ('win32' !== process.platform) return;
|
|
325
|
+
const nodeDir = __rspack_external_path.dirname(process.execPath);
|
|
326
|
+
const pathSep = __rspack_external_path.delimiter;
|
|
327
|
+
const existing = process.env.PATH || process.env.Path || '';
|
|
328
|
+
if (existing.includes(nodeDir)) return;
|
|
329
|
+
return {
|
|
330
|
+
...process.env,
|
|
331
|
+
PATH: `${nodeDir}${pathSep}${existing}`.trim(),
|
|
332
|
+
Path: `${nodeDir}${pathSep}${existing}`.trim()
|
|
333
|
+
};
|
|
334
|
+
}
|
|
335
|
+
function buildInstallCommand(pm, args) {
|
|
336
|
+
if (pm.runnerCommand) return {
|
|
337
|
+
command: pm.runnerCommand,
|
|
338
|
+
args: [
|
|
339
|
+
...pm.runnerArgs || [],
|
|
340
|
+
...args
|
|
341
|
+
]
|
|
342
|
+
};
|
|
343
|
+
if (pm.execPath) {
|
|
344
|
+
if (isWindowsExecutablePath(pm.execPath)) return {
|
|
345
|
+
command: pm.execPath,
|
|
346
|
+
args
|
|
347
|
+
};
|
|
348
|
+
if (isNodeScriptPath(pm.execPath)) return {
|
|
349
|
+
command: process.execPath,
|
|
350
|
+
args: [
|
|
351
|
+
pm.execPath,
|
|
352
|
+
...args
|
|
353
|
+
]
|
|
354
|
+
};
|
|
355
|
+
return {
|
|
356
|
+
command: pm.execPath,
|
|
357
|
+
args
|
|
358
|
+
};
|
|
359
|
+
}
|
|
360
|
+
return {
|
|
361
|
+
command: pm.name,
|
|
362
|
+
args
|
|
363
|
+
};
|
|
364
|
+
}
|
|
365
|
+
function buildSpawnInvocation(command, args) {
|
|
366
|
+
return {
|
|
367
|
+
command,
|
|
368
|
+
args
|
|
369
|
+
};
|
|
370
|
+
}
|
|
371
|
+
function execInstallCommand(command, args, options) {
|
|
372
|
+
const invocation = buildSpawnInvocation(command, args);
|
|
373
|
+
const env = buildExecEnv();
|
|
374
|
+
const stdio = options?.stdio ?? 'ignore';
|
|
375
|
+
const useShell = 'win32' === process.platform && /\.(cmd|bat)$/i.test(invocation.command);
|
|
376
|
+
return new Promise((resolve, reject)=>{
|
|
377
|
+
const child = spawn(invocation.command, invocation.args, {
|
|
378
|
+
cwd: options?.cwd,
|
|
379
|
+
stdio,
|
|
380
|
+
env: env || process.env,
|
|
381
|
+
...useShell ? {
|
|
382
|
+
shell: true
|
|
383
|
+
} : {}
|
|
384
|
+
});
|
|
385
|
+
child.on('close', (code)=>{
|
|
386
|
+
if (0 !== code) reject(new Error(`Install failed with exit code ${code}`));
|
|
387
|
+
else resolve();
|
|
388
|
+
});
|
|
389
|
+
child.on('error', (error)=>reject(error));
|
|
390
|
+
});
|
|
391
|
+
}
|
|
392
|
+
async function ensureUserProjectDependencies(packageJsonDir) {
|
|
393
|
+
if (!needsInstall(packageJsonDir)) return;
|
|
394
|
+
const pm = resolvePackageManager({
|
|
395
|
+
cwd: packageJsonDir
|
|
396
|
+
});
|
|
397
|
+
const cmd = buildInstallCommand(pm, [
|
|
398
|
+
'install'
|
|
399
|
+
]);
|
|
400
|
+
await execInstallCommand(cmd.command, cmd.args, {
|
|
401
|
+
cwd: packageJsonDir,
|
|
402
|
+
stdio: 'inherit'
|
|
403
|
+
});
|
|
404
|
+
}
|
|
405
|
+
async function ensureDevelopArtifacts() {
|
|
406
|
+
const developRoot = findExtensionDevelopRoot();
|
|
407
|
+
if (!developRoot) return;
|
|
408
|
+
const requiredFiles = [
|
|
409
|
+
__rspack_external_path.join(developRoot, 'dist', "ensure-hmr-for-scripts.js"),
|
|
410
|
+
__rspack_external_path.join(developRoot, 'dist', "minimum-script-file.js")
|
|
411
|
+
];
|
|
412
|
+
const missing = requiredFiles.filter((file)=>!__rspack_external_fs.existsSync(file));
|
|
413
|
+
if (0 === missing.length) return;
|
|
414
|
+
const pm = resolvePackageManager({
|
|
415
|
+
cwd: developRoot
|
|
416
|
+
});
|
|
417
|
+
const command = buildInstallCommand(pm, [
|
|
418
|
+
'run',
|
|
419
|
+
'compile'
|
|
420
|
+
]);
|
|
421
|
+
const isAuthor = 'true' === process.env.EXTENSION_AUTHOR_MODE;
|
|
422
|
+
const stdio = isAuthor ? 'inherit' : 'ignore';
|
|
423
|
+
if (isAuthor) console.warn(authorInstallNotice('extension-develop build artifacts (dist missing)'));
|
|
424
|
+
await execInstallCommand(command.command, command.args, {
|
|
425
|
+
cwd: developRoot,
|
|
426
|
+
stdio
|
|
427
|
+
});
|
|
428
|
+
}
|
|
429
|
+
async function extensionBuild(pathOrRemoteUrl, buildOptions) {
|
|
430
|
+
const projectStructure = await getProjectStructure(pathOrRemoteUrl);
|
|
431
|
+
const isVitest = 'true' === process.env.VITEST;
|
|
432
|
+
const shouldExitOnError = (buildOptions?.exitOnError ?? true) && !isVitest;
|
|
433
|
+
const browser = normalizeBrowser(buildOptions?.browser || 'chrome', buildOptions?.chromiumBinary, buildOptions?.geckoBinary || buildOptions?.firefoxBinary);
|
|
434
|
+
const { manifestDir, packageJsonDir } = getDirs(projectStructure);
|
|
435
|
+
const isAuthor = 'true' === process.env.EXTENSION_AUTHOR_MODE;
|
|
436
|
+
try {
|
|
437
|
+
await ensureDevelopArtifacts();
|
|
438
|
+
if (buildOptions?.install !== false) await ensureUserProjectDependencies(packageJsonDir);
|
|
439
|
+
const [{ rspack }, { merge }, { handleStatsErrors }, { default: webpackConfig }] = await Promise.all([
|
|
440
|
+
import("@rspack/core"),
|
|
441
|
+
import("webpack-merge"),
|
|
442
|
+
import("./0~stats-handler.mjs"),
|
|
443
|
+
import("./0~rspack-config.mjs").then((m)=>m.rspack_config_namespaceObject)
|
|
444
|
+
]);
|
|
445
|
+
const debug = isAuthor;
|
|
446
|
+
if (projectStructure.packageJsonPath) assertNoManagedDependencyConflicts(projectStructure.packageJsonPath, manifestDir);
|
|
447
|
+
const commandConfig = await loadCommandConfig(packageJsonDir, 'build');
|
|
448
|
+
const specialFoldersData = getSpecialFoldersDataForProjectRoot(packageJsonDir);
|
|
449
|
+
const distPath = getDistPath(packageJsonDir, browser);
|
|
450
|
+
try {
|
|
451
|
+
__rspack_external_fs.rmSync(distPath, {
|
|
452
|
+
recursive: true,
|
|
453
|
+
force: true
|
|
454
|
+
});
|
|
455
|
+
} catch {}
|
|
456
|
+
if (debug) {
|
|
457
|
+
console.log(debugDirs(manifestDir, packageJsonDir));
|
|
458
|
+
console.log(debugBrowser(browser, buildOptions?.chromiumBinary, buildOptions?.geckoBinary || buildOptions?.firefoxBinary));
|
|
459
|
+
console.log(debugOutputPath(distPath));
|
|
460
|
+
}
|
|
461
|
+
const mergedExtensionsConfig = buildOptions?.extensions ?? commandConfig.extensions ?? specialFoldersData.extensions;
|
|
462
|
+
const resolvedExtensionsConfig = await resolveCompanionExtensionsConfig({
|
|
463
|
+
projectRoot: packageJsonDir,
|
|
464
|
+
browser,
|
|
465
|
+
config: mergedExtensionsConfig
|
|
466
|
+
});
|
|
467
|
+
const resolvedMode = buildOptions?.mode === 'development' || buildOptions?.mode === 'none' || buildOptions?.mode === 'production' ? buildOptions.mode : 'production';
|
|
468
|
+
if ('development' === resolvedMode || 'production' === resolvedMode) process.env.NODE_ENV = resolvedMode;
|
|
469
|
+
const baseConfig = webpackConfig(projectStructure, {
|
|
470
|
+
...commandConfig,
|
|
471
|
+
...buildOptions,
|
|
472
|
+
extensions: resolvedExtensionsConfig,
|
|
473
|
+
browser,
|
|
474
|
+
mode: resolvedMode,
|
|
475
|
+
output: {
|
|
476
|
+
clean: true,
|
|
477
|
+
path: distPath
|
|
478
|
+
}
|
|
479
|
+
});
|
|
480
|
+
const allPluginsButBrowserRunners = baseConfig.plugins?.filter((plugin)=>plugin?.constructor.name !== 'plugin-browsers');
|
|
481
|
+
const userExtensionConfig = await loadCustomConfig(packageJsonDir);
|
|
482
|
+
const userConfig = userExtensionConfig({
|
|
483
|
+
...baseConfig,
|
|
484
|
+
plugins: allPluginsButBrowserRunners
|
|
485
|
+
});
|
|
486
|
+
const compilerConfig = merge(userConfig);
|
|
487
|
+
compilerConfig.stats = false;
|
|
488
|
+
const compiler = rspack(compilerConfig);
|
|
489
|
+
let summary = {
|
|
490
|
+
browser,
|
|
491
|
+
total_assets: 0,
|
|
492
|
+
total_bytes: 0,
|
|
493
|
+
largest_asset_bytes: 0,
|
|
494
|
+
warnings_count: 0,
|
|
495
|
+
errors_count: 0
|
|
496
|
+
};
|
|
497
|
+
await new Promise((resolve, reject)=>{
|
|
498
|
+
compiler.run(async (err, stats)=>{
|
|
499
|
+
if (err) {
|
|
500
|
+
console.error(err.stack || err);
|
|
501
|
+
return reject(err);
|
|
502
|
+
}
|
|
503
|
+
if (!stats || 'function' != typeof stats.hasErrors) return reject(new Error('Build failed: bundler returned invalid stats output (no reliable compilation result).'));
|
|
504
|
+
if (!buildOptions?.silent && stats) console.log(buildWebpack(manifestDir, stats, browser));
|
|
505
|
+
if (stats.hasErrors()) {
|
|
506
|
+
handleStatsErrors(stats);
|
|
507
|
+
if (!shouldExitOnError) return reject(new Error('Build failed with errors'));
|
|
508
|
+
process.exit(1);
|
|
509
|
+
} else {
|
|
510
|
+
const info = stats?.toJson({
|
|
511
|
+
all: false,
|
|
512
|
+
assets: true,
|
|
513
|
+
warnings: true,
|
|
514
|
+
errors: true
|
|
515
|
+
});
|
|
516
|
+
summary = getBuildSummary(browser, info);
|
|
517
|
+
if (summary.warnings_count > 0) {
|
|
518
|
+
console.log(buildSuccessWithWarnings(summary.warnings_count));
|
|
519
|
+
const warningDetails = buildWarningsDetails(info?.warnings || []);
|
|
520
|
+
if (warningDetails) console.log(`\n${warningDetails}`);
|
|
521
|
+
} else console.log(buildSuccess());
|
|
522
|
+
resolve();
|
|
523
|
+
}
|
|
524
|
+
});
|
|
525
|
+
});
|
|
526
|
+
return summary;
|
|
527
|
+
} catch (error) {
|
|
528
|
+
const isAuthor = 'true' === process.env.EXTENSION_AUTHOR_MODE;
|
|
529
|
+
if (isAuthor) console.error(error);
|
|
530
|
+
else console.error(buildCommandFailed(error));
|
|
531
|
+
if (!shouldExitOnError) throw error;
|
|
532
|
+
process.exit(1);
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
async function generateExtensionTypes(manifestDir, packageJsonDir) {
|
|
536
|
+
const extensionEnvFile = __rspack_external_path.join(packageJsonDir, 'extension-env.d.ts');
|
|
537
|
+
const typePath = 'extension';
|
|
538
|
+
const fileContent = `\
|
|
539
|
+
// Required Extension.js types for TypeScript projects.
|
|
540
|
+
// This file is auto-generated and should not be excluded.
|
|
541
|
+
// If you need additional types, consider creating a new *.d.ts file and
|
|
542
|
+
// referencing it in the "include" array of your tsconfig.json file.
|
|
543
|
+
// See https://www.typescriptlang.org/tsconfig#include for more information.
|
|
544
|
+
/// <reference types="${typePath}/types" />
|
|
545
|
+
|
|
546
|
+
// Polyfill types for browser.* APIs
|
|
547
|
+
/// <reference types="${typePath}/types/polyfill" />
|
|
548
|
+
`;
|
|
549
|
+
try {
|
|
550
|
+
await __rspack_external_fs_promises_400951f8.access(extensionEnvFile);
|
|
551
|
+
const existingContent = await __rspack_external_fs_promises_400951f8.readFile(extensionEnvFile, 'utf8');
|
|
552
|
+
if (existingContent.includes('develop/dist/types')) await __rspack_external_fs_promises_400951f8.writeFile(extensionEnvFile, fileContent);
|
|
553
|
+
await __rspack_external_fs_promises_400951f8.writeFile(extensionEnvFile, fileContent);
|
|
554
|
+
} catch (err) {
|
|
555
|
+
const manifestText = await __rspack_external_fs_promises_400951f8.readFile(__rspack_external_path.join(manifestDir, 'manifest.json'), 'utf8');
|
|
556
|
+
const manifest = parseJsonSafe(manifestText);
|
|
557
|
+
console.log(writingTypeDefinitions(manifest));
|
|
558
|
+
try {
|
|
559
|
+
await __rspack_external_fs_promises_400951f8.writeFile(extensionEnvFile, fileContent);
|
|
560
|
+
} catch (writeErr) {
|
|
561
|
+
console.log(writingTypeDefinitionsError(writeErr));
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
class BuildEmitter extends EventEmitter {
|
|
566
|
+
constructor(){
|
|
567
|
+
super();
|
|
568
|
+
this.on('error', ()=>{});
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
class BrowsersPlugin {
|
|
572
|
+
options;
|
|
573
|
+
static name = 'plugin-browsers';
|
|
574
|
+
emitter = new BuildEmitter();
|
|
575
|
+
extensionsToLoad = [];
|
|
576
|
+
isFirstCompile = true;
|
|
577
|
+
controller;
|
|
578
|
+
constructor(options){
|
|
579
|
+
this.options = options;
|
|
580
|
+
}
|
|
581
|
+
apply(compiler) {
|
|
582
|
+
let pendingReloadReason;
|
|
583
|
+
let pendingChangedSources = [];
|
|
584
|
+
compiler.hooks.watchRun.tap(BrowsersPlugin.name, ()=>{
|
|
585
|
+
pendingReloadReason = void 0;
|
|
586
|
+
pendingChangedSources = [];
|
|
587
|
+
const modifiedFiles = compiler.modifiedFiles;
|
|
588
|
+
if (!modifiedFiles || 0 === modifiedFiles.size) return;
|
|
589
|
+
const contextDir = compiler.options.context || '';
|
|
590
|
+
for (const file of modifiedFiles){
|
|
591
|
+
const normalized = __rspack_external_path.relative(contextDir, file).replace(/\\/g, '/');
|
|
592
|
+
pendingChangedSources.push(normalized);
|
|
593
|
+
if (normalized.includes('manifest.json')) pendingReloadReason = 'full';
|
|
594
|
+
else if (normalized.includes('_locales/')) pendingReloadReason = 'full';
|
|
595
|
+
}
|
|
596
|
+
});
|
|
597
|
+
compiler.hooks.done.tapPromise(BrowsersPlugin.name, async (stats)=>{
|
|
598
|
+
const compilation = stats.compilation;
|
|
599
|
+
const hasErrors = compilation.errors && compilation.errors.length > 0;
|
|
600
|
+
if (hasErrors) return void this.emitter.emit('error', {
|
|
601
|
+
errors: compilation.errors.map((e)=>'string' == typeof e ? e : e.message || String(e))
|
|
602
|
+
});
|
|
603
|
+
const outputPath = String(compilation.options?.output?.path || '');
|
|
604
|
+
const contextDir = String(compilation.options?.context || '');
|
|
605
|
+
let reloadInstruction;
|
|
606
|
+
if (!this.isFirstCompile && pendingReloadReason) reloadInstruction = {
|
|
607
|
+
type: pendingReloadReason,
|
|
608
|
+
changedAssets: pendingChangedSources
|
|
609
|
+
};
|
|
610
|
+
else if (!this.isFirstCompile && pendingChangedSources.length > 0) {
|
|
611
|
+
const isServiceWorkerSource = (rel)=>/(^|\/)background(\.|\/)/i.test(rel) || /service[-_.]?worker/i.test(rel);
|
|
612
|
+
const hasServiceWorkerChange = pendingChangedSources.some(isServiceWorkerSource);
|
|
613
|
+
if (hasServiceWorkerChange) reloadInstruction = {
|
|
614
|
+
type: 'service-worker',
|
|
615
|
+
changedAssets: pendingChangedSources
|
|
616
|
+
};
|
|
617
|
+
else {
|
|
618
|
+
const contentScriptCount = readContentScriptCount(compilation, outputPath);
|
|
619
|
+
if (contentScriptCount > 0) {
|
|
620
|
+
const entries = [];
|
|
621
|
+
for(let i = 0; i < contentScriptCount; i++)entries.push(getCanonicalContentScriptEntryName(i));
|
|
622
|
+
reloadInstruction = {
|
|
623
|
+
type: "content-scripts",
|
|
624
|
+
changedContentScriptEntries: entries,
|
|
625
|
+
changedAssets: pendingChangedSources
|
|
626
|
+
};
|
|
627
|
+
} else reloadInstruction = void 0;
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
const wasFirstCompile = this.isFirstCompile;
|
|
631
|
+
this.isFirstCompile = false;
|
|
632
|
+
if (wasFirstCompile) try {
|
|
633
|
+
this.controller = await this.options.launcher({
|
|
634
|
+
...this.options.browserOptions,
|
|
635
|
+
outputPath,
|
|
636
|
+
contextDir,
|
|
637
|
+
extensionsToLoad: this.extensionsToLoad
|
|
638
|
+
});
|
|
639
|
+
const logLevel = this.options.browserOptions.logLevel || 'off';
|
|
640
|
+
if ('off' !== logLevel && this.controller) await this.controller.enableUnifiedLogging({
|
|
641
|
+
level: logLevel,
|
|
642
|
+
contexts: this.options.browserOptions.logContexts,
|
|
643
|
+
format: this.options.browserOptions.logFormat,
|
|
644
|
+
timestamps: this.options.browserOptions.logTimestamps,
|
|
645
|
+
color: this.options.browserOptions.logColor,
|
|
646
|
+
urlFilter: this.options.browserOptions.logUrl,
|
|
647
|
+
tabFilter: this.options.browserOptions.logTab
|
|
648
|
+
});
|
|
649
|
+
} catch (error) {
|
|
650
|
+
this.emitter.emit('error', {
|
|
651
|
+
errors: [
|
|
652
|
+
error instanceof Error ? error.message : String(error)
|
|
653
|
+
]
|
|
654
|
+
});
|
|
655
|
+
}
|
|
656
|
+
else if (this.controller && reloadInstruction) {
|
|
657
|
+
if ('true' !== process.env.EXTENSION_NO_RELOAD) try {
|
|
658
|
+
await this.controller.reload(reloadInstruction);
|
|
659
|
+
} catch {}
|
|
660
|
+
}
|
|
661
|
+
this.emitter.emit('compiled', {
|
|
662
|
+
outputPath,
|
|
663
|
+
contextDir,
|
|
664
|
+
isFirstCompile: wasFirstCompile,
|
|
665
|
+
reloadInstruction,
|
|
666
|
+
extensionsToLoad: wasFirstCompile ? this.extensionsToLoad : void 0
|
|
667
|
+
});
|
|
668
|
+
});
|
|
669
|
+
}
|
|
670
|
+
}
|
|
671
|
+
function readContentScriptCount(compilation, outputPath) {
|
|
672
|
+
try {
|
|
673
|
+
const asset = compilation.getAsset?.('manifest.json');
|
|
674
|
+
if (asset?.source) {
|
|
675
|
+
const manifest = JSON.parse(String(asset.source.source()));
|
|
676
|
+
const list = manifest?.content_scripts;
|
|
677
|
+
if (Array.isArray(list)) return list.length;
|
|
678
|
+
}
|
|
679
|
+
} catch {}
|
|
680
|
+
try {
|
|
681
|
+
const manifestPath = __rspack_external_path.join(outputPath, 'manifest.json');
|
|
682
|
+
if (__rspack_external_fs.existsSync(manifestPath)) {
|
|
683
|
+
const manifest = JSON.parse(__rspack_external_fs.readFileSync(manifestPath, 'utf8'));
|
|
684
|
+
const list = manifest?.content_scripts;
|
|
685
|
+
if (Array.isArray(list)) return list.length;
|
|
686
|
+
}
|
|
687
|
+
} catch {}
|
|
688
|
+
return 0;
|
|
689
|
+
}
|
|
690
|
+
function isUsingIntegration(name) {
|
|
691
|
+
return `${pintor.gray('⏵⏵⏵')} Using ${pintor.brightBlue(name)}...`;
|
|
692
|
+
}
|
|
693
|
+
function creatingTSConfig() {
|
|
694
|
+
return `${pintor.gray('⏵⏵⏵')} Creating default tsconfig.json...`;
|
|
695
|
+
}
|
|
696
|
+
function isUsingCustomLoader(loaderPath) {
|
|
697
|
+
return `${pintor.gray('⏵⏵⏵')} Using custom loader: ${pintor.yellow(loaderPath)}.`;
|
|
698
|
+
}
|
|
699
|
+
function jsFrameworksIntegrationsEnabled(integrations) {
|
|
700
|
+
const list = integrations.length > 0 ? integrations.map((n)=>pintor.yellow(n)).join(', ') : pintor.gray('none');
|
|
701
|
+
return `${pintor.gray('⏵⏵⏵')} JS: Integrations enabled (${pintor.gray(String(integrations.length))}) ${list}`;
|
|
702
|
+
}
|
|
703
|
+
function jsFrameworksConfigsDetected(tsConfigPath, tsRoot, targets) {
|
|
704
|
+
const fmt = (v)=>v ? pintor.underline(v) : pintor.gray('none');
|
|
705
|
+
const tgt = targets && targets.length ? targets.map((t)=>pintor.gray(t)).join(', ') : pintor.gray('default');
|
|
706
|
+
return `${pintor.gray('⏵⏵⏵')} JS: Configs\n${pintor.gray('TSCONFIG')} ${fmt(tsConfigPath)}\n${pintor.gray('TSROOT')} ${fmt(tsRoot)}\n${pintor.gray('SWC_TARGETS')} ${tgt}`;
|
|
707
|
+
}
|
|
708
|
+
function jsFrameworksHmrSummary(enabled, frameworks) {
|
|
709
|
+
const list = frameworks.length > 0 ? frameworks.map((n)=>pintor.yellow(n)).join(', ') : pintor.gray('none');
|
|
710
|
+
return `${pintor.gray('⏵⏵⏵')} JS: HMR ${enabled ? pintor.green('enabled') : pintor.gray('disabled')} for ${list}`;
|
|
711
|
+
}
|
|
712
|
+
function hasDependency(projectPath, packageName) {
|
|
713
|
+
const manifestPath = __rspack_external_path.join(projectPath, 'package.json');
|
|
714
|
+
if (!__rspack_external_fs.existsSync(manifestPath)) return false;
|
|
715
|
+
try {
|
|
716
|
+
const raw = __rspack_external_fs.readFileSync(manifestPath, 'utf8');
|
|
717
|
+
const pkg = JSON.parse(raw || '{}');
|
|
718
|
+
const sections = [
|
|
719
|
+
pkg.dependencies,
|
|
720
|
+
pkg.devDependencies,
|
|
721
|
+
pkg.optionalDependencies,
|
|
722
|
+
pkg.peerDependencies
|
|
723
|
+
];
|
|
724
|
+
return sections.some((s)=>s && 'object' == typeof s && packageName in s);
|
|
725
|
+
} catch {
|
|
726
|
+
return false;
|
|
727
|
+
}
|
|
728
|
+
}
|
|
729
|
+
function isUsingJSFramework(projectPath) {
|
|
730
|
+
const frameworks = [
|
|
731
|
+
'react',
|
|
732
|
+
'vue',
|
|
733
|
+
'@angular/core',
|
|
734
|
+
'svelte',
|
|
735
|
+
'solid-js',
|
|
736
|
+
'preact'
|
|
737
|
+
];
|
|
738
|
+
return frameworks.some((fw)=>hasDependency(projectPath, fw));
|
|
739
|
+
}
|
|
740
|
+
function installRootRules(packageIds) {
|
|
741
|
+
return packageIds.map((packageId)=>({
|
|
742
|
+
type: 'install-root',
|
|
743
|
+
packageId
|
|
744
|
+
}));
|
|
745
|
+
}
|
|
746
|
+
function defineContract(contract) {
|
|
747
|
+
return contract;
|
|
748
|
+
}
|
|
749
|
+
const OPTIONAL_DEPENDENCY_CONTRACTS = {
|
|
750
|
+
typescript: defineContract({
|
|
751
|
+
id: "typescript",
|
|
752
|
+
integration: 'TypeScript',
|
|
753
|
+
installPackages: [
|
|
754
|
+
"typescript@5.9.3"
|
|
755
|
+
],
|
|
756
|
+
verificationRules: installRootRules([
|
|
757
|
+
"typescript"
|
|
758
|
+
])
|
|
759
|
+
}),
|
|
760
|
+
'react-refresh': defineContract({
|
|
761
|
+
id: 'react-refresh',
|
|
762
|
+
integration: 'React',
|
|
763
|
+
installPackages: [
|
|
764
|
+
'react-refresh@0.18.0',
|
|
765
|
+
'@rspack/plugin-react-refresh@1.6.0'
|
|
766
|
+
],
|
|
767
|
+
verificationRules: [
|
|
768
|
+
...installRootRules([
|
|
769
|
+
'react-refresh',
|
|
770
|
+
'@rspack/plugin-react-refresh'
|
|
771
|
+
]),
|
|
772
|
+
{
|
|
773
|
+
type: 'module-context-resolve',
|
|
774
|
+
fromPackage: '@rspack/plugin-react-refresh',
|
|
775
|
+
packageId: 'react-refresh'
|
|
776
|
+
}
|
|
777
|
+
]
|
|
778
|
+
}),
|
|
779
|
+
'preact-refresh': defineContract({
|
|
780
|
+
id: 'preact-refresh',
|
|
781
|
+
integration: 'Preact',
|
|
782
|
+
installPackages: [
|
|
783
|
+
'@prefresh/core@1.5.9',
|
|
784
|
+
'@prefresh/utils@1.2.1',
|
|
785
|
+
'@rspack/plugin-preact-refresh@1.1.5',
|
|
786
|
+
'preact@10.27.2'
|
|
787
|
+
],
|
|
788
|
+
verificationRules: [
|
|
789
|
+
...installRootRules([
|
|
790
|
+
'@prefresh/core',
|
|
791
|
+
'@prefresh/utils',
|
|
792
|
+
'@rspack/plugin-preact-refresh',
|
|
793
|
+
'preact'
|
|
794
|
+
]),
|
|
795
|
+
{
|
|
796
|
+
type: 'module-context-resolve',
|
|
797
|
+
fromPackage: '@rspack/plugin-preact-refresh',
|
|
798
|
+
packageId: '@prefresh/core'
|
|
799
|
+
},
|
|
800
|
+
{
|
|
801
|
+
type: 'module-context-resolve',
|
|
802
|
+
fromPackage: '@rspack/plugin-preact-refresh',
|
|
803
|
+
packageId: '@prefresh/utils'
|
|
804
|
+
},
|
|
805
|
+
{
|
|
806
|
+
type: 'module-context-resolve',
|
|
807
|
+
fromPackage: '@rspack/plugin-preact-refresh',
|
|
808
|
+
packageId: 'preact'
|
|
809
|
+
}
|
|
810
|
+
]
|
|
811
|
+
}),
|
|
812
|
+
vue: defineContract({
|
|
813
|
+
id: 'vue',
|
|
814
|
+
integration: 'Vue',
|
|
815
|
+
installPackages: [
|
|
816
|
+
'vue-loader@17.4.2',
|
|
817
|
+
'@vue/compiler-sfc@3.5.26',
|
|
818
|
+
'vue@3.5.26'
|
|
819
|
+
],
|
|
820
|
+
verificationRules: [
|
|
821
|
+
...installRootRules([
|
|
822
|
+
'vue-loader',
|
|
823
|
+
'@vue/compiler-sfc',
|
|
824
|
+
'vue'
|
|
825
|
+
]),
|
|
826
|
+
{
|
|
827
|
+
type: 'module-context-load',
|
|
828
|
+
fromPackage: 'vue-loader',
|
|
829
|
+
packageId: '@vue/compiler-sfc'
|
|
830
|
+
}
|
|
831
|
+
]
|
|
832
|
+
}),
|
|
833
|
+
svelte: defineContract({
|
|
834
|
+
id: 'svelte',
|
|
835
|
+
integration: 'Svelte',
|
|
836
|
+
installPackages: [
|
|
837
|
+
"typescript@5.9.3",
|
|
838
|
+
'svelte-loader@3.2.4'
|
|
839
|
+
],
|
|
840
|
+
verificationRules: installRootRules([
|
|
841
|
+
"typescript",
|
|
842
|
+
'svelte-loader'
|
|
843
|
+
])
|
|
844
|
+
}),
|
|
845
|
+
less: defineContract({
|
|
846
|
+
id: 'less',
|
|
847
|
+
integration: 'LESS',
|
|
848
|
+
installPackages: [
|
|
849
|
+
'less@4.5.1',
|
|
850
|
+
'less-loader@12.3.0'
|
|
851
|
+
],
|
|
852
|
+
verificationRules: installRootRules([
|
|
853
|
+
'less',
|
|
854
|
+
'less-loader'
|
|
855
|
+
])
|
|
856
|
+
}),
|
|
857
|
+
postcss: defineContract({
|
|
858
|
+
id: 'postcss',
|
|
859
|
+
integration: 'PostCSS',
|
|
860
|
+
installPackages: [
|
|
861
|
+
'postcss@8.5.6',
|
|
862
|
+
'postcss-loader@8.2.0'
|
|
863
|
+
],
|
|
864
|
+
verificationRules: installRootRules([
|
|
865
|
+
'postcss',
|
|
866
|
+
'postcss-loader'
|
|
867
|
+
])
|
|
868
|
+
}),
|
|
869
|
+
sass: defineContract({
|
|
870
|
+
id: 'sass',
|
|
871
|
+
integration: 'SASS',
|
|
872
|
+
installPackages: [
|
|
873
|
+
'postcss-loader@8.2.0',
|
|
874
|
+
'postcss-scss@4.0.9',
|
|
875
|
+
'postcss-preset-env@11.1.1',
|
|
876
|
+
'sass-loader@16.0.6'
|
|
877
|
+
],
|
|
878
|
+
verificationRules: installRootRules([
|
|
879
|
+
'postcss-loader',
|
|
880
|
+
'postcss-scss',
|
|
881
|
+
'postcss-preset-env',
|
|
882
|
+
'sass-loader'
|
|
883
|
+
])
|
|
884
|
+
})
|
|
885
|
+
};
|
|
886
|
+
function getOptionalDependencyContract(contractId) {
|
|
887
|
+
const contract = OPTIONAL_DEPENDENCY_CONTRACTS[contractId];
|
|
888
|
+
if (!contract) throw new Error(`Unknown optional dependency contract: ${contractId}`);
|
|
889
|
+
return contract;
|
|
890
|
+
}
|
|
891
|
+
function toInstallRootContract(integration, contractId, installDependencies, verifyPackageIds) {
|
|
892
|
+
return {
|
|
893
|
+
id: contractId,
|
|
894
|
+
integration,
|
|
895
|
+
installPackages: installDependencies,
|
|
896
|
+
verificationRules: verifyPackageIds.map((packageId)=>({
|
|
897
|
+
type: 'install-root',
|
|
898
|
+
packageId
|
|
899
|
+
}))
|
|
900
|
+
};
|
|
901
|
+
}
|
|
902
|
+
function getVerificationContract(input) {
|
|
903
|
+
if (input.contract) return input.contract;
|
|
904
|
+
const installDependencies = input.installDependencies || [
|
|
905
|
+
input.dependencyId
|
|
906
|
+
];
|
|
907
|
+
const verifyPackageIds = input.verifyPackageIds || installDependencies;
|
|
908
|
+
return toInstallRootContract(input.integration, input.integration, installDependencies, verifyPackageIds);
|
|
909
|
+
}
|
|
910
|
+
function getResolutionBases(projectPath) {
|
|
911
|
+
const extensionRoot = resolveDevelopInstallRoot();
|
|
912
|
+
const bases = [
|
|
913
|
+
projectPath,
|
|
914
|
+
extensionRoot || void 0,
|
|
915
|
+
process.cwd()
|
|
916
|
+
].filter(Boolean);
|
|
917
|
+
if (extensionRoot && extensionRoot.includes('.pnpm')) bases.push(__rspack_external_path.join(extensionRoot, '..', '..'));
|
|
918
|
+
return Array.from(new Set(bases));
|
|
919
|
+
}
|
|
920
|
+
function optional_deps_resolver_packageJsonPath(basePath) {
|
|
921
|
+
return __rspack_external_path.join(basePath, 'package.json');
|
|
922
|
+
}
|
|
923
|
+
function tryResolveWithBase(dependencyId, basePath) {
|
|
924
|
+
try {
|
|
925
|
+
const req = createRequire(optional_deps_resolver_packageJsonPath(basePath));
|
|
926
|
+
return req.resolve(dependencyId);
|
|
927
|
+
} catch {
|
|
928
|
+
return;
|
|
929
|
+
}
|
|
930
|
+
}
|
|
931
|
+
function resolveDependency(dependencyId, projectPath) {
|
|
932
|
+
const bases = getResolutionBases(projectPath);
|
|
933
|
+
for (const basePath of bases){
|
|
934
|
+
const resolvedPath = tryResolveWithBase(dependencyId, basePath);
|
|
935
|
+
if (resolvedPath) return {
|
|
936
|
+
resolvedPath,
|
|
937
|
+
basePath
|
|
938
|
+
};
|
|
939
|
+
}
|
|
940
|
+
try {
|
|
941
|
+
const resolvedPath = require.resolve(dependencyId, {
|
|
942
|
+
paths: bases
|
|
943
|
+
});
|
|
944
|
+
return {
|
|
945
|
+
resolvedPath,
|
|
946
|
+
basePath: projectPath
|
|
947
|
+
};
|
|
948
|
+
} catch {
|
|
949
|
+
return;
|
|
950
|
+
}
|
|
951
|
+
}
|
|
952
|
+
function resolveFromKnownLocations(dependencyId, projectPath) {
|
|
953
|
+
const direct = resolveDependency(dependencyId, projectPath)?.resolvedPath;
|
|
954
|
+
if (direct) return direct;
|
|
955
|
+
if (declaresDependency(projectPath, dependencyId)) return projectPath;
|
|
956
|
+
}
|
|
957
|
+
function declaresDependency(projectPath, dependencyId) {
|
|
958
|
+
try {
|
|
959
|
+
const packageJsonPath = __rspack_external_path.join(projectPath, 'package.json');
|
|
960
|
+
if (!__rspack_external_fs.existsSync(packageJsonPath)) return false;
|
|
961
|
+
const pkg = JSON.parse(__rspack_external_fs.readFileSync(packageJsonPath, 'utf8'));
|
|
962
|
+
const sections = [
|
|
963
|
+
pkg.dependencies,
|
|
964
|
+
pkg.devDependencies,
|
|
965
|
+
pkg.optionalDependencies,
|
|
966
|
+
pkg.peerDependencies
|
|
967
|
+
];
|
|
968
|
+
return sections.some((section)=>section && 'object' == typeof section && dependencyId in section);
|
|
969
|
+
} catch {
|
|
970
|
+
return false;
|
|
971
|
+
}
|
|
972
|
+
}
|
|
973
|
+
function dedupeFailures(packageIds) {
|
|
974
|
+
return Array.from(new Set(packageIds));
|
|
975
|
+
}
|
|
976
|
+
function resolveRealPathSafe(targetPath) {
|
|
977
|
+
try {
|
|
978
|
+
return __rspack_external_fs.realpathSync(targetPath);
|
|
979
|
+
} catch {
|
|
980
|
+
return __rspack_external_path.resolve(targetPath);
|
|
981
|
+
}
|
|
982
|
+
}
|
|
983
|
+
function findOwningPackageDir(resolvedPath) {
|
|
984
|
+
let currentPath = __rspack_external_path.dirname(resolvedPath);
|
|
985
|
+
for(let depth = 0; depth < 8; depth++){
|
|
986
|
+
const packageJson = __rspack_external_path.join(currentPath, 'package.json');
|
|
987
|
+
if (__rspack_external_fs.existsSync(packageJson)) return currentPath;
|
|
988
|
+
const parent = __rspack_external_path.dirname(currentPath);
|
|
989
|
+
if (parent === currentPath) break;
|
|
990
|
+
currentPath = parent;
|
|
991
|
+
}
|
|
992
|
+
}
|
|
993
|
+
function isSameInstalledPackage(resolvedPath, expectedInstalledPath) {
|
|
994
|
+
const resolvedPackageDir = findOwningPackageDir(resolvedPath);
|
|
995
|
+
const expectedPackageDir = findOwningPackageDir(expectedInstalledPath);
|
|
996
|
+
if (resolvedPackageDir && expectedPackageDir) return resolveRealPathSafe(resolvedPackageDir) === resolveRealPathSafe(expectedPackageDir);
|
|
997
|
+
return resolveRealPathSafe(resolvedPath) === resolveRealPathSafe(expectedInstalledPath);
|
|
998
|
+
}
|
|
999
|
+
function evaluateModuleContextRule(rule, fromPackagePath, options) {
|
|
1000
|
+
try {
|
|
1001
|
+
const req = createRequire(fromPackagePath);
|
|
1002
|
+
const resolvedPeer = req.resolve(rule.packageId);
|
|
1003
|
+
if (options?.expectedInstalledPath && !isSameInstalledPackage(resolvedPeer, options.expectedInstalledPath)) return rule.packageId;
|
|
1004
|
+
if ('module-context-load' === rule.type) req(rule.packageId);
|
|
1005
|
+
return;
|
|
1006
|
+
} catch {
|
|
1007
|
+
return rule.packageId;
|
|
1008
|
+
}
|
|
1009
|
+
}
|
|
1010
|
+
function getContractVerificationFailuresFromKnownLocations(contract, projectPath) {
|
|
1011
|
+
const resolvedByPackage = new Map();
|
|
1012
|
+
const resolvePackage = (packageId)=>{
|
|
1013
|
+
if (!resolvedByPackage.has(packageId)) resolvedByPackage.set(packageId, resolveFromKnownLocations(packageId, projectPath));
|
|
1014
|
+
return resolvedByPackage.get(packageId);
|
|
1015
|
+
};
|
|
1016
|
+
const failures = [];
|
|
1017
|
+
for (const rule of contract.verificationRules){
|
|
1018
|
+
if ('install-root' === rule.type) {
|
|
1019
|
+
if (!resolvePackage(rule.packageId)) failures.push(rule.packageId);
|
|
1020
|
+
continue;
|
|
1021
|
+
}
|
|
1022
|
+
const fromPackagePath = resolvePackage(rule.fromPackage);
|
|
1023
|
+
if (!fromPackagePath) {
|
|
1024
|
+
failures.push(rule.fromPackage);
|
|
1025
|
+
continue;
|
|
1026
|
+
}
|
|
1027
|
+
const failure = evaluateModuleContextRule(rule, fromPackagePath);
|
|
1028
|
+
if (!(failure && declaresDependency(projectPath, failure))) {
|
|
1029
|
+
if (failure) failures.push(failure);
|
|
1030
|
+
}
|
|
1031
|
+
}
|
|
1032
|
+
return dedupeFailures(failures);
|
|
1033
|
+
}
|
|
1034
|
+
function buildDiagnostics(input) {
|
|
1035
|
+
const bases = getResolutionBases(input.projectPath);
|
|
1036
|
+
return {
|
|
1037
|
+
contractId: input.contract?.id || null,
|
|
1038
|
+
integration: input.integration,
|
|
1039
|
+
dependencyId: input.dependencyId,
|
|
1040
|
+
projectPath: input.projectPath,
|
|
1041
|
+
installDependencies: input.installDependencies,
|
|
1042
|
+
verifyPackageIds: input.verifyPackageIds,
|
|
1043
|
+
resolutionBases: bases
|
|
1044
|
+
};
|
|
1045
|
+
}
|
|
1046
|
+
function resolveOptionalDependencySync(dependencyId, projectPath) {
|
|
1047
|
+
const resolved = resolveFromKnownLocations(dependencyId, projectPath);
|
|
1048
|
+
if (resolved) return resolved;
|
|
1049
|
+
const bases = getResolutionBases(projectPath);
|
|
1050
|
+
throw new Error(`[CSS] ${dependencyId} could not be resolved. Searched: ${bases.join(', ')}`);
|
|
1051
|
+
}
|
|
1052
|
+
async function ensureOptionalPackageResolved(input) {
|
|
1053
|
+
const contract = getVerificationContract(input);
|
|
1054
|
+
const missing = getContractVerificationFailuresFromKnownLocations(contract, input.projectPath);
|
|
1055
|
+
const resolved = resolveFromKnownLocations(input.dependencyId, input.projectPath);
|
|
1056
|
+
if (resolved && 0 === missing.length) return resolved;
|
|
1057
|
+
const diagnostics = buildDiagnostics({
|
|
1058
|
+
integration: input.integration,
|
|
1059
|
+
dependencyId: input.dependencyId,
|
|
1060
|
+
projectPath: input.projectPath,
|
|
1061
|
+
contract,
|
|
1062
|
+
installDependencies: contract.installPackages,
|
|
1063
|
+
verifyPackageIds: contract.installPackages
|
|
1064
|
+
});
|
|
1065
|
+
throw new Error(`[${input.integration}] ${input.dependencyId} could not be resolved.` + (missing.length > 0 ? ` Missing or invalid packages: ${missing.join(', ')}.` : '') + '\n' + JSON.stringify({
|
|
1066
|
+
...diagnostics,
|
|
1067
|
+
missing
|
|
1068
|
+
}, null, 2));
|
|
1069
|
+
}
|
|
1070
|
+
function resolveOptionalPackageWithoutInstall(input) {
|
|
1071
|
+
const contract = getVerificationContract(input);
|
|
1072
|
+
const resolved = resolveFromKnownLocations(input.dependencyId, input.projectPath);
|
|
1073
|
+
const missingPeerDeps = getContractVerificationFailuresFromKnownLocations(contract, input.projectPath);
|
|
1074
|
+
if (resolved && 0 === missingPeerDeps.length) return resolved;
|
|
1075
|
+
const diagnostics = buildDiagnostics({
|
|
1076
|
+
integration: input.integration,
|
|
1077
|
+
dependencyId: input.dependencyId,
|
|
1078
|
+
projectPath: input.projectPath,
|
|
1079
|
+
contract,
|
|
1080
|
+
installDependencies: contract.installPackages,
|
|
1081
|
+
verifyPackageIds: contract.installPackages
|
|
1082
|
+
});
|
|
1083
|
+
throw new Error(`[${input.integration}] ${input.dependencyId} could not be resolved from the project or extension-develop.\n` + JSON.stringify({
|
|
1084
|
+
...diagnostics,
|
|
1085
|
+
missingPeerDeps,
|
|
1086
|
+
expectation: 'Run optional dependency preflight or reinstall extension-develop.'
|
|
1087
|
+
}, null, 2));
|
|
1088
|
+
}
|
|
1089
|
+
async function ensureOptionalModuleLoaded(input) {
|
|
1090
|
+
const resolvedPath = await ensureOptionalPackageResolved(input);
|
|
1091
|
+
const candidateBases = getResolutionBases(input.projectPath);
|
|
1092
|
+
let loaded;
|
|
1093
|
+
let didLoad = false;
|
|
1094
|
+
let lastLoadError;
|
|
1095
|
+
for (const basePath of candidateBases){
|
|
1096
|
+
const req = createRequire(optional_deps_resolver_packageJsonPath(basePath));
|
|
1097
|
+
const candidateModuleIds = [
|
|
1098
|
+
input.dependencyId,
|
|
1099
|
+
resolvedPath
|
|
1100
|
+
];
|
|
1101
|
+
for (const candidateModuleId of candidateModuleIds)try {
|
|
1102
|
+
loaded = req(candidateModuleId);
|
|
1103
|
+
didLoad = true;
|
|
1104
|
+
break;
|
|
1105
|
+
} catch (error) {
|
|
1106
|
+
lastLoadError = error;
|
|
1107
|
+
}
|
|
1108
|
+
if (didLoad) break;
|
|
1109
|
+
}
|
|
1110
|
+
if (!didLoad) try {
|
|
1111
|
+
loaded = require(resolvedPath);
|
|
1112
|
+
didLoad = true;
|
|
1113
|
+
} catch (directRequireError) {
|
|
1114
|
+
lastLoadError = directRequireError;
|
|
1115
|
+
}
|
|
1116
|
+
if (!didLoad) {
|
|
1117
|
+
const diagnostics = {
|
|
1118
|
+
...buildDiagnostics({
|
|
1119
|
+
integration: input.integration,
|
|
1120
|
+
dependencyId: input.dependencyId,
|
|
1121
|
+
projectPath: input.projectPath,
|
|
1122
|
+
installDependencies: input.installDependencies || [
|
|
1123
|
+
input.dependencyId
|
|
1124
|
+
],
|
|
1125
|
+
verifyPackageIds: input.verifyPackageIds || input.installDependencies || [
|
|
1126
|
+
input.dependencyId
|
|
1127
|
+
]
|
|
1128
|
+
}),
|
|
1129
|
+
resolvedPath,
|
|
1130
|
+
loadError: lastLoadError instanceof Error ? lastLoadError.message : String(lastLoadError)
|
|
1131
|
+
};
|
|
1132
|
+
throw new Error(`[${input.integration}] ${input.dependencyId} could not be loaded after it resolved.\n` + JSON.stringify(diagnostics, null, 2));
|
|
1133
|
+
}
|
|
1134
|
+
return input.moduleAdapter ? input.moduleAdapter(loaded) : loaded;
|
|
1135
|
+
}
|
|
1136
|
+
function loadOptionalModuleWithoutInstall(input) {
|
|
1137
|
+
const resolvedPath = resolveOptionalPackageWithoutInstall(input);
|
|
1138
|
+
const candidateBases = getResolutionBases(input.projectPath);
|
|
1139
|
+
let loaded;
|
|
1140
|
+
let didLoad = false;
|
|
1141
|
+
let lastLoadError;
|
|
1142
|
+
for (const basePath of candidateBases){
|
|
1143
|
+
const req = createRequire(optional_deps_resolver_packageJsonPath(basePath));
|
|
1144
|
+
const candidateModuleIds = [
|
|
1145
|
+
input.dependencyId,
|
|
1146
|
+
resolvedPath
|
|
1147
|
+
];
|
|
1148
|
+
for (const candidateModuleId of candidateModuleIds)try {
|
|
1149
|
+
loaded = req(candidateModuleId);
|
|
1150
|
+
didLoad = true;
|
|
1151
|
+
break;
|
|
1152
|
+
} catch (error) {
|
|
1153
|
+
lastLoadError = error;
|
|
1154
|
+
}
|
|
1155
|
+
if (didLoad) break;
|
|
1156
|
+
}
|
|
1157
|
+
if (!didLoad) try {
|
|
1158
|
+
loaded = require(resolvedPath);
|
|
1159
|
+
didLoad = true;
|
|
1160
|
+
} catch (directRequireError) {
|
|
1161
|
+
lastLoadError = directRequireError;
|
|
1162
|
+
}
|
|
1163
|
+
if (!didLoad) throw new Error(`[${input.integration}] ${input.dependencyId} could not be loaded after resolving.\n` + JSON.stringify({
|
|
1164
|
+
resolvedPath,
|
|
1165
|
+
loadError: lastLoadError instanceof Error ? lastLoadError.message : String(lastLoadError)
|
|
1166
|
+
}, null, 2));
|
|
1167
|
+
return input.moduleAdapter ? input.moduleAdapter(loaded) : loaded;
|
|
1168
|
+
}
|
|
1169
|
+
async function optional_deps_resolver_ensureOptionalContractPackageResolved(input) {
|
|
1170
|
+
const contract = getOptionalDependencyContract(input.contractId);
|
|
1171
|
+
return ensureOptionalPackageResolved({
|
|
1172
|
+
integration: contract.integration,
|
|
1173
|
+
projectPath: input.projectPath,
|
|
1174
|
+
dependencyId: input.dependencyId,
|
|
1175
|
+
contract
|
|
1176
|
+
});
|
|
1177
|
+
}
|
|
1178
|
+
async function ensureOptionalContractModuleLoaded(input) {
|
|
1179
|
+
const contract = getOptionalDependencyContract(input.contractId);
|
|
1180
|
+
return ensureOptionalModuleLoaded({
|
|
1181
|
+
integration: contract.integration,
|
|
1182
|
+
projectPath: input.projectPath,
|
|
1183
|
+
dependencyId: input.dependencyId,
|
|
1184
|
+
contract,
|
|
1185
|
+
moduleAdapter: input.moduleAdapter
|
|
1186
|
+
});
|
|
1187
|
+
}
|
|
1188
|
+
function resolveOptionalContractPackageWithoutInstall(input) {
|
|
1189
|
+
const contract = getOptionalDependencyContract(input.contractId);
|
|
1190
|
+
return resolveOptionalPackageWithoutInstall({
|
|
1191
|
+
integration: contract.integration,
|
|
1192
|
+
projectPath: input.projectPath,
|
|
1193
|
+
dependencyId: input.dependencyId,
|
|
1194
|
+
contract
|
|
1195
|
+
});
|
|
1196
|
+
}
|
|
1197
|
+
function loadOptionalContractModuleWithoutInstall(input) {
|
|
1198
|
+
const contract = getOptionalDependencyContract(input.contractId);
|
|
1199
|
+
return loadOptionalModuleWithoutInstall({
|
|
1200
|
+
integration: contract.integration,
|
|
1201
|
+
projectPath: input.projectPath,
|
|
1202
|
+
dependencyId: input.dependencyId,
|
|
1203
|
+
contract,
|
|
1204
|
+
moduleAdapter: input.moduleAdapter
|
|
1205
|
+
});
|
|
1206
|
+
}
|
|
1207
|
+
let hasShownUserMessage = false;
|
|
1208
|
+
function findNearestPackageJsonDirectory(startPath) {
|
|
1209
|
+
let currentDirectory = startPath;
|
|
1210
|
+
const maxDepth = 6;
|
|
1211
|
+
for(let i = 0; i < maxDepth; i++){
|
|
1212
|
+
const candidate = __rspack_external_path.join(currentDirectory, 'package.json');
|
|
1213
|
+
if (__rspack_external_fs.existsSync(candidate)) return currentDirectory;
|
|
1214
|
+
const parentDirectory = __rspack_external_path.dirname(currentDirectory);
|
|
1215
|
+
if (parentDirectory === currentDirectory) break;
|
|
1216
|
+
currentDirectory = parentDirectory;
|
|
1217
|
+
}
|
|
1218
|
+
}
|
|
1219
|
+
function hasTypeScriptSourceFiles(projectPath) {
|
|
1220
|
+
try {
|
|
1221
|
+
const entries = __rspack_external_fs.readdirSync(projectPath, {
|
|
1222
|
+
withFileTypes: true
|
|
1223
|
+
});
|
|
1224
|
+
return entries.some((entry)=>{
|
|
1225
|
+
if (entry.isFile()) {
|
|
1226
|
+
const name = entry.name;
|
|
1227
|
+
if (!/\.(ts|tsx|mts|mtsx)$/i.test(name)) return false;
|
|
1228
|
+
if (/\.(d\.ts|d\.mts|d\.mtsx)$/i.test(name)) return false;
|
|
1229
|
+
if (/\.(spec|test)\.(ts|tsx|mts|mtsx)$/i.test(name)) return false;
|
|
1230
|
+
return true;
|
|
1231
|
+
}
|
|
1232
|
+
if (entry.isDirectory()) {
|
|
1233
|
+
if (![
|
|
1234
|
+
'src',
|
|
1235
|
+
'content',
|
|
1236
|
+
'sidebar',
|
|
1237
|
+
'background'
|
|
1238
|
+
].includes(entry.name)) return false;
|
|
1239
|
+
const sub = __rspack_external_path.join(projectPath, entry.name);
|
|
1240
|
+
return hasTypeScriptSourceFiles(sub);
|
|
1241
|
+
}
|
|
1242
|
+
return false;
|
|
1243
|
+
});
|
|
1244
|
+
} catch {
|
|
1245
|
+
return false;
|
|
1246
|
+
}
|
|
1247
|
+
}
|
|
1248
|
+
function isUsingTypeScript(projectPath) {
|
|
1249
|
+
const packageJsonDirectory = findNearestPackageJsonDirectory(projectPath);
|
|
1250
|
+
const tsConfigFilePath = getUserTypeScriptConfigFile(projectPath);
|
|
1251
|
+
const packageJson = packageJsonDirectory ? parseJsonSafe(__rspack_external_fs.readFileSync(__rspack_external_path.join(packageJsonDirectory, 'package.json'), 'utf8')) : void 0;
|
|
1252
|
+
const TypeScriptAsDevDep = packageJson?.devDependencies?.typescript;
|
|
1253
|
+
const TypeScriptAsDep = packageJson?.dependencies?.typescript;
|
|
1254
|
+
const hasTsFiles = hasTypeScriptSourceFiles(projectPath);
|
|
1255
|
+
if (!hasShownUserMessage) {
|
|
1256
|
+
if (TypeScriptAsDevDep || TypeScriptAsDep || hasTsFiles) if (tsConfigFilePath) {
|
|
1257
|
+
if ('true' === process.env.EXTENSION_AUTHOR_MODE) console.log(`${pintor.brightMagenta('⏵⏵⏵ Author says')} ${isUsingIntegration('TypeScript')}`);
|
|
1258
|
+
} else if (hasTsFiles) {
|
|
1259
|
+
const errorMessage = '[Extension.js] Missing tsconfig.json next to package.json. Create one to use TypeScript.';
|
|
1260
|
+
throw new Error(errorMessage);
|
|
1261
|
+
} else {
|
|
1262
|
+
console.log(creatingTSConfig());
|
|
1263
|
+
writeTsConfig(projectPath);
|
|
1264
|
+
}
|
|
1265
|
+
hasShownUserMessage = true;
|
|
1266
|
+
}
|
|
1267
|
+
return !!tsConfigFilePath && !!(TypeScriptAsDevDep || TypeScriptAsDep || hasTsFiles);
|
|
1268
|
+
}
|
|
1269
|
+
function defaultTypeScriptConfig(projectPath, _opts) {
|
|
1270
|
+
return {
|
|
1271
|
+
compilerOptions: {
|
|
1272
|
+
allowJs: true,
|
|
1273
|
+
allowSyntheticDefaultImports: true,
|
|
1274
|
+
esModuleInterop: true,
|
|
1275
|
+
forceConsistentCasingInFileNames: true,
|
|
1276
|
+
jsx: isUsingJSFramework(projectPath) ? 'react-jsx' : 'preserve',
|
|
1277
|
+
lib: [
|
|
1278
|
+
'dom',
|
|
1279
|
+
'dom.iterable',
|
|
1280
|
+
'esnext'
|
|
1281
|
+
],
|
|
1282
|
+
moduleResolution: 'node',
|
|
1283
|
+
module: 'esnext',
|
|
1284
|
+
resolveJsonModule: true,
|
|
1285
|
+
strict: true,
|
|
1286
|
+
target: 'esnext',
|
|
1287
|
+
isolatedModules: false,
|
|
1288
|
+
skipLibCheck: true
|
|
1289
|
+
},
|
|
1290
|
+
exclude: [
|
|
1291
|
+
'node_modules',
|
|
1292
|
+
'dist'
|
|
1293
|
+
]
|
|
1294
|
+
};
|
|
1295
|
+
}
|
|
1296
|
+
function getUserTypeScriptConfigFile(projectPath) {
|
|
1297
|
+
const pkgDir = findNearestPackageJsonDirectory(projectPath);
|
|
1298
|
+
if (pkgDir) {
|
|
1299
|
+
const tsconfigPath = __rspack_external_path.join(pkgDir, 'tsconfig.json');
|
|
1300
|
+
if (__rspack_external_fs.existsSync(tsconfigPath)) return tsconfigPath;
|
|
1301
|
+
}
|
|
1302
|
+
}
|
|
1303
|
+
function writeTsConfig(projectPath) {
|
|
1304
|
+
__rspack_external_fs.writeFileSync(__rspack_external_path.join(projectPath, 'tsconfig.json'), JSON.stringify(defaultTypeScriptConfig(projectPath, {
|
|
1305
|
+
mode: 'development'
|
|
1306
|
+
}), null, 2));
|
|
1307
|
+
}
|
|
1308
|
+
async function extensionDev(pathOrRemoteUrl, devOptions) {
|
|
1309
|
+
let browsersPlugin;
|
|
1310
|
+
let emitter = new BuildEmitter();
|
|
1311
|
+
const projectStructure = await getProjectStructure(pathOrRemoteUrl);
|
|
1312
|
+
try {
|
|
1313
|
+
const isAuthor = 'true' === process.env.EXTENSION_AUTHOR_MODE;
|
|
1314
|
+
const debug = isAuthor;
|
|
1315
|
+
const { manifestDir, packageJsonDir } = getDirs(projectStructure);
|
|
1316
|
+
await ensureDevelopArtifacts();
|
|
1317
|
+
if (false !== devOptions.install) await ensureUserProjectDependencies(packageJsonDir);
|
|
1318
|
+
if (isUsingTypeScript(manifestDir)) await generateExtensionTypes(manifestDir, packageJsonDir);
|
|
1319
|
+
if (projectStructure.packageJsonPath) assertNoManagedDependencyConflicts(projectStructure.packageJsonPath, manifestDir);
|
|
1320
|
+
const browser = normalizeBrowser(devOptions.browser || 'chrome', devOptions.chromiumBinary, devOptions.geckoBinary || devOptions.firefoxBinary);
|
|
1321
|
+
const geckoBinary = devOptions.geckoBinary || devOptions.firefoxBinary;
|
|
1322
|
+
if (debug) {
|
|
1323
|
+
console.log(debugDirs(manifestDir, packageJsonDir));
|
|
1324
|
+
console.log(debugBrowser(browser, devOptions.chromiumBinary, geckoBinary));
|
|
1325
|
+
}
|
|
1326
|
+
const browserConfig = await loadBrowserConfig(packageJsonDir, browser);
|
|
1327
|
+
const commandConfig = await loadCommandConfig(packageJsonDir, 'dev');
|
|
1328
|
+
const merged = {
|
|
1329
|
+
...sanitize(browserConfig),
|
|
1330
|
+
...sanitize(commandConfig),
|
|
1331
|
+
...sanitize(devOptions)
|
|
1332
|
+
};
|
|
1333
|
+
if (devOptions.launcher && !devOptions.noBrowser) {
|
|
1334
|
+
browsersPlugin = new BrowsersPlugin({
|
|
1335
|
+
launcher: devOptions.launcher,
|
|
1336
|
+
browserOptions: {
|
|
1337
|
+
browser,
|
|
1338
|
+
mode: 'development',
|
|
1339
|
+
enableDevtools: true,
|
|
1340
|
+
noOpen: merged.noOpen,
|
|
1341
|
+
profile: merged.profile,
|
|
1342
|
+
persistProfile: merged.persistProfile,
|
|
1343
|
+
preferences: merged.preferences,
|
|
1344
|
+
browserFlags: merged.browserFlags,
|
|
1345
|
+
excludeBrowserFlags: merged.excludeBrowserFlags,
|
|
1346
|
+
startingUrl: merged.startingUrl,
|
|
1347
|
+
chromiumBinary: merged.chromiumBinary,
|
|
1348
|
+
geckoBinary: merged.geckoBinary || merged.firefoxBinary,
|
|
1349
|
+
port: merged.port,
|
|
1350
|
+
source: merged.source,
|
|
1351
|
+
watchSource: merged.watchSource,
|
|
1352
|
+
sourceFormat: merged.sourceFormat,
|
|
1353
|
+
sourceSummary: merged.sourceSummary,
|
|
1354
|
+
sourceMeta: merged.sourceMeta,
|
|
1355
|
+
sourceProbe: merged.sourceProbe,
|
|
1356
|
+
sourceTree: merged.sourceTree,
|
|
1357
|
+
sourceConsole: merged.sourceConsole,
|
|
1358
|
+
sourceDom: merged.sourceDom,
|
|
1359
|
+
sourceMaxBytes: merged.sourceMaxBytes,
|
|
1360
|
+
sourceRedact: merged.sourceRedact,
|
|
1361
|
+
sourceIncludeShadow: merged.sourceIncludeShadow,
|
|
1362
|
+
sourceDiff: merged.sourceDiff,
|
|
1363
|
+
logLevel: merged.logLevel,
|
|
1364
|
+
logContexts: merged.logContexts,
|
|
1365
|
+
logFormat: merged.logFormat,
|
|
1366
|
+
logTimestamps: merged.logTimestamps,
|
|
1367
|
+
logColor: merged.logColor,
|
|
1368
|
+
logUrl: merged.logUrl,
|
|
1369
|
+
logTab: merged.logTab
|
|
1370
|
+
}
|
|
1371
|
+
});
|
|
1372
|
+
emitter = browsersPlugin.emitter;
|
|
1373
|
+
}
|
|
1374
|
+
if ('true' === process.env.EXTENSION_DEV_DRY_RUN) return emitter;
|
|
1375
|
+
const { devServer } = await import("./0~dev-server.mjs");
|
|
1376
|
+
await devServer(projectStructure, {
|
|
1377
|
+
...devOptions,
|
|
1378
|
+
mode: 'development',
|
|
1379
|
+
browser,
|
|
1380
|
+
geckoBinary,
|
|
1381
|
+
browsersPlugin
|
|
1382
|
+
});
|
|
1383
|
+
return emitter;
|
|
1384
|
+
} catch (error) {
|
|
1385
|
+
console.error(error);
|
|
1386
|
+
process.exit(1);
|
|
1387
|
+
}
|
|
1388
|
+
}
|
|
1389
|
+
export { BuildEmitter, ensureOptionalContractModuleLoaded, extensionBuild, extensionDev, getUserTypeScriptConfigFile, hasDependency, isUsingCustomLoader, isUsingIntegration, isUsingTypeScript, jsFrameworksConfigsDetected, jsFrameworksHmrSummary, jsFrameworksIntegrationsEnabled, loadOptionalContractModuleWithoutInstall, optional_deps_resolver_ensureOptionalContractPackageResolved, parseJsonSafe, resolveDevelopDistFile, resolveDevelopInstallRoot, resolveOptionalContractPackageWithoutInstall, resolveOptionalDependencySync };
|