@bleed-believer/path-alias
Version:
Assign path alias using tsconfig.json file
88 lines (87 loc) • 3.54 kB
JavaScript
import { basename, dirname, join, normalize, relative } from "path";
import { mkdir, writeFile } from "node:fs/promises";
import { transformFile } from "@swc/core";
import fastGlob from "fast-glob";
import { tsConfigToSwcOptions } from "./ts-config-to-swc-options.js";
import { getTsConfig } from "../get-ts-config/index.js";
import { getOutPath } from "./get-out-path.js";
export class SwcTranspiler {
#transformFile;
#getTsConfig;
#writeFile;
#fastGlob;
#process;
#mkdir;
#path;
constructor(path, injection){
this.#transformFile = injection?.transformFile ?? transformFile;
this.#getTsConfig = injection?.getTsConfig ?? getTsConfig;
this.#writeFile = injection?.writeFile ?? writeFile;
this.#fastGlob = injection?.fastGlob ?? fastGlob;
this.#process = injection?.process ?? process;
this.#mkdir = injection?.mkdir ?? mkdir;
this.#path = path;
}
async getSourceCode(tsConfigResult) {
const tsConfig = tsConfigResult.config;
const include = [];
if (tsConfig.compilerOptions?.rootDir) {
include.push(normalize(join(tsConfig.compilerOptions.rootDir, './**/*.{ts,mts,cjs}')));
}
if (tsConfig.compilerOptions?.rootDirs) {
const rootDirs = tsConfig.compilerOptions.rootDirs.map((x)=>join(x, './**/*.{ts,mts,cjs}')).map((x)=>normalize(x));
include.push(...rootDirs);
}
if (include.length === 0) {
include.push(normalize('./**/*.{ts,mts,cjs}'));
}
const exclude = tsConfigResult.config.exclude ?? [];
exclude.unshift(normalize('./**/node_modules/*'));
include.forEach((_, i)=>{
include[i] = normalize(include[i]);
});
exclude.forEach((_, i)=>{
exclude[i] = normalize(exclude[i]);
});
const sources = await this.#fastGlob(include, {
dot: true,
cwd: dirname(tsConfigResult.path),
ignore: exclude,
absolute: true,
globstar: true,
onlyFiles: true,
objectMode: true
});
return sources.map(({ path })=>({
rootPath: path,
outPath: getOutPath(path, tsConfigResult)
}));
}
async build(callback) {
const tsConfigResult = this.#getTsConfig(this.#path, {
process: this.#process
});
if (!tsConfigResult || !tsConfigResult.config) {
throw new Error('Invalid tsConfigResult provided.');
}
const cwd = dirname(tsConfigResult.path);
const sources = await this.getSourceCode(tsConfigResult);
for (const source of sources){
const swcOptions = tsConfigToSwcOptions(tsConfigResult);
// delete swcOptions.exclude;
await this.#mkdir(dirname(source.outPath), {
recursive: true
});
if (swcOptions.sourceMaps) {
swcOptions.sourceFileName = source.rootPath;
}
let { code, map } = await this.#transformFile(source.rootPath, swcOptions);
if (map && swcOptions.sourceMaps) {
code = `${code}\n\n//# sourceMappingURL=${basename(source.outPath)}.map`;
await this.#writeFile(`${source.outPath}.map`, map, 'utf-8');
}
await this.#writeFile(source.outPath, code, 'utf-8');
callback?.(relative(cwd, source.rootPath), relative(cwd, source.outPath));
}
}
}