unplugin-oxc
Version:
Oxc integration for unplugin.
158 lines (157 loc) • 4.57 kB
JavaScript
import { readFileSync } from "node:fs";
import path from "node:path";
import process from "node:process";
import { ResolverFactory } from "oxc-resolver";
import { transformSync } from "oxc-transform";
import { createUnplugin } from "unplugin";
//#region node_modules/.pnpm/@antfu+utils@9.3.0/node_modules/@antfu/utils/dist/index.mjs
function toArray(array) {
array = array ?? [];
return Array.isArray(array) ? array : [array];
}
//#endregion
//#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) {
switch (path.extname(id)) {
case ".mjs":
case ".mts": return "module";
case ".cjs":
case ".cts": return "commonjs";
case ".json": return "json";
case ".jsx":
case ".tsx": return "module";
}
}
//#endregion
//#region src/index.ts
const Oxc = createUnplugin((rawOptions = {}, { framework }) => {
const options = resolveOptions(rawOptions, framework);
const resolveId = options.resolve === false ? void 0 : (id, importer, resolveOptions) => {
if (!options.resolveNodeModules && id[0] !== "." && !path.isAbsolute(id)) return;
const resolver = new ResolverFactory({
extensions: [
".mjs",
".js",
".ts",
".jsx",
".tsx",
".json",
".node"
],
conditionNames: resolveOptions?.conditions ? Array.from(resolveOptions.conditions) : [
"import",
"require",
"browser",
"node",
"default"
],
builtinModules: true,
moduleType: 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
};
}
};
const transform = options.transform === false ? void 0 : (code, id, ...args) => {
const [transformOptions] = args;
const result = transformSync(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
};
};
const renderChunk = options.minify === false ? void 0 : async (code, chunk) => {
const { minify } = await import("oxc-minify");
const result = await minify(chunk.fileName, code, {
...options.minify === true ? {} : options.minify,
sourcemap: options.sourcemap
});
return {
code: result.code,
map: result.map
};
};
const unloader = {
options(config) {
config.sourcemap ||= options.sourcemap;
},
load: {
filter: { id: {
include: [/\.json$/, ...toArray(options.include)],
exclude: options.exclude
} },
handler(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"
};
}
return readFileSync(id, "utf8");
}
}
};
return {
name: "unplugin-oxc",
enforce: options.enforce,
resolveId,
transform: transform ? {
filter: { id: {
include: options.include,
exclude: options.exclude
} },
handler: transform
} : void 0,
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 as t };