feat: improve transpiler infrastructure
This commit is contained in:
parent
74f08b7483
commit
6c8c329992
@ -31,7 +31,7 @@ task compileEnv(type: NpmTask) {
|
||||
}
|
||||
task compileTypescript(type: NpmTask) {
|
||||
inputs.files('rollup.config.js');
|
||||
inputs.dir('src/lib/ts');
|
||||
inputs.dir('src/lib/transpiler');
|
||||
outputs.files("build/js/ts.js");
|
||||
// nom nom tasty ram
|
||||
environment.put("NODE_OPTIONS", "--max-old-space-size=4096");
|
||||
|
@ -1,10 +1,17 @@
|
||||
{
|
||||
"scripts": {
|
||||
"build-env": "rollup -c --environment INPUT:src/lib/libs/_entry.ts,OUTPUT:build/js/index.js,POLYFILLS:src/lib/libs/polyfills",
|
||||
"build-ts": "rollup -c --environment INPUT:src/lib/ts/_entry.ts,OUTPUT:build/js/ts.js"
|
||||
"build-ts": "rollup -c --environment INPUT:src/lib/transpiler/_entry.ts,OUTPUT:build/js/ts.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/core": "^7.26.0",
|
||||
"@babel/runtime": "^7.26.0",
|
||||
"@babel/standalone": "^7.26.4",
|
||||
"@rollup/plugin-json": "^6.1.0",
|
||||
"@types/babel__preset-env": "^7.9.7",
|
||||
"@types/babel__standalone": "^7.1.9",
|
||||
"@types/coffeescript": "^2.5.7",
|
||||
"coffeescript": "^2.7.0",
|
||||
"typescript": "^5.7.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
@ -4,6 +4,7 @@ const typescript = require("@rollup/plugin-typescript");
|
||||
const babel = require("@rollup/plugin-babel");
|
||||
const commonjs = require("@rollup/plugin-commonjs");
|
||||
const nodeResolve = require("@rollup/plugin-node-resolve");
|
||||
const json = require("@rollup/plugin-json");
|
||||
const { resolve } = require("path");
|
||||
|
||||
const shouldMinify = () => false;
|
||||
@ -21,6 +22,7 @@ const construct = (input, output) => defineConfig({
|
||||
},
|
||||
commonjs(),
|
||||
nodeResolve(),
|
||||
json(),
|
||||
babel({
|
||||
extensions: [],
|
||||
exclude: ["node_modules/**"],
|
||||
@ -107,6 +109,14 @@ const construct = (input, output) => defineConfig({
|
||||
path: "null",
|
||||
os: "null",
|
||||
inspector: "null",
|
||||
tty: "null",
|
||||
util: "null",
|
||||
assert: "null",
|
||||
url: "null",
|
||||
"@babel/preset-typescript/package.json": "null",
|
||||
module: "null",
|
||||
process: "null",
|
||||
v8: "null",
|
||||
},
|
||||
// plugins: [babel.getBabelOutputPlugin({
|
||||
// allowAllFormats: true,
|
||||
|
4
src/lib/transpiler/_entry.ts
Normal file
4
src/lib/transpiler/_entry.ts
Normal file
@ -0,0 +1,4 @@
|
||||
import coffeescript from "./coffeescript.ts";
|
||||
import babel from "./babel.ts";
|
||||
|
||||
register(v => coffeescript(babel(v)));
|
25
src/lib/transpiler/babel.ts
Normal file
25
src/lib/transpiler/babel.ts
Normal file
@ -0,0 +1,25 @@
|
||||
import { SourceMap } from "./map.ts";
|
||||
import { transform } from "@babel/standalone";
|
||||
// import presetEnv from "@babel/preset-env";
|
||||
|
||||
export default function babel(next: Compiler): Compiler {
|
||||
print("Loaded babel!");
|
||||
|
||||
return (filename, code, prevMap) => {
|
||||
const res = transform(code, {
|
||||
filename,
|
||||
sourceMaps: true,
|
||||
});
|
||||
|
||||
const map = SourceMap.parse({
|
||||
file: "babel-internal://" + filename,
|
||||
mappings: res.map!.mappings,
|
||||
sources: [filename],
|
||||
});
|
||||
|
||||
const compiled = next("babel-internal://" + filename, res.code!, SourceMap.chain(map, prevMap));
|
||||
registerSource(filename, code);
|
||||
return compiled;
|
||||
};
|
||||
}
|
||||
|
28
src/lib/transpiler/coffeescript.ts
Normal file
28
src/lib/transpiler/coffeescript.ts
Normal file
@ -0,0 +1,28 @@
|
||||
import { compile } from "coffeescript";
|
||||
import { SourceMap } from "./map.ts";
|
||||
|
||||
export default function coffee(next: Compiler): Compiler {
|
||||
print("Loaded coffeescript!");
|
||||
|
||||
return (filename, code, prevMap) => {
|
||||
const {
|
||||
js: result,
|
||||
v3SourceMap: rawMap,
|
||||
} = compile(code, {
|
||||
filename,
|
||||
sourceMap: true,
|
||||
bare: true,
|
||||
});
|
||||
|
||||
const map = SourceMap.parse({
|
||||
file: "coffee-internal://" + filename,
|
||||
mappings: JSON.parse(rawMap).mappings,
|
||||
sources: [filename],
|
||||
});
|
||||
|
||||
const compiled = next("coffee-internal://" + filename, result, SourceMap.chain(map, prevMap));
|
||||
registerSource(filename, code);
|
||||
return compiled;
|
||||
};
|
||||
}
|
||||
|
@ -123,13 +123,16 @@ export class VLQSourceMap {
|
||||
|
||||
public static parseVLQ(compiled: string, filenames: string[], raw: string): VLQSourceMap {
|
||||
const mapping = decodeVLQ(raw);
|
||||
const res = new Map<string, [start: number, dst: Location][][]>();
|
||||
const file: [start: number, dst: Location][][] = [];
|
||||
const res = new Map<string, [start: number, dst: Location][][]>([[compiled, file]]);
|
||||
|
||||
let originalRow = 0;
|
||||
let originalCol = 0;
|
||||
let originalFile = 0;
|
||||
const lastCols = new Set<number>();
|
||||
|
||||
for (let compiledRow = 0; compiledRow < mapping.length; compiledRow++) {
|
||||
const line = file[compiledRow] ??= [];
|
||||
let compiledCol = 0;
|
||||
|
||||
for (const rawSeg of mapping[compiledRow]) {
|
||||
@ -138,12 +141,13 @@ export class VLQSourceMap {
|
||||
originalRow += rawSeg.length > 2 ? rawSeg[2] : 0;
|
||||
originalCol += rawSeg.length > 3 ? rawSeg[3] : 0;
|
||||
|
||||
let file = res.get(compiled);
|
||||
if (file == null) res.set(compiled, file = []);
|
||||
|
||||
const line = file[compiledRow] ??= [];
|
||||
if (!lastCols.has(compiledCol)) {
|
||||
line[line.length] = [compiledCol, [filenames[originalFile], originalRow, originalCol]];
|
||||
}
|
||||
lastCols.add(compiledCol);
|
||||
}
|
||||
|
||||
line.sort((a, b) => a[0] - b[0]);
|
||||
}
|
||||
|
||||
return new VLQSourceMap(res);
|
10
src/lib/transpiler/types.ts
Normal file
10
src/lib/transpiler/types.ts
Normal file
@ -0,0 +1,10 @@
|
||||
import { type SourceMap } from "./map.ts";
|
||||
|
||||
declare global {
|
||||
type CompilerFactory = (next: Compiler) => Compiler;
|
||||
type Compiler = (filename: string, src: string, mapper: SourceMap) => Function;
|
||||
|
||||
function print(...args: any[]): void;
|
||||
function register(factory: CompilerFactory): void;
|
||||
function registerSource(filename: string, src: string): void;
|
||||
}
|
@ -17,7 +17,7 @@ function resource(name: string) {
|
||||
else return resources[name] = getResource(name);
|
||||
}
|
||||
|
||||
register(next => {
|
||||
export default function typescript(next: Compiler): Compiler {
|
||||
const files: Record<string, IScriptSnapshot> = {};
|
||||
const versions: Record<string, number> = {};
|
||||
let declI = 0;
|
||||
@ -34,6 +34,7 @@ register(next => {
|
||||
forceConsistentCasingInFileNames: true,
|
||||
declaration: true,
|
||||
sourceMap: true,
|
||||
downlevelIteration: true,
|
||||
};
|
||||
|
||||
let service: LanguageService;
|
||||
@ -114,7 +115,7 @@ register(next => {
|
||||
const result = outputs["/src.js"];
|
||||
const declaration = outputs["/src.d.ts"];
|
||||
|
||||
const compiled = next("ts-internal://" + filename, result, SourceMap.chain(prevMap, map));
|
||||
const compiled = next("ts-internal://" + filename, result, SourceMap.chain(map, prevMap));
|
||||
registerSource(filename, code);
|
||||
|
||||
return function (this: any) {
|
||||
@ -123,4 +124,4 @@ register(next => {
|
||||
return res;
|
||||
};
|
||||
};
|
||||
});
|
||||
}
|
Loading…
Reference in New Issue
Block a user