fluorine-loader
Version:
A webpack loader to compile fluorine specializations and catalyst handlers.
112 lines (96 loc) • 3.03 kB
text/typescript
import { getOptions } from "loader-utils";
import { performance } from "perf_hooks";
import { RawSourceMap } from "source-map";
import sorcery = require("source-map");
import { loader } from "webpack";
import { transform } from "./transformer";
let now = performance.now;
export interface Options {
benchmark?: boolean;
sourceMap?: boolean;
_filename?: string;
}
function fluorine_loader(
this: loader.LoaderContext,
source: string | Buffer,
last_sourcemap: RawSourceMap | undefined
) {
let opts: Options = getOptions(this) || {};
if (opts.sourceMap === undefined) opts.sourceMap = this.sourceMap;
opts._filename = this.resource;
let callback = this.async()!;
_async_loader(source, last_sourcemap, opts)
.then(([code, sourcemap]) => {
callback(null, code, sourcemap as any);
})
.catch(err => {
callback(err);
});
return undefined;
}
export default fluorine_loader;
async function _async_loader(
source: string | Buffer,
last_sourcemap: RawSourceMap | undefined,
opts: Options = {}
): Promise<[string, RawSourceMap?]> {
let { code, sourcemap: next_sourcemap, performance: time } = await transform(
source instanceof Buffer ? source.toString() : source,
{ sourcemap: opts.sourceMap, now }
);
if (next_sourcemap) {
let merged_sourcemap = next_sourcemap;
if (last_sourcemap) {
next_sourcemap.file = last_sourcemap.file;
next_sourcemap.sourceRoot = last_sourcemap.sourceRoot;
let source_gen = sorcery.SourceMapGenerator.fromSourceMap(
await new sorcery.SourceMapConsumer(next_sourcemap)
);
source_gen.applySourceMap(
await new sorcery.SourceMapConsumer(last_sourcemap)
);
merged_sourcemap = source_gen.toJSON();
}
time.sourcemap = now();
if (opts.benchmark) show_performance(time, opts);
return [code, merged_sourcemap];
} else {
if (opts.benchmark) show_performance(time, opts);
return [code];
}
}
function show_performance(time: { [key: string]: number }, opts: Options = {}) {
console.log(
" Fluorine Loader transformed",
opts._filename,
"in",
i(
(time.sourcemap !== undefined ? time.sourcemap : time.walk) - time.start
) + "ms"
);
console.log(
`
- parse ..................${h(time.parse - time.start)}ms
- walk ...................${h(time.walk - time.parse)}ms
- visit ................${h(time.visit)}ms
- transform_element ..${h(time.transform_element)}ms
- transform_catalyst .${h(time.transform_catalyst)}ms
- md5 ..................${h(time.md5)}ms
${
time.sourcemap !== undefined
? `- sourcemap ..............${h(time.sourcemap - time.walk)}ms`
: ""
}
`.slice(1, -1)
);
}
function h(num: number) {
let prefix = "";
for (let ix = 0; ix < 3 - ("" + Math.floor(num)).length; ix += 1)
prefix += ".";
return prefix + " " + i(num);
}
function i(num: number) {
if (Math.floor(num) == num) return "" + num;
else return num.toFixed(3);
}