@hirarijs/loader 1.0.9 → 1.0.10
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/chunk-2YMWZ4IT.js +289 -0
- package/dist/chunk-B6QICL5V.js +293 -0
- package/dist/chunk-J2O76MZJ.js +15 -0
- package/dist/chunk-JPHIWQ7S.js +15 -0
- package/dist/chunk-O7SYNOVB.js +296 -0
- package/dist/chunk-XTXLI7WO.js +15 -0
- package/dist/index.cjs +19 -19
- package/dist/index.d.cts +7 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +2 -2
- package/dist/loader.cjs +22 -26
- package/dist/loader.js +1 -1
- package/dist/register-auto.cjs +19 -19
- package/dist/register-auto.js +2 -2
- package/dist/register.cjs +19 -19
- package/dist/register.js +2 -2
- package/package.json +1 -1
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
// src/config.ts
|
|
2
|
+
import fs from "fs";
|
|
3
|
+
import path from "path";
|
|
4
|
+
var DEFAULT_CONFIG = {
|
|
5
|
+
format: "cjs",
|
|
6
|
+
plugins: [
|
|
7
|
+
"@hirarijs/loader-ts",
|
|
8
|
+
"@hirarijs/loader-tsx",
|
|
9
|
+
"@hirarijs/loader-vue",
|
|
10
|
+
"@hirarijs/loader-cjs-interop"
|
|
11
|
+
]
|
|
12
|
+
};
|
|
13
|
+
function loadHirariConfig(cwd = process.cwd()) {
|
|
14
|
+
const configPath = path.join(cwd, "hirari.json");
|
|
15
|
+
if (!fs.existsSync(configPath)) {
|
|
16
|
+
return { ...DEFAULT_CONFIG };
|
|
17
|
+
}
|
|
18
|
+
const raw = fs.readFileSync(configPath, "utf8");
|
|
19
|
+
let parsed;
|
|
20
|
+
try {
|
|
21
|
+
parsed = JSON.parse(raw);
|
|
22
|
+
} catch (error) {
|
|
23
|
+
throw new Error(`Failed to parse hirari.json: ${error.message}`);
|
|
24
|
+
}
|
|
25
|
+
const loaderConfig = parsed.loader || {};
|
|
26
|
+
return {
|
|
27
|
+
...DEFAULT_CONFIG,
|
|
28
|
+
...loaderConfig,
|
|
29
|
+
plugins: loaderConfig.plugins?.length ? loaderConfig.plugins : DEFAULT_CONFIG.plugins
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
function getFormat(config) {
|
|
33
|
+
return config.format === "esm" ? "esm" : "cjs";
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// src/constants.ts
|
|
37
|
+
var IMPORT_META_URL_VARIABLE = "__hirari_loader_import_meta_url__";
|
|
38
|
+
|
|
39
|
+
// src/plugin-manager.ts
|
|
40
|
+
import { spawnSync } from "child_process";
|
|
41
|
+
import fs2 from "fs";
|
|
42
|
+
import path2 from "path";
|
|
43
|
+
import { createRequire } from "module";
|
|
44
|
+
var PACKAGE_MANAGERS = [
|
|
45
|
+
{ lock: "pnpm-lock.yaml", command: "pnpm", args: ["add"] },
|
|
46
|
+
{ lock: "yarn.lock", command: "yarn", args: ["add"] },
|
|
47
|
+
{ lock: "package-lock.json", command: "npm", args: ["install"] },
|
|
48
|
+
{ lock: "npm-shrinkwrap.json", command: "npm", args: ["install"] }
|
|
49
|
+
];
|
|
50
|
+
function detectPackageManager(cwd) {
|
|
51
|
+
for (const pm of PACKAGE_MANAGERS) {
|
|
52
|
+
if (fs2.existsSync(path2.join(cwd, pm.lock))) return pm;
|
|
53
|
+
}
|
|
54
|
+
return { command: "npm", args: ["install"] };
|
|
55
|
+
}
|
|
56
|
+
function tryRequire(moduleId, cwd) {
|
|
57
|
+
const req = createRequire(path2.join(cwd, "noop.js"));
|
|
58
|
+
const loaded = req(moduleId);
|
|
59
|
+
return loaded && (loaded.default || loaded);
|
|
60
|
+
}
|
|
61
|
+
function install(pkg, cwd) {
|
|
62
|
+
const pm = detectPackageManager(cwd);
|
|
63
|
+
const result = spawnSync(pm.command, [...pm.args, pkg], {
|
|
64
|
+
cwd,
|
|
65
|
+
stdio: "inherit",
|
|
66
|
+
env: process.env
|
|
67
|
+
});
|
|
68
|
+
if (result.error) {
|
|
69
|
+
throw result.error;
|
|
70
|
+
}
|
|
71
|
+
if (result.status !== 0) {
|
|
72
|
+
throw new Error(`${pm.command} ${pm.args.join(" ")} ${pkg} failed`);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
function resolvePlugins(config, cwd) {
|
|
76
|
+
const plugins = [];
|
|
77
|
+
for (const pluginName of config.plugins || []) {
|
|
78
|
+
let loaded = null;
|
|
79
|
+
try {
|
|
80
|
+
loaded = tryRequire(pluginName, cwd);
|
|
81
|
+
} catch (error) {
|
|
82
|
+
if (config.autoInstall) {
|
|
83
|
+
console.log(`[hirari-loader] installing missing plugin ${pluginName}`);
|
|
84
|
+
install(pluginName, cwd);
|
|
85
|
+
loaded = tryRequire(pluginName, cwd);
|
|
86
|
+
} else {
|
|
87
|
+
throw new Error(
|
|
88
|
+
`Plugin "${pluginName}" not found. Enable autoInstall or install manually.`
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
if (!loaded) continue;
|
|
93
|
+
plugins.push({
|
|
94
|
+
plugin: loaded,
|
|
95
|
+
options: config.pluginOptions?.[pluginName]
|
|
96
|
+
});
|
|
97
|
+
if (config.debug) {
|
|
98
|
+
console.log(`[hirari-loader] loaded plugin ${pluginName}`);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return plugins;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// src/runtime.ts
|
|
105
|
+
import fs3 from "fs";
|
|
106
|
+
import module from "module";
|
|
107
|
+
import path3 from "path";
|
|
108
|
+
import { fileURLToPath, pathToFileURL } from "url";
|
|
109
|
+
import { addHook } from "pirates";
|
|
110
|
+
import * as sourceMapSupport from "source-map-support";
|
|
111
|
+
var map = {};
|
|
112
|
+
var EXTENSION_CANDIDATES = [
|
|
113
|
+
".ts",
|
|
114
|
+
".mts",
|
|
115
|
+
".cts",
|
|
116
|
+
".tsx",
|
|
117
|
+
".jsx",
|
|
118
|
+
".vue",
|
|
119
|
+
".js",
|
|
120
|
+
".mjs",
|
|
121
|
+
".cjs"
|
|
122
|
+
];
|
|
123
|
+
function installSourceMaps() {
|
|
124
|
+
sourceMapSupport.install({
|
|
125
|
+
handleUncaughtExceptions: false,
|
|
126
|
+
environment: "node",
|
|
127
|
+
retrieveSourceMap(file) {
|
|
128
|
+
if (map[file]) {
|
|
129
|
+
return { url: file, map: map[file] };
|
|
130
|
+
}
|
|
131
|
+
return null;
|
|
132
|
+
}
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
var toNodeLoaderFormat = (format) => format === "esm" ? "module" : "commonjs";
|
|
136
|
+
function createRuntime(cwd = process.cwd()) {
|
|
137
|
+
const loaderConfig = loadHirariConfig(cwd);
|
|
138
|
+
const resolvedPlugins = resolvePlugins(loaderConfig, cwd);
|
|
139
|
+
installSourceMaps();
|
|
140
|
+
return {
|
|
141
|
+
cwd,
|
|
142
|
+
loaderConfig,
|
|
143
|
+
resolvedPlugins,
|
|
144
|
+
format: getFormat(loaderConfig)
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
function applyPlugin(code, filename, runtime) {
|
|
148
|
+
for (const match of runtime.resolvedPlugins) {
|
|
149
|
+
if (!match.plugin.match(filename)) continue;
|
|
150
|
+
const ctx = {
|
|
151
|
+
format: runtime.format,
|
|
152
|
+
loaderConfig: runtime.loaderConfig,
|
|
153
|
+
pluginOptions: match.options
|
|
154
|
+
};
|
|
155
|
+
const result = match.plugin.transform(code, filename, ctx);
|
|
156
|
+
if (runtime.loaderConfig.debug) {
|
|
157
|
+
console.log(`[hirari-loader][${match.plugin.name}] compiled ${filename}`);
|
|
158
|
+
}
|
|
159
|
+
if (result.continue) {
|
|
160
|
+
continue;
|
|
161
|
+
}
|
|
162
|
+
if (result.map) {
|
|
163
|
+
map[filename] = result.map;
|
|
164
|
+
}
|
|
165
|
+
return result;
|
|
166
|
+
}
|
|
167
|
+
if (runtime.loaderConfig.debug) {
|
|
168
|
+
console.log(`[hirari-loader] no plugin matched ${filename}`);
|
|
169
|
+
}
|
|
170
|
+
return { code };
|
|
171
|
+
}
|
|
172
|
+
function pickPlugin(filename, runtime) {
|
|
173
|
+
return runtime.resolvedPlugins.find(({ plugin }) => plugin.match(filename));
|
|
174
|
+
}
|
|
175
|
+
function collectExtensions(plugins) {
|
|
176
|
+
const set = /* @__PURE__ */ new Set();
|
|
177
|
+
for (const { plugin } of plugins) {
|
|
178
|
+
plugin.extensions.forEach((ext) => set.add(ext));
|
|
179
|
+
}
|
|
180
|
+
return Array.from(set);
|
|
181
|
+
}
|
|
182
|
+
function registerRequireHooks(runtime) {
|
|
183
|
+
const extensions = collectExtensions(runtime.resolvedPlugins);
|
|
184
|
+
const compile = (code, filename) => {
|
|
185
|
+
const result = applyPlugin(code, filename, runtime);
|
|
186
|
+
const banner = `const ${IMPORT_META_URL_VARIABLE} = require('url').pathToFileURL(__filename).href;`;
|
|
187
|
+
if (!result.code.includes(IMPORT_META_URL_VARIABLE)) {
|
|
188
|
+
return `${banner}${result.code}`;
|
|
189
|
+
}
|
|
190
|
+
return result.code;
|
|
191
|
+
};
|
|
192
|
+
const revert = addHook(compile, {
|
|
193
|
+
exts: extensions,
|
|
194
|
+
ignoreNodeModules: false
|
|
195
|
+
});
|
|
196
|
+
const extensionsObj = module.Module._extensions;
|
|
197
|
+
const jsHandler = extensionsObj[".js"];
|
|
198
|
+
extensionsObj[".js"] = function(mod, filename) {
|
|
199
|
+
try {
|
|
200
|
+
return jsHandler.call(this, mod, filename);
|
|
201
|
+
} catch (error) {
|
|
202
|
+
if (error && error.code === "ERR_REQUIRE_ESM") {
|
|
203
|
+
const src = fs3.readFileSync(filename, "utf8");
|
|
204
|
+
const result = applyPlugin(src, filename, runtime);
|
|
205
|
+
mod._compile(result.code, filename);
|
|
206
|
+
return;
|
|
207
|
+
}
|
|
208
|
+
throw error;
|
|
209
|
+
}
|
|
210
|
+
};
|
|
211
|
+
return () => {
|
|
212
|
+
revert();
|
|
213
|
+
extensionsObj[".js"] = jsHandler;
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
async function loaderResolve(specifier, context, next, runtime) {
|
|
217
|
+
const parentUrl = context && context.parentURL;
|
|
218
|
+
const baseDir = parentUrl && typeof parentUrl === "string" && parentUrl.startsWith("file:") ? path3.dirname(fileURLToPath(parentUrl)) : process.cwd();
|
|
219
|
+
const tryResolve = (basePath, note) => {
|
|
220
|
+
for (const ext2 of EXTENSION_CANDIDATES) {
|
|
221
|
+
const candidate = basePath + ext2;
|
|
222
|
+
if (fs3.existsSync(candidate) && fs3.statSync(candidate).isFile()) {
|
|
223
|
+
const url = pathToFileURL(candidate).href;
|
|
224
|
+
if (runtime.loaderConfig.debug) {
|
|
225
|
+
console.log(`[hirari-loader] resolve ${note} ${specifier} -> ${url}`);
|
|
226
|
+
}
|
|
227
|
+
return { url, shortCircuit: true };
|
|
228
|
+
}
|
|
229
|
+
const indexCandidate = path3.join(basePath, "index" + ext2);
|
|
230
|
+
if (fs3.existsSync(indexCandidate) && fs3.statSync(indexCandidate).isFile()) {
|
|
231
|
+
const url = pathToFileURL(indexCandidate).href;
|
|
232
|
+
if (runtime.loaderConfig.debug) {
|
|
233
|
+
console.log(`[hirari-loader] resolve ${note} ${specifier} -> ${url}`);
|
|
234
|
+
}
|
|
235
|
+
return { url, shortCircuit: true };
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
return null;
|
|
239
|
+
};
|
|
240
|
+
if (!path3.extname(specifier) && (specifier.startsWith("./") || specifier.startsWith("../") || specifier.startsWith("/") || specifier.startsWith("file:")) && !specifier.startsWith("node:")) {
|
|
241
|
+
const basePath = specifier.startsWith("file:") ? fileURLToPath(specifier) : specifier.startsWith("/") ? specifier : path3.resolve(baseDir, specifier);
|
|
242
|
+
const res = tryResolve(basePath, "extless");
|
|
243
|
+
if (res) return res;
|
|
244
|
+
}
|
|
245
|
+
const ext = path3.extname(specifier);
|
|
246
|
+
if ((ext === ".js" || ext === ".mjs" || ext === ".cjs") && (specifier.startsWith("./") || specifier.startsWith("../") || specifier.startsWith("/") || specifier.startsWith("file:"))) {
|
|
247
|
+
const withoutExt = specifier.slice(0, -ext.length);
|
|
248
|
+
const basePath = specifier.startsWith("file:") ? fileURLToPath(withoutExt) : specifier.startsWith("/") ? withoutExt : path3.resolve(baseDir, withoutExt);
|
|
249
|
+
const res = tryResolve(basePath, "fallback-js");
|
|
250
|
+
if (res) return res;
|
|
251
|
+
}
|
|
252
|
+
if (next) return next(specifier, context);
|
|
253
|
+
return { url: specifier, shortCircuit: true };
|
|
254
|
+
}
|
|
255
|
+
async function loaderLoad(url, context, next, runtime) {
|
|
256
|
+
const { format: expectedFormat } = runtime;
|
|
257
|
+
if (url.startsWith("file://")) {
|
|
258
|
+
const filename = fileURLToPath(url);
|
|
259
|
+
const match = pickPlugin(filename, runtime);
|
|
260
|
+
if (runtime.loaderConfig.debug) {
|
|
261
|
+
console.log(`[hirari-loader] load hook url=${url} match=${!!match}`);
|
|
262
|
+
}
|
|
263
|
+
if (match) {
|
|
264
|
+
const source = fs3.readFileSync(filename, "utf8");
|
|
265
|
+
const result = applyPlugin(source, filename, runtime);
|
|
266
|
+
return {
|
|
267
|
+
format: toNodeLoaderFormat(result.format || expectedFormat),
|
|
268
|
+
source: result.code,
|
|
269
|
+
shortCircuit: true
|
|
270
|
+
};
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
if (!next) {
|
|
274
|
+
throw new Error("No default loader available for " + url);
|
|
275
|
+
}
|
|
276
|
+
const forwarded = await next(url, context);
|
|
277
|
+
if (forwarded) return forwarded;
|
|
278
|
+
throw new Error("Loader did not return a result for " + url);
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
export {
|
|
282
|
+
loadHirariConfig,
|
|
283
|
+
IMPORT_META_URL_VARIABLE,
|
|
284
|
+
resolvePlugins,
|
|
285
|
+
createRuntime,
|
|
286
|
+
registerRequireHooks,
|
|
287
|
+
loaderResolve,
|
|
288
|
+
loaderLoad
|
|
289
|
+
};
|
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
// src/config.ts
|
|
2
|
+
import fs from "fs";
|
|
3
|
+
import path from "path";
|
|
4
|
+
var DEFAULT_CONFIG = {
|
|
5
|
+
format: "cjs",
|
|
6
|
+
plugins: [
|
|
7
|
+
"@hirarijs/loader-ts",
|
|
8
|
+
"@hirarijs/loader-tsx",
|
|
9
|
+
"@hirarijs/loader-vue",
|
|
10
|
+
"@hirarijs/loader-cjs-interop"
|
|
11
|
+
]
|
|
12
|
+
};
|
|
13
|
+
function loadHirariConfig(cwd = process.cwd()) {
|
|
14
|
+
const configPath = path.join(cwd, "hirari.json");
|
|
15
|
+
if (!fs.existsSync(configPath)) {
|
|
16
|
+
return { ...DEFAULT_CONFIG };
|
|
17
|
+
}
|
|
18
|
+
const raw = fs.readFileSync(configPath, "utf8");
|
|
19
|
+
let parsed;
|
|
20
|
+
try {
|
|
21
|
+
parsed = JSON.parse(raw);
|
|
22
|
+
} catch (error) {
|
|
23
|
+
throw new Error(`Failed to parse hirari.json: ${error.message}`);
|
|
24
|
+
}
|
|
25
|
+
const loaderConfig = parsed.loader || {};
|
|
26
|
+
return {
|
|
27
|
+
...DEFAULT_CONFIG,
|
|
28
|
+
...loaderConfig,
|
|
29
|
+
plugins: loaderConfig.plugins?.length ? loaderConfig.plugins : DEFAULT_CONFIG.plugins
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
function getFormat(config) {
|
|
33
|
+
return config.format === "esm" ? "esm" : "cjs";
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// src/constants.ts
|
|
37
|
+
var IMPORT_META_URL_VARIABLE = "__hirari_loader_import_meta_url__";
|
|
38
|
+
|
|
39
|
+
// src/plugin-manager.ts
|
|
40
|
+
import { spawnSync } from "child_process";
|
|
41
|
+
import fs2 from "fs";
|
|
42
|
+
import path2 from "path";
|
|
43
|
+
import { createRequire } from "module";
|
|
44
|
+
var PACKAGE_MANAGERS = [
|
|
45
|
+
{ lock: "pnpm-lock.yaml", command: "pnpm", args: ["add"] },
|
|
46
|
+
{ lock: "yarn.lock", command: "yarn", args: ["add"] },
|
|
47
|
+
{ lock: "package-lock.json", command: "npm", args: ["install"] },
|
|
48
|
+
{ lock: "npm-shrinkwrap.json", command: "npm", args: ["install"] }
|
|
49
|
+
];
|
|
50
|
+
function detectPackageManager(cwd) {
|
|
51
|
+
for (const pm of PACKAGE_MANAGERS) {
|
|
52
|
+
if (fs2.existsSync(path2.join(cwd, pm.lock))) return pm;
|
|
53
|
+
}
|
|
54
|
+
return { command: "npm", args: ["install"] };
|
|
55
|
+
}
|
|
56
|
+
function tryRequire(moduleId, cwd) {
|
|
57
|
+
const req = createRequire(path2.join(cwd, "noop.js"));
|
|
58
|
+
const loaded = req(moduleId);
|
|
59
|
+
return loaded && (loaded.default || loaded);
|
|
60
|
+
}
|
|
61
|
+
function install(pkg, cwd) {
|
|
62
|
+
const pm = detectPackageManager(cwd);
|
|
63
|
+
const result = spawnSync(pm.command, [...pm.args, pkg], {
|
|
64
|
+
cwd,
|
|
65
|
+
stdio: "inherit",
|
|
66
|
+
env: process.env
|
|
67
|
+
});
|
|
68
|
+
if (result.error) {
|
|
69
|
+
throw result.error;
|
|
70
|
+
}
|
|
71
|
+
if (result.status !== 0) {
|
|
72
|
+
throw new Error(`${pm.command} ${pm.args.join(" ")} ${pkg} failed`);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
function resolvePlugins(config, cwd) {
|
|
76
|
+
const plugins = [];
|
|
77
|
+
for (const pluginName of config.plugins || []) {
|
|
78
|
+
let loaded = null;
|
|
79
|
+
try {
|
|
80
|
+
loaded = tryRequire(pluginName, cwd);
|
|
81
|
+
} catch (error) {
|
|
82
|
+
if (config.autoInstall) {
|
|
83
|
+
console.log(`[hirari-loader] installing missing plugin ${pluginName}`);
|
|
84
|
+
install(pluginName, cwd);
|
|
85
|
+
loaded = tryRequire(pluginName, cwd);
|
|
86
|
+
} else {
|
|
87
|
+
throw new Error(
|
|
88
|
+
`Plugin "${pluginName}" not found. Enable autoInstall or install manually.`
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
if (!loaded) continue;
|
|
93
|
+
plugins.push({
|
|
94
|
+
plugin: loaded,
|
|
95
|
+
options: config.pluginOptions?.[pluginName]
|
|
96
|
+
});
|
|
97
|
+
if (config.debug) {
|
|
98
|
+
console.log(`[hirari-loader] loaded plugin ${pluginName}`);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return plugins;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// src/runtime.ts
|
|
105
|
+
import fs3 from "fs";
|
|
106
|
+
import module from "module";
|
|
107
|
+
import path3 from "path";
|
|
108
|
+
import { fileURLToPath, pathToFileURL } from "url";
|
|
109
|
+
import { addHook } from "pirates";
|
|
110
|
+
import * as sourceMapSupport from "source-map-support";
|
|
111
|
+
var map = {};
|
|
112
|
+
var EXTENSION_CANDIDATES = [
|
|
113
|
+
".ts",
|
|
114
|
+
".mts",
|
|
115
|
+
".cts",
|
|
116
|
+
".tsx",
|
|
117
|
+
".jsx",
|
|
118
|
+
".vue",
|
|
119
|
+
".js",
|
|
120
|
+
".mjs",
|
|
121
|
+
".cjs"
|
|
122
|
+
];
|
|
123
|
+
function installSourceMaps() {
|
|
124
|
+
sourceMapSupport.install({
|
|
125
|
+
handleUncaughtExceptions: false,
|
|
126
|
+
environment: "node",
|
|
127
|
+
retrieveSourceMap(file) {
|
|
128
|
+
if (map[file]) {
|
|
129
|
+
return { url: file, map: map[file] };
|
|
130
|
+
}
|
|
131
|
+
return null;
|
|
132
|
+
}
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
var toNodeLoaderFormat = (format) => format === "esm" ? "module" : "commonjs";
|
|
136
|
+
function createRuntime(cwd = process.cwd()) {
|
|
137
|
+
const loaderConfig = loadHirariConfig(cwd);
|
|
138
|
+
const resolvedPlugins = resolvePlugins(loaderConfig, cwd);
|
|
139
|
+
installSourceMaps();
|
|
140
|
+
return {
|
|
141
|
+
cwd,
|
|
142
|
+
loaderConfig,
|
|
143
|
+
resolvedPlugins,
|
|
144
|
+
format: getFormat(loaderConfig)
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
function applyPlugin(code, filename, runtime) {
|
|
148
|
+
for (const match of runtime.resolvedPlugins) {
|
|
149
|
+
if (!match.plugin.match(filename)) continue;
|
|
150
|
+
const ctx = {
|
|
151
|
+
format: runtime.format,
|
|
152
|
+
loaderConfig: runtime.loaderConfig,
|
|
153
|
+
pluginOptions: match.options
|
|
154
|
+
};
|
|
155
|
+
const result = match.plugin.transform(code, filename, ctx);
|
|
156
|
+
if (runtime.loaderConfig.debug) {
|
|
157
|
+
console.log(`[hirari-loader][${match.plugin.name}] compiled ${filename}`);
|
|
158
|
+
}
|
|
159
|
+
if (result.continue) {
|
|
160
|
+
continue;
|
|
161
|
+
}
|
|
162
|
+
if (result.map) {
|
|
163
|
+
map[filename] = result.map;
|
|
164
|
+
}
|
|
165
|
+
return result;
|
|
166
|
+
}
|
|
167
|
+
if (runtime.loaderConfig.debug) {
|
|
168
|
+
console.log(`[hirari-loader] no plugin matched ${filename}`);
|
|
169
|
+
}
|
|
170
|
+
return { code };
|
|
171
|
+
}
|
|
172
|
+
function collectExtensions(plugins) {
|
|
173
|
+
const set = /* @__PURE__ */ new Set();
|
|
174
|
+
for (const { plugin } of plugins) {
|
|
175
|
+
plugin.extensions.forEach((ext) => set.add(ext));
|
|
176
|
+
}
|
|
177
|
+
return Array.from(set);
|
|
178
|
+
}
|
|
179
|
+
function registerRequireHooks(runtime) {
|
|
180
|
+
const extensions = collectExtensions(runtime.resolvedPlugins);
|
|
181
|
+
const compile = (code, filename) => {
|
|
182
|
+
const result = applyPlugin(code, filename, runtime);
|
|
183
|
+
const banner = `const ${IMPORT_META_URL_VARIABLE} = require('url').pathToFileURL(__filename).href;`;
|
|
184
|
+
if (!result.code.includes(IMPORT_META_URL_VARIABLE)) {
|
|
185
|
+
return `${banner}${result.code}`;
|
|
186
|
+
}
|
|
187
|
+
return result.code;
|
|
188
|
+
};
|
|
189
|
+
const revert = addHook(compile, {
|
|
190
|
+
exts: extensions,
|
|
191
|
+
ignoreNodeModules: runtime.loaderConfig.hookIgnoreNodeModules ?? true
|
|
192
|
+
});
|
|
193
|
+
const extensionsObj = module.Module._extensions;
|
|
194
|
+
const jsHandler = extensionsObj[".js"];
|
|
195
|
+
extensionsObj[".js"] = function(mod, filename) {
|
|
196
|
+
try {
|
|
197
|
+
return jsHandler.call(this, mod, filename);
|
|
198
|
+
} catch (error) {
|
|
199
|
+
if (error && error.code === "ERR_REQUIRE_ESM") {
|
|
200
|
+
const src = fs3.readFileSync(filename, "utf8");
|
|
201
|
+
const result = applyPlugin(src, filename, runtime);
|
|
202
|
+
mod._compile(result.code, filename);
|
|
203
|
+
return;
|
|
204
|
+
}
|
|
205
|
+
throw error;
|
|
206
|
+
}
|
|
207
|
+
};
|
|
208
|
+
return () => {
|
|
209
|
+
revert();
|
|
210
|
+
extensionsObj[".js"] = jsHandler;
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
async function loaderResolve(specifier, context, next, runtime) {
|
|
214
|
+
const ignoreNodeModules = runtime.loaderConfig.hookIgnoreNodeModules ?? true;
|
|
215
|
+
const parentUrl = context && context.parentURL;
|
|
216
|
+
const baseDir = parentUrl && typeof parentUrl === "string" && parentUrl.startsWith("file:") ? path3.dirname(fileURLToPath(parentUrl)) : process.cwd();
|
|
217
|
+
const tryResolve = (basePath, note) => {
|
|
218
|
+
for (const ext2 of EXTENSION_CANDIDATES) {
|
|
219
|
+
const candidate = basePath + ext2;
|
|
220
|
+
if (ignoreNodeModules && candidate.includes("node_modules")) {
|
|
221
|
+
continue;
|
|
222
|
+
}
|
|
223
|
+
if (fs3.existsSync(candidate) && fs3.statSync(candidate).isFile()) {
|
|
224
|
+
const url = pathToFileURL(candidate).href;
|
|
225
|
+
if (runtime.loaderConfig.debug) {
|
|
226
|
+
console.log(`[hirari-loader] resolve ${note} ${specifier} -> ${url}`);
|
|
227
|
+
}
|
|
228
|
+
return { url, shortCircuit: true };
|
|
229
|
+
}
|
|
230
|
+
const indexCandidate = path3.join(basePath, "index" + ext2);
|
|
231
|
+
if (ignoreNodeModules && indexCandidate.includes("node_modules")) {
|
|
232
|
+
continue;
|
|
233
|
+
}
|
|
234
|
+
if (fs3.existsSync(indexCandidate) && fs3.statSync(indexCandidate).isFile()) {
|
|
235
|
+
const url = pathToFileURL(indexCandidate).href;
|
|
236
|
+
if (runtime.loaderConfig.debug) {
|
|
237
|
+
console.log(`[hirari-loader] resolve ${note} ${specifier} -> ${url}`);
|
|
238
|
+
}
|
|
239
|
+
return { url, shortCircuit: true };
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
return null;
|
|
243
|
+
};
|
|
244
|
+
if (!path3.extname(specifier) && (specifier.startsWith("./") || specifier.startsWith("../") || specifier.startsWith("/") || specifier.startsWith("file:")) && !specifier.startsWith("node:")) {
|
|
245
|
+
const basePath = specifier.startsWith("file:") ? fileURLToPath(specifier) : specifier.startsWith("/") ? specifier : path3.resolve(baseDir, specifier);
|
|
246
|
+
const res = tryResolve(basePath, "extless");
|
|
247
|
+
if (res) return res;
|
|
248
|
+
}
|
|
249
|
+
const ext = path3.extname(specifier);
|
|
250
|
+
if ((ext === ".js" || ext === ".mjs" || ext === ".cjs") && (specifier.startsWith("./") || specifier.startsWith("../") || specifier.startsWith("/") || specifier.startsWith("file:"))) {
|
|
251
|
+
const withoutExt = specifier.slice(0, -ext.length);
|
|
252
|
+
const basePath = specifier.startsWith("file:") ? fileURLToPath(withoutExt) : specifier.startsWith("/") ? withoutExt : path3.resolve(baseDir, withoutExt);
|
|
253
|
+
const res = tryResolve(basePath, "fallback-js");
|
|
254
|
+
if (res) return res;
|
|
255
|
+
}
|
|
256
|
+
if (next) return next(specifier, context);
|
|
257
|
+
return { url: specifier, shortCircuit: true };
|
|
258
|
+
}
|
|
259
|
+
async function loaderLoad(url, context, next, runtime) {
|
|
260
|
+
const { format: expectedFormat } = runtime;
|
|
261
|
+
if (url.startsWith("file://")) {
|
|
262
|
+
const filename = fileURLToPath(url);
|
|
263
|
+
const match = pickPlugin(filename, runtime.resolvedPlugins);
|
|
264
|
+
if (runtime.loaderConfig.debug) {
|
|
265
|
+
console.log(`[hirari-loader] load hook url=${url} match=${!!match}`);
|
|
266
|
+
}
|
|
267
|
+
if (match) {
|
|
268
|
+
const source = fs3.readFileSync(filename, "utf8");
|
|
269
|
+
const result = applyPlugin(source, filename, runtime);
|
|
270
|
+
return {
|
|
271
|
+
format: toNodeLoaderFormat(result.format || expectedFormat),
|
|
272
|
+
source: result.code,
|
|
273
|
+
shortCircuit: true
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
if (!next) {
|
|
278
|
+
throw new Error("No default loader available for " + url);
|
|
279
|
+
}
|
|
280
|
+
const forwarded = await next(url, context);
|
|
281
|
+
if (forwarded) return forwarded;
|
|
282
|
+
throw new Error("Loader did not return a result for " + url);
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
export {
|
|
286
|
+
loadHirariConfig,
|
|
287
|
+
IMPORT_META_URL_VARIABLE,
|
|
288
|
+
resolvePlugins,
|
|
289
|
+
createRuntime,
|
|
290
|
+
registerRequireHooks,
|
|
291
|
+
loaderResolve,
|
|
292
|
+
loaderLoad
|
|
293
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createRuntime,
|
|
3
|
+
registerRequireHooks
|
|
4
|
+
} from "./chunk-O7SYNOVB.js";
|
|
5
|
+
|
|
6
|
+
// src/register.ts
|
|
7
|
+
function register(cwd = process.cwd()) {
|
|
8
|
+
const runtime = createRuntime(cwd);
|
|
9
|
+
const unregister = registerRequireHooks(runtime);
|
|
10
|
+
return { unregister };
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export {
|
|
14
|
+
register
|
|
15
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createRuntime,
|
|
3
|
+
registerRequireHooks
|
|
4
|
+
} from "./chunk-2YMWZ4IT.js";
|
|
5
|
+
|
|
6
|
+
// src/register.ts
|
|
7
|
+
function register(cwd = process.cwd()) {
|
|
8
|
+
const runtime = createRuntime(cwd);
|
|
9
|
+
const unregister = registerRequireHooks(runtime);
|
|
10
|
+
return { unregister };
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export {
|
|
14
|
+
register
|
|
15
|
+
};
|
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
// src/config.ts
|
|
2
|
+
import fs from "fs";
|
|
3
|
+
import path from "path";
|
|
4
|
+
var DEFAULT_CONFIG = {
|
|
5
|
+
format: "cjs",
|
|
6
|
+
plugins: [
|
|
7
|
+
"@hirarijs/loader-ts",
|
|
8
|
+
"@hirarijs/loader-tsx",
|
|
9
|
+
"@hirarijs/loader-vue",
|
|
10
|
+
"@hirarijs/loader-cjs-interop"
|
|
11
|
+
]
|
|
12
|
+
};
|
|
13
|
+
function loadHirariConfig(cwd = process.cwd()) {
|
|
14
|
+
const configPath = path.join(cwd, "hirari.json");
|
|
15
|
+
if (!fs.existsSync(configPath)) {
|
|
16
|
+
return { ...DEFAULT_CONFIG };
|
|
17
|
+
}
|
|
18
|
+
const raw = fs.readFileSync(configPath, "utf8");
|
|
19
|
+
let parsed;
|
|
20
|
+
try {
|
|
21
|
+
parsed = JSON.parse(raw);
|
|
22
|
+
} catch (error) {
|
|
23
|
+
throw new Error(`Failed to parse hirari.json: ${error.message}`);
|
|
24
|
+
}
|
|
25
|
+
const loaderConfig = parsed.loader || {};
|
|
26
|
+
return {
|
|
27
|
+
...DEFAULT_CONFIG,
|
|
28
|
+
...loaderConfig,
|
|
29
|
+
plugins: loaderConfig.plugins?.length ? loaderConfig.plugins : DEFAULT_CONFIG.plugins
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
function getFormat(config) {
|
|
33
|
+
return config.format === "esm" ? "esm" : "cjs";
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// src/constants.ts
|
|
37
|
+
var IMPORT_META_URL_VARIABLE = "__hirari_loader_import_meta_url__";
|
|
38
|
+
|
|
39
|
+
// src/plugin-manager.ts
|
|
40
|
+
import { spawnSync } from "child_process";
|
|
41
|
+
import fs2 from "fs";
|
|
42
|
+
import path2 from "path";
|
|
43
|
+
import { createRequire } from "module";
|
|
44
|
+
var PACKAGE_MANAGERS = [
|
|
45
|
+
{ lock: "pnpm-lock.yaml", command: "pnpm", args: ["add"] },
|
|
46
|
+
{ lock: "yarn.lock", command: "yarn", args: ["add"] },
|
|
47
|
+
{ lock: "package-lock.json", command: "npm", args: ["install"] },
|
|
48
|
+
{ lock: "npm-shrinkwrap.json", command: "npm", args: ["install"] }
|
|
49
|
+
];
|
|
50
|
+
function detectPackageManager(cwd) {
|
|
51
|
+
for (const pm of PACKAGE_MANAGERS) {
|
|
52
|
+
if (fs2.existsSync(path2.join(cwd, pm.lock))) return pm;
|
|
53
|
+
}
|
|
54
|
+
return { command: "npm", args: ["install"] };
|
|
55
|
+
}
|
|
56
|
+
function tryRequire(moduleId, cwd) {
|
|
57
|
+
const req = createRequire(path2.join(cwd, "noop.js"));
|
|
58
|
+
const loaded = req(moduleId);
|
|
59
|
+
return loaded && (loaded.default || loaded);
|
|
60
|
+
}
|
|
61
|
+
function install(pkg, cwd) {
|
|
62
|
+
const pm = detectPackageManager(cwd);
|
|
63
|
+
const result = spawnSync(pm.command, [...pm.args, pkg], {
|
|
64
|
+
cwd,
|
|
65
|
+
stdio: "inherit",
|
|
66
|
+
env: process.env
|
|
67
|
+
});
|
|
68
|
+
if (result.error) {
|
|
69
|
+
throw result.error;
|
|
70
|
+
}
|
|
71
|
+
if (result.status !== 0) {
|
|
72
|
+
throw new Error(`${pm.command} ${pm.args.join(" ")} ${pkg} failed`);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
function resolvePlugins(config, cwd) {
|
|
76
|
+
const plugins = [];
|
|
77
|
+
for (const pluginName of config.plugins || []) {
|
|
78
|
+
let loaded = null;
|
|
79
|
+
try {
|
|
80
|
+
loaded = tryRequire(pluginName, cwd);
|
|
81
|
+
} catch (error) {
|
|
82
|
+
if (config.autoInstall) {
|
|
83
|
+
console.log(`[hirari-loader] installing missing plugin ${pluginName}`);
|
|
84
|
+
install(pluginName, cwd);
|
|
85
|
+
loaded = tryRequire(pluginName, cwd);
|
|
86
|
+
} else {
|
|
87
|
+
throw new Error(
|
|
88
|
+
`Plugin "${pluginName}" not found. Enable autoInstall or install manually.`
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
if (!loaded) continue;
|
|
93
|
+
plugins.push({
|
|
94
|
+
plugin: loaded,
|
|
95
|
+
options: config.pluginOptions?.[pluginName]
|
|
96
|
+
});
|
|
97
|
+
if (config.debug) {
|
|
98
|
+
console.log(`[hirari-loader] loaded plugin ${pluginName}`);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return plugins;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// src/runtime.ts
|
|
105
|
+
import fs3 from "fs";
|
|
106
|
+
import module from "module";
|
|
107
|
+
import path3 from "path";
|
|
108
|
+
import { fileURLToPath, pathToFileURL } from "url";
|
|
109
|
+
import { addHook } from "pirates";
|
|
110
|
+
import * as sourceMapSupport from "source-map-support";
|
|
111
|
+
var map = {};
|
|
112
|
+
var EXTENSION_CANDIDATES = [
|
|
113
|
+
".ts",
|
|
114
|
+
".mts",
|
|
115
|
+
".cts",
|
|
116
|
+
".tsx",
|
|
117
|
+
".jsx",
|
|
118
|
+
".vue",
|
|
119
|
+
".js",
|
|
120
|
+
".mjs",
|
|
121
|
+
".cjs"
|
|
122
|
+
];
|
|
123
|
+
function installSourceMaps() {
|
|
124
|
+
sourceMapSupport.install({
|
|
125
|
+
handleUncaughtExceptions: false,
|
|
126
|
+
environment: "node",
|
|
127
|
+
retrieveSourceMap(file) {
|
|
128
|
+
if (map[file]) {
|
|
129
|
+
return { url: file, map: map[file] };
|
|
130
|
+
}
|
|
131
|
+
return null;
|
|
132
|
+
}
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
var toNodeLoaderFormat = (format) => format === "esm" ? "module" : "commonjs";
|
|
136
|
+
function createRuntime(cwd = process.cwd()) {
|
|
137
|
+
const loaderConfig = loadHirariConfig(cwd);
|
|
138
|
+
const resolvedPlugins = resolvePlugins(loaderConfig, cwd);
|
|
139
|
+
installSourceMaps();
|
|
140
|
+
return {
|
|
141
|
+
cwd,
|
|
142
|
+
loaderConfig,
|
|
143
|
+
resolvedPlugins,
|
|
144
|
+
format: getFormat(loaderConfig)
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
function applyPlugin(code, filename, runtime) {
|
|
148
|
+
for (const match of runtime.resolvedPlugins) {
|
|
149
|
+
if (!match.plugin.match(filename)) continue;
|
|
150
|
+
const ctx = {
|
|
151
|
+
format: runtime.format,
|
|
152
|
+
loaderConfig: runtime.loaderConfig,
|
|
153
|
+
pluginOptions: match.options
|
|
154
|
+
};
|
|
155
|
+
const result = match.plugin.transform(code, filename, ctx);
|
|
156
|
+
if (runtime.loaderConfig.debug) {
|
|
157
|
+
console.log(`[hirari-loader][${match.plugin.name}] compiled ${filename}`);
|
|
158
|
+
}
|
|
159
|
+
if (result.continue) {
|
|
160
|
+
continue;
|
|
161
|
+
}
|
|
162
|
+
if (result.map) {
|
|
163
|
+
map[filename] = result.map;
|
|
164
|
+
}
|
|
165
|
+
return result;
|
|
166
|
+
}
|
|
167
|
+
if (runtime.loaderConfig.debug) {
|
|
168
|
+
console.log(`[hirari-loader] no plugin matched ${filename}`);
|
|
169
|
+
}
|
|
170
|
+
return { code };
|
|
171
|
+
}
|
|
172
|
+
function pickPlugin(filename, runtime) {
|
|
173
|
+
return runtime.resolvedPlugins.find(({ plugin }) => plugin.match(filename));
|
|
174
|
+
}
|
|
175
|
+
function collectExtensions(plugins) {
|
|
176
|
+
const set = /* @__PURE__ */ new Set();
|
|
177
|
+
for (const { plugin } of plugins) {
|
|
178
|
+
plugin.extensions.forEach((ext) => set.add(ext));
|
|
179
|
+
}
|
|
180
|
+
return Array.from(set);
|
|
181
|
+
}
|
|
182
|
+
function registerRequireHooks(runtime) {
|
|
183
|
+
const extensions = collectExtensions(runtime.resolvedPlugins);
|
|
184
|
+
const compile = (code, filename) => {
|
|
185
|
+
const result = applyPlugin(code, filename, runtime);
|
|
186
|
+
const banner = `const ${IMPORT_META_URL_VARIABLE} = require('url').pathToFileURL(__filename).href;`;
|
|
187
|
+
if (!result.code.includes(IMPORT_META_URL_VARIABLE)) {
|
|
188
|
+
return `${banner}${result.code}`;
|
|
189
|
+
}
|
|
190
|
+
return result.code;
|
|
191
|
+
};
|
|
192
|
+
const revert = addHook(compile, {
|
|
193
|
+
exts: extensions,
|
|
194
|
+
ignoreNodeModules: runtime.loaderConfig.hookIgnoreNodeModules ?? true
|
|
195
|
+
});
|
|
196
|
+
const extensionsObj = module.Module._extensions;
|
|
197
|
+
const jsHandler = extensionsObj[".js"];
|
|
198
|
+
extensionsObj[".js"] = function(mod, filename) {
|
|
199
|
+
try {
|
|
200
|
+
return jsHandler.call(this, mod, filename);
|
|
201
|
+
} catch (error) {
|
|
202
|
+
if (error && error.code === "ERR_REQUIRE_ESM") {
|
|
203
|
+
const src = fs3.readFileSync(filename, "utf8");
|
|
204
|
+
const result = applyPlugin(src, filename, runtime);
|
|
205
|
+
mod._compile(result.code, filename);
|
|
206
|
+
return;
|
|
207
|
+
}
|
|
208
|
+
throw error;
|
|
209
|
+
}
|
|
210
|
+
};
|
|
211
|
+
return () => {
|
|
212
|
+
revert();
|
|
213
|
+
extensionsObj[".js"] = jsHandler;
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
async function loaderResolve(specifier, context, next, runtime) {
|
|
217
|
+
const ignoreNodeModules = runtime.loaderConfig.hookIgnoreNodeModules ?? true;
|
|
218
|
+
const parentUrl = context && context.parentURL;
|
|
219
|
+
const baseDir = parentUrl && typeof parentUrl === "string" && parentUrl.startsWith("file:") ? path3.dirname(fileURLToPath(parentUrl)) : process.cwd();
|
|
220
|
+
const tryResolve = (basePath, note) => {
|
|
221
|
+
for (const ext2 of EXTENSION_CANDIDATES) {
|
|
222
|
+
const candidate = basePath + ext2;
|
|
223
|
+
if (ignoreNodeModules && candidate.includes("node_modules")) {
|
|
224
|
+
continue;
|
|
225
|
+
}
|
|
226
|
+
if (fs3.existsSync(candidate) && fs3.statSync(candidate).isFile()) {
|
|
227
|
+
const url = pathToFileURL(candidate).href;
|
|
228
|
+
if (runtime.loaderConfig.debug) {
|
|
229
|
+
console.log(`[hirari-loader] resolve ${note} ${specifier} -> ${url}`);
|
|
230
|
+
}
|
|
231
|
+
return { url, shortCircuit: true };
|
|
232
|
+
}
|
|
233
|
+
const indexCandidate = path3.join(basePath, "index" + ext2);
|
|
234
|
+
if (ignoreNodeModules && indexCandidate.includes("node_modules")) {
|
|
235
|
+
continue;
|
|
236
|
+
}
|
|
237
|
+
if (fs3.existsSync(indexCandidate) && fs3.statSync(indexCandidate).isFile()) {
|
|
238
|
+
const url = pathToFileURL(indexCandidate).href;
|
|
239
|
+
if (runtime.loaderConfig.debug) {
|
|
240
|
+
console.log(`[hirari-loader] resolve ${note} ${specifier} -> ${url}`);
|
|
241
|
+
}
|
|
242
|
+
return { url, shortCircuit: true };
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
return null;
|
|
246
|
+
};
|
|
247
|
+
if (!path3.extname(specifier) && (specifier.startsWith("./") || specifier.startsWith("../") || specifier.startsWith("/") || specifier.startsWith("file:")) && !specifier.startsWith("node:")) {
|
|
248
|
+
const basePath = specifier.startsWith("file:") ? fileURLToPath(specifier) : specifier.startsWith("/") ? specifier : path3.resolve(baseDir, specifier);
|
|
249
|
+
const res = tryResolve(basePath, "extless");
|
|
250
|
+
if (res) return res;
|
|
251
|
+
}
|
|
252
|
+
const ext = path3.extname(specifier);
|
|
253
|
+
if ((ext === ".js" || ext === ".mjs" || ext === ".cjs") && (specifier.startsWith("./") || specifier.startsWith("../") || specifier.startsWith("/") || specifier.startsWith("file:"))) {
|
|
254
|
+
const withoutExt = specifier.slice(0, -ext.length);
|
|
255
|
+
const basePath = specifier.startsWith("file:") ? fileURLToPath(withoutExt) : specifier.startsWith("/") ? withoutExt : path3.resolve(baseDir, withoutExt);
|
|
256
|
+
const res = tryResolve(basePath, "fallback-js");
|
|
257
|
+
if (res) return res;
|
|
258
|
+
}
|
|
259
|
+
if (next) return next(specifier, context);
|
|
260
|
+
return { url: specifier, shortCircuit: true };
|
|
261
|
+
}
|
|
262
|
+
async function loaderLoad(url, context, next, runtime) {
|
|
263
|
+
const { format: expectedFormat } = runtime;
|
|
264
|
+
if (url.startsWith("file://")) {
|
|
265
|
+
const filename = fileURLToPath(url);
|
|
266
|
+
const match = pickPlugin(filename, runtime);
|
|
267
|
+
if (runtime.loaderConfig.debug) {
|
|
268
|
+
console.log(`[hirari-loader] load hook url=${url} match=${!!match}`);
|
|
269
|
+
}
|
|
270
|
+
if (match) {
|
|
271
|
+
const source = fs3.readFileSync(filename, "utf8");
|
|
272
|
+
const result = applyPlugin(source, filename, runtime);
|
|
273
|
+
return {
|
|
274
|
+
format: toNodeLoaderFormat(result.format || expectedFormat),
|
|
275
|
+
source: result.code,
|
|
276
|
+
shortCircuit: true
|
|
277
|
+
};
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
if (!next) {
|
|
281
|
+
throw new Error("No default loader available for " + url);
|
|
282
|
+
}
|
|
283
|
+
const forwarded = await next(url, context);
|
|
284
|
+
if (forwarded) return forwarded;
|
|
285
|
+
throw new Error("Loader did not return a result for " + url);
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
export {
|
|
289
|
+
loadHirariConfig,
|
|
290
|
+
IMPORT_META_URL_VARIABLE,
|
|
291
|
+
resolvePlugins,
|
|
292
|
+
createRuntime,
|
|
293
|
+
registerRequireHooks,
|
|
294
|
+
loaderResolve,
|
|
295
|
+
loaderLoad
|
|
296
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createRuntime,
|
|
3
|
+
registerRequireHooks
|
|
4
|
+
} from "./chunk-B6QICL5V.js";
|
|
5
|
+
|
|
6
|
+
// src/register.ts
|
|
7
|
+
function register(cwd = process.cwd()) {
|
|
8
|
+
const runtime = createRuntime(cwd);
|
|
9
|
+
const unregister = registerRequireHooks(runtime);
|
|
10
|
+
return { unregister };
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export {
|
|
14
|
+
register
|
|
15
|
+
};
|
package/dist/index.cjs
CHANGED
|
@@ -173,30 +173,30 @@ function createRuntime(cwd = process.cwd()) {
|
|
|
173
173
|
format: getFormat(loaderConfig)
|
|
174
174
|
};
|
|
175
175
|
}
|
|
176
|
-
function pickPlugin(filename, plugins) {
|
|
177
|
-
return plugins.find(({ plugin }) => plugin.match(filename));
|
|
178
|
-
}
|
|
179
176
|
function applyPlugin(code, filename, runtime) {
|
|
180
|
-
const match
|
|
181
|
-
|
|
177
|
+
for (const match of runtime.resolvedPlugins) {
|
|
178
|
+
if (!match.plugin.match(filename)) continue;
|
|
179
|
+
const ctx = {
|
|
180
|
+
format: runtime.format,
|
|
181
|
+
loaderConfig: runtime.loaderConfig,
|
|
182
|
+
pluginOptions: match.options
|
|
183
|
+
};
|
|
184
|
+
const result = match.plugin.transform(code, filename, ctx);
|
|
182
185
|
if (runtime.loaderConfig.debug) {
|
|
183
|
-
console.log(`[hirari-loader]
|
|
186
|
+
console.log(`[hirari-loader][${match.plugin.name}] compiled ${filename}`);
|
|
187
|
+
}
|
|
188
|
+
if (result.continue) {
|
|
189
|
+
continue;
|
|
190
|
+
}
|
|
191
|
+
if (result.map) {
|
|
192
|
+
map[filename] = result.map;
|
|
184
193
|
}
|
|
185
|
-
return
|
|
194
|
+
return result;
|
|
186
195
|
}
|
|
187
|
-
const ctx = {
|
|
188
|
-
format: runtime.format,
|
|
189
|
-
loaderConfig: runtime.loaderConfig,
|
|
190
|
-
pluginOptions: match.options
|
|
191
|
-
};
|
|
192
|
-
const result = match.plugin.transform(code, filename, ctx);
|
|
193
196
|
if (runtime.loaderConfig.debug) {
|
|
194
|
-
console.log(`[hirari-loader]
|
|
195
|
-
}
|
|
196
|
-
if (result.map) {
|
|
197
|
-
map[filename] = result.map;
|
|
197
|
+
console.log(`[hirari-loader] no plugin matched ${filename}`);
|
|
198
198
|
}
|
|
199
|
-
return
|
|
199
|
+
return { code };
|
|
200
200
|
}
|
|
201
201
|
function collectExtensions(plugins) {
|
|
202
202
|
const set = /* @__PURE__ */ new Set();
|
|
@@ -217,7 +217,7 @@ function registerRequireHooks(runtime) {
|
|
|
217
217
|
};
|
|
218
218
|
const revert = (0, import_pirates.addHook)(compile, {
|
|
219
219
|
exts: extensions,
|
|
220
|
-
ignoreNodeModules:
|
|
220
|
+
ignoreNodeModules: false
|
|
221
221
|
});
|
|
222
222
|
const extensionsObj = import_module2.default.Module._extensions;
|
|
223
223
|
const jsHandler = extensionsObj[".js"];
|
package/dist/index.d.cts
CHANGED
|
@@ -10,6 +10,10 @@ interface TransformResult {
|
|
|
10
10
|
code: string;
|
|
11
11
|
map?: string;
|
|
12
12
|
format?: ModuleFormat;
|
|
13
|
+
/**
|
|
14
|
+
* When true, loader will continue to next plugin instead of short-circuiting.
|
|
15
|
+
*/
|
|
16
|
+
continue?: boolean;
|
|
13
17
|
}
|
|
14
18
|
interface LoaderPlugin {
|
|
15
19
|
name: string;
|
|
@@ -31,6 +35,9 @@ interface LoaderConfig {
|
|
|
31
35
|
plugins?: string[];
|
|
32
36
|
pluginOptions?: Record<string, Record<string, unknown>>;
|
|
33
37
|
autoInstall?: boolean;
|
|
38
|
+
/**
|
|
39
|
+
* @deprecated 全局 ignore 已取消,请使用各插件的 ignoreNodeModules/allowNodeModules 配置。
|
|
40
|
+
*/
|
|
34
41
|
hookIgnoreNodeModules?: boolean;
|
|
35
42
|
debug?: boolean;
|
|
36
43
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -10,6 +10,10 @@ interface TransformResult {
|
|
|
10
10
|
code: string;
|
|
11
11
|
map?: string;
|
|
12
12
|
format?: ModuleFormat;
|
|
13
|
+
/**
|
|
14
|
+
* When true, loader will continue to next plugin instead of short-circuiting.
|
|
15
|
+
*/
|
|
16
|
+
continue?: boolean;
|
|
13
17
|
}
|
|
14
18
|
interface LoaderPlugin {
|
|
15
19
|
name: string;
|
|
@@ -31,6 +35,9 @@ interface LoaderConfig {
|
|
|
31
35
|
plugins?: string[];
|
|
32
36
|
pluginOptions?: Record<string, Record<string, unknown>>;
|
|
33
37
|
autoInstall?: boolean;
|
|
38
|
+
/**
|
|
39
|
+
* @deprecated 全局 ignore 已取消,请使用各插件的 ignoreNodeModules/allowNodeModules 配置。
|
|
40
|
+
*/
|
|
34
41
|
hookIgnoreNodeModules?: boolean;
|
|
35
42
|
debug?: boolean;
|
|
36
43
|
}
|
package/dist/index.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
register
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-JPHIWQ7S.js";
|
|
4
4
|
import {
|
|
5
5
|
IMPORT_META_URL_VARIABLE,
|
|
6
6
|
createRuntime,
|
|
7
7
|
loadHirariConfig,
|
|
8
8
|
resolvePlugins
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-2YMWZ4IT.js";
|
|
10
10
|
export {
|
|
11
11
|
IMPORT_META_URL_VARIABLE,
|
|
12
12
|
createRuntime,
|
package/dist/loader.cjs
CHANGED
|
@@ -179,41 +179,40 @@ function createRuntime(cwd = process.cwd()) {
|
|
|
179
179
|
format: getFormat(loaderConfig)
|
|
180
180
|
};
|
|
181
181
|
}
|
|
182
|
-
function pickPlugin(filename, plugins) {
|
|
183
|
-
return plugins.find(({ plugin }) => plugin.match(filename));
|
|
184
|
-
}
|
|
185
182
|
function applyPlugin(code, filename, runtime2) {
|
|
186
|
-
const match
|
|
187
|
-
|
|
183
|
+
for (const match of runtime2.resolvedPlugins) {
|
|
184
|
+
if (!match.plugin.match(filename)) continue;
|
|
185
|
+
const ctx = {
|
|
186
|
+
format: runtime2.format,
|
|
187
|
+
loaderConfig: runtime2.loaderConfig,
|
|
188
|
+
pluginOptions: match.options
|
|
189
|
+
};
|
|
190
|
+
const result = match.plugin.transform(code, filename, ctx);
|
|
188
191
|
if (runtime2.loaderConfig.debug) {
|
|
189
|
-
console.log(`[hirari-loader]
|
|
192
|
+
console.log(`[hirari-loader][${match.plugin.name}] compiled ${filename}`);
|
|
193
|
+
}
|
|
194
|
+
if (result.continue) {
|
|
195
|
+
continue;
|
|
190
196
|
}
|
|
191
|
-
|
|
197
|
+
if (result.map) {
|
|
198
|
+
map[filename] = result.map;
|
|
199
|
+
}
|
|
200
|
+
return result;
|
|
192
201
|
}
|
|
193
|
-
const ctx = {
|
|
194
|
-
format: runtime2.format,
|
|
195
|
-
loaderConfig: runtime2.loaderConfig,
|
|
196
|
-
pluginOptions: match.options
|
|
197
|
-
};
|
|
198
|
-
const result = match.plugin.transform(code, filename, ctx);
|
|
199
202
|
if (runtime2.loaderConfig.debug) {
|
|
200
|
-
console.log(`[hirari-loader]
|
|
203
|
+
console.log(`[hirari-loader] no plugin matched ${filename}`);
|
|
201
204
|
}
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
return
|
|
205
|
+
return { code };
|
|
206
|
+
}
|
|
207
|
+
function pickPlugin(filename, runtime2) {
|
|
208
|
+
return runtime2.resolvedPlugins.find(({ plugin }) => plugin.match(filename));
|
|
206
209
|
}
|
|
207
210
|
async function loaderResolve(specifier, context, next, runtime2) {
|
|
208
|
-
const ignoreNodeModules = runtime2.loaderConfig.hookIgnoreNodeModules ?? true;
|
|
209
211
|
const parentUrl = context && context.parentURL;
|
|
210
212
|
const baseDir = parentUrl && typeof parentUrl === "string" && parentUrl.startsWith("file:") ? import_path3.default.dirname((0, import_url.fileURLToPath)(parentUrl)) : process.cwd();
|
|
211
213
|
const tryResolve = (basePath, note) => {
|
|
212
214
|
for (const ext2 of EXTENSION_CANDIDATES) {
|
|
213
215
|
const candidate = basePath + ext2;
|
|
214
|
-
if (ignoreNodeModules && candidate.includes("node_modules")) {
|
|
215
|
-
continue;
|
|
216
|
-
}
|
|
217
216
|
if (import_fs3.default.existsSync(candidate) && import_fs3.default.statSync(candidate).isFile()) {
|
|
218
217
|
const url = (0, import_url.pathToFileURL)(candidate).href;
|
|
219
218
|
if (runtime2.loaderConfig.debug) {
|
|
@@ -222,9 +221,6 @@ async function loaderResolve(specifier, context, next, runtime2) {
|
|
|
222
221
|
return { url, shortCircuit: true };
|
|
223
222
|
}
|
|
224
223
|
const indexCandidate = import_path3.default.join(basePath, "index" + ext2);
|
|
225
|
-
if (ignoreNodeModules && indexCandidate.includes("node_modules")) {
|
|
226
|
-
continue;
|
|
227
|
-
}
|
|
228
224
|
if (import_fs3.default.existsSync(indexCandidate) && import_fs3.default.statSync(indexCandidate).isFile()) {
|
|
229
225
|
const url = (0, import_url.pathToFileURL)(indexCandidate).href;
|
|
230
226
|
if (runtime2.loaderConfig.debug) {
|
|
@@ -254,7 +250,7 @@ async function loaderLoad(url, context, next, runtime2) {
|
|
|
254
250
|
const { format: expectedFormat } = runtime2;
|
|
255
251
|
if (url.startsWith("file://")) {
|
|
256
252
|
const filename = (0, import_url.fileURLToPath)(url);
|
|
257
|
-
const match = pickPlugin(filename, runtime2
|
|
253
|
+
const match = pickPlugin(filename, runtime2);
|
|
258
254
|
if (runtime2.loaderConfig.debug) {
|
|
259
255
|
console.log(`[hirari-loader] load hook url=${url} match=${!!match}`);
|
|
260
256
|
}
|
package/dist/loader.js
CHANGED
package/dist/register-auto.cjs
CHANGED
|
@@ -156,30 +156,30 @@ function createRuntime(cwd = process.cwd()) {
|
|
|
156
156
|
format: getFormat(loaderConfig)
|
|
157
157
|
};
|
|
158
158
|
}
|
|
159
|
-
function pickPlugin(filename, plugins) {
|
|
160
|
-
return plugins.find(({ plugin }) => plugin.match(filename));
|
|
161
|
-
}
|
|
162
159
|
function applyPlugin(code, filename, runtime) {
|
|
163
|
-
const match
|
|
164
|
-
|
|
160
|
+
for (const match of runtime.resolvedPlugins) {
|
|
161
|
+
if (!match.plugin.match(filename)) continue;
|
|
162
|
+
const ctx = {
|
|
163
|
+
format: runtime.format,
|
|
164
|
+
loaderConfig: runtime.loaderConfig,
|
|
165
|
+
pluginOptions: match.options
|
|
166
|
+
};
|
|
167
|
+
const result = match.plugin.transform(code, filename, ctx);
|
|
165
168
|
if (runtime.loaderConfig.debug) {
|
|
166
|
-
console.log(`[hirari-loader]
|
|
169
|
+
console.log(`[hirari-loader][${match.plugin.name}] compiled ${filename}`);
|
|
170
|
+
}
|
|
171
|
+
if (result.continue) {
|
|
172
|
+
continue;
|
|
173
|
+
}
|
|
174
|
+
if (result.map) {
|
|
175
|
+
map[filename] = result.map;
|
|
167
176
|
}
|
|
168
|
-
return
|
|
177
|
+
return result;
|
|
169
178
|
}
|
|
170
|
-
const ctx = {
|
|
171
|
-
format: runtime.format,
|
|
172
|
-
loaderConfig: runtime.loaderConfig,
|
|
173
|
-
pluginOptions: match.options
|
|
174
|
-
};
|
|
175
|
-
const result = match.plugin.transform(code, filename, ctx);
|
|
176
179
|
if (runtime.loaderConfig.debug) {
|
|
177
|
-
console.log(`[hirari-loader]
|
|
178
|
-
}
|
|
179
|
-
if (result.map) {
|
|
180
|
-
map[filename] = result.map;
|
|
180
|
+
console.log(`[hirari-loader] no plugin matched ${filename}`);
|
|
181
181
|
}
|
|
182
|
-
return
|
|
182
|
+
return { code };
|
|
183
183
|
}
|
|
184
184
|
function collectExtensions(plugins) {
|
|
185
185
|
const set = /* @__PURE__ */ new Set();
|
|
@@ -200,7 +200,7 @@ function registerRequireHooks(runtime) {
|
|
|
200
200
|
};
|
|
201
201
|
const revert = (0, import_pirates.addHook)(compile, {
|
|
202
202
|
exts: extensions,
|
|
203
|
-
ignoreNodeModules:
|
|
203
|
+
ignoreNodeModules: false
|
|
204
204
|
});
|
|
205
205
|
const extensionsObj = import_module2.default.Module._extensions;
|
|
206
206
|
const jsHandler = extensionsObj[".js"];
|
package/dist/register-auto.js
CHANGED
package/dist/register.cjs
CHANGED
|
@@ -168,30 +168,30 @@ function createRuntime(cwd = process.cwd()) {
|
|
|
168
168
|
format: getFormat(loaderConfig)
|
|
169
169
|
};
|
|
170
170
|
}
|
|
171
|
-
function pickPlugin(filename, plugins) {
|
|
172
|
-
return plugins.find(({ plugin }) => plugin.match(filename));
|
|
173
|
-
}
|
|
174
171
|
function applyPlugin(code, filename, runtime) {
|
|
175
|
-
const match
|
|
176
|
-
|
|
172
|
+
for (const match of runtime.resolvedPlugins) {
|
|
173
|
+
if (!match.plugin.match(filename)) continue;
|
|
174
|
+
const ctx = {
|
|
175
|
+
format: runtime.format,
|
|
176
|
+
loaderConfig: runtime.loaderConfig,
|
|
177
|
+
pluginOptions: match.options
|
|
178
|
+
};
|
|
179
|
+
const result = match.plugin.transform(code, filename, ctx);
|
|
177
180
|
if (runtime.loaderConfig.debug) {
|
|
178
|
-
console.log(`[hirari-loader]
|
|
181
|
+
console.log(`[hirari-loader][${match.plugin.name}] compiled ${filename}`);
|
|
182
|
+
}
|
|
183
|
+
if (result.continue) {
|
|
184
|
+
continue;
|
|
185
|
+
}
|
|
186
|
+
if (result.map) {
|
|
187
|
+
map[filename] = result.map;
|
|
179
188
|
}
|
|
180
|
-
return
|
|
189
|
+
return result;
|
|
181
190
|
}
|
|
182
|
-
const ctx = {
|
|
183
|
-
format: runtime.format,
|
|
184
|
-
loaderConfig: runtime.loaderConfig,
|
|
185
|
-
pluginOptions: match.options
|
|
186
|
-
};
|
|
187
|
-
const result = match.plugin.transform(code, filename, ctx);
|
|
188
191
|
if (runtime.loaderConfig.debug) {
|
|
189
|
-
console.log(`[hirari-loader]
|
|
190
|
-
}
|
|
191
|
-
if (result.map) {
|
|
192
|
-
map[filename] = result.map;
|
|
192
|
+
console.log(`[hirari-loader] no plugin matched ${filename}`);
|
|
193
193
|
}
|
|
194
|
-
return
|
|
194
|
+
return { code };
|
|
195
195
|
}
|
|
196
196
|
function collectExtensions(plugins) {
|
|
197
197
|
const set = /* @__PURE__ */ new Set();
|
|
@@ -212,7 +212,7 @@ function registerRequireHooks(runtime) {
|
|
|
212
212
|
};
|
|
213
213
|
const revert = (0, import_pirates.addHook)(compile, {
|
|
214
214
|
exts: extensions,
|
|
215
|
-
ignoreNodeModules:
|
|
215
|
+
ignoreNodeModules: false
|
|
216
216
|
});
|
|
217
217
|
const extensionsObj = import_module2.default.Module._extensions;
|
|
218
218
|
const jsHandler = extensionsObj[".js"];
|
package/dist/register.js
CHANGED