unplugin-oxc
Version:
Oxc integration for unplugin.
148 lines (144 loc) • 4.26 kB
JavaScript
import { readFileSync } from "node:fs";
import path from "node:path";
import process from "node:process";
import { ResolverFactory } from "oxc-resolver";
import { transform } from "oxc-transform";
import { createUnplugin } from "unplugin";
import { createFilter } from "unplugin-utils";
//#region src/core/options.ts
function resolveOptions(options, framework) {
return {
include: options.include || [/\.[cm]?[jt]sx?$/],
exclude: options.exclude || [/node_modules/],
enforce: "enforce" in options ? options.enforce : "pre",
transform: options.transform || {},
resolve: options.resolve || {},
resolveNodeModules: options.resolveNodeModules || false,
minify: options.minify || false,
sourcemap: options.sourcemap ?? framework === "unloader"
};
}
//#endregion
//#region src/core/utils.ts
function getModuleFormat(id) {
const ext = path.extname(id);
switch (ext) {
case ".mjs":
case ".mts": return "module";
case ".cjs":
case ".cts": return "commonjs";
case ".json": return "json";
}
}
//#endregion
//#region src/index.ts
const Oxc = createUnplugin((rawOptions = {}, { framework }) => {
const options = resolveOptions(rawOptions, framework);
const filter = createFilter(options.include, options.exclude);
const resolveId = options.resolve !== false ? (id, importer, resolveOptions$1) => {
if (!options.resolveNodeModules && id[0] !== "." && !path.isAbsolute(id)) return;
const resolver = new ResolverFactory({
extensions: [
".mjs",
".js",
".ts",
".jsx",
".tsx",
".json",
".node"
],
conditionNames: resolveOptions$1?.conditions ? Array.from(resolveOptions$1.conditions) : [
"import",
"require",
"browser",
"node",
"default"
],
builtinModules: true,
...options.resolve
});
const directory = importer ? path.dirname(importer) : process.cwd();
const resolved = resolver.sync(directory, id);
if (resolved.error?.startsWith("Builtin module")) return {
id,
external: true,
moduleSideEffects: false
};
if (resolved.path) {
const format = getModuleFormat(resolved.path) || resolved.moduleType || "commonjs";
return {
id: resolved.path,
format
};
}
} : void 0;
const transform$1 = options.transform !== false ? (code, id, ...args) => {
const [transformOptions] = args;
const result = transform(id, code, {
...options.transform,
sourceType: guessSourceType(id, transformOptions?.format),
sourcemap: options.sourcemap
});
if (result.errors.length) throw new SyntaxError(result.errors.map((error) => error.message).join("\n"));
return {
code: result.code,
map: result.map
};
} : void 0;
const renderChunk = options.minify !== false ? async (code, chunk) => {
const { minify } = await import("oxc-minify");
const result = minify(chunk.fileName, code, {
...options.minify === true ? {} : options.minify,
sourcemap: options.sourcemap
});
return {
code: result.code,
map: result.map
};
} : void 0;
const unloader = {
options(config) {
config.sourcemap ||= options.sourcemap;
},
load(id) {
if (id.endsWith(".json")) {
let code = readFileSync(id, "utf8");
const json = JSON.parse(code);
code = `const json = ${code}\nexport default json\n`;
const i = 0;
for (const key of Object.keys(json)) {
const sanitizedKey = `_${key.replaceAll(/\W/g, "_")}${i}`;
code += `\nconst ${sanitizedKey} = json[${JSON.stringify(key)}]\nexport { ${sanitizedKey} as ${JSON.stringify(key)} }\n`;
}
return {
code,
format: "module"
};
}
if (!filter(id)) return;
const contents = readFileSync(id, "utf8");
return contents;
}
};
return {
name: "unplugin-oxc",
enforce: options.enforce,
resolveId,
transformInclude(id) {
return filter(id);
},
transform: transform$1,
rollup: { renderChunk },
rolldown: { renderChunk },
vite: { renderChunk },
unloader
};
});
function guessSourceType(id, format) {
if (format === "module" || format === "module-typescript") return "module";
else if (format === "commonjs" || format === "commonjs-typescript") return "script";
const moduleFormat = getModuleFormat(id);
if (moduleFormat) return moduleFormat === "module" ? "module" : "script";
}
//#endregion
export { Oxc };