rollup-plugin-ngc
Version:
Rollup plugin for angular with ivy enable
108 lines (102 loc) • 3.72 kB
JavaScript
import { join, dirname, resolve } from 'path';
import { ScriptTarget, ModuleKind, ModuleResolutionKind } from 'typescript';
import { createProgram, createCompilerHost } from '@angular/compiler-cli';
import { existsSync, statSync, readdirSync } from 'fs';
import { buildOptimizer } from '@angular-devkit/build-optimizer';
function resolver(extensions) {
const _extensions = ["ts", ...extensions != null ? extensions : []];
const resolveFile = (resolved, index = false) => {
for (const extension of _extensions) {
const file = index ? join(resolved, `index.${extension}`) : `${resolved}.${extension}`;
if (existsSync(file))
return file;
}
};
return function resolveId(id, origin) {
if (!origin || id.includes("node_modules"))
return id;
const resolved = join(dirname(origin), id);
const file = resolveFile(resolved);
if (file)
return file;
if (existsSync(resolved) && statSync(resolved).isDirectory()) {
const coreFile = resolveFile(resolved, true);
if (coreFile)
return coreFile;
}
};
}
function compile(opts) {
const {id, host, options, files} = opts;
const programm = createProgram({rootNames: [id], options, host});
programm.emit();
const file = id.replace(".ts", "");
const map = files.get(`${file}.js.map`);
const code = files.get(`${file}.js`);
return {
code: (code != null ? code : "").replace(/\/\/# sourceMappingURL.*/, ""),
map
};
}
const defautSideEffects = (sideEffectFreeModules) => {
const sideEffects = readdirSync("node_modules/@angular").map((effect) => join("node_modules/@angular", effect));
return [
...sideEffects,
"node_modules/rxjs",
...sideEffectFreeModules != null ? sideEffectFreeModules : []
].map((p) => p.replace(/\\/g, "/"));
};
function optimizer(content, id, options) {
const normalizedId = id.replace(/\\/g, "/");
const isSideEffectFree = options.sideEffectFreeModules && options.sideEffectFreeModules.some((m) => normalizedId.indexOf(m) >= 0);
const isAngularCoreFile = options.angularCoreModules && options.angularCoreModules.some((m) => normalizedId.indexOf(m) >= 0);
const result = buildOptimizer({
content,
inputFilePath: id,
emitSourceMap: true,
isSideEffectFree,
isAngularCoreFile
});
return {
code: result.content,
map: result.sourceMap
};
}
function ngcPlugin(options) {
let host, files = new Map(), sideEffectFreeModules;
const {target = "es2018", rootDir = "src", sourceMap = true} = options;
const opts = {
target: ScriptTarget[target.toLocaleUpperCase()],
module: ModuleKind.ESNext,
lib: ["dom", "es2015", "es2017", "es2018", "es2019"],
rootDir: resolve(rootDir),
moduleResolution: ModuleResolutionKind.NodeJs,
esModuleInterop: true,
declaration: false,
experimentalDecorators: true,
emitDecoratorMetadata: true,
enableIvy: true,
sourceMap
};
return {
name: "ngc",
buildStart: () => {
var _a;
sideEffectFreeModules = defautSideEffects((_a = options == null ? void 0 : options.buildOptimizer) == null ? void 0 : _a.sideEffectFreeModules);
host = createCompilerHost({options: opts});
host.writeFile = (fileName, contents) => files.set(fileName, contents);
},
resolveId: resolver(),
transform(code, id) {
var _a;
if (!id.includes("node_modules")) {
return compile({id: resolve(id).replace(/\\/g, "/"), host, options: opts, files});
}
return optimizer(code, id, {
sideEffectFreeModules,
angularCoreModules: (_a = options == null ? void 0 : options.buildOptimizer) == null ? void 0 : _a.angularCoreModules
});
}
};
}
export { ngcPlugin };