@ainc/script
Version:
Script compiler for typescript
182 lines • 5.36 kB
JavaScript
/**
*****************************************
* Created by edonet@163.com
* Created on 2020-07-04 21:01:05
*****************************************
*/
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.findDependencies = exports.refresh = exports.clear = exports.load = void 0;
/**
*****************************************
* 加载依赖
*****************************************
*/
const fs = require("fs");
const transform = require("./transform");
const json_1 = require("./helpers/json");
/**
*****************************************
* 脚本对象
*****************************************
*/
const Script = require('module');
/**
*****************************************
* 模块加载函数
*****************************************
*/
const moduleExtensions = Script._extensions;
const moduleImportHandler = Script.prototype.require;
/**
*****************************************
* 生成脚本解析函数
*****************************************
*/
function makeCompileHandler(transformScript) {
return function compile(script, filename) {
const code = script._code ?? fs.readFileSync(filename, 'utf8');
// 转换代码
const source = transformScript(filename, code);
// 更新加载函数
script.require = dynamicImportScript;
// 编译内容
script._compile(transformScript(filename, source), filename);
};
}
/**
*****************************************
* 模块解析器
*****************************************
*/
const moduleCompiler = {
js: makeCompileHandler(transform.transformJavaScript),
ts: makeCompileHandler(transform.transformTypeScript),
jsx: makeCompileHandler(transform.transformJSXScript),
tsx: makeCompileHandler(transform.transformTSXScript),
json: json_1.json,
};
/**
*****************************************
* 执行函数
*****************************************
*/
function invoke(handler) {
const cached = { ...Script._extensions };
// 更新处理函数
moduleExtensions['.ts'] = moduleCompiler.ts;
moduleExtensions['.js'] = moduleCompiler.js;
moduleExtensions['.mjs'] = moduleCompiler.js;
moduleExtensions['.jsx'] = moduleCompiler.jsx;
moduleExtensions['.tsx'] = moduleCompiler.tsx;
moduleExtensions['.json'] = moduleCompiler.json;
// 执行函数
const result = handler();
// 恢复处理函数
moduleExtensions['.ts'] = cached['.ts'];
moduleExtensions['.js'] = cached['.js'];
moduleExtensions['.mjs'] = cached['.mjs'];
moduleExtensions['.jsx'] = cached['.jsx'];
moduleExtensions['.tsx'] = cached['.tsx'];
moduleExtensions['.json'] = cached['.json'];
// 返回结果
return result;
}
/**
*****************************************
* 动态载入脚本
*****************************************
*/
function dynamicImportScript(id) {
return invoke(() => moduleImportHandler.call(this, id));
}
/**
*****************************************
* 加载脚本
*****************************************
*/
function load(filename, code) {
const script = new Script(filename, module);
// 设置代码
script._code = code;
// 加载文件
invoke(() => script.load(filename));
// 返回结果
return script;
}
exports.load = load;
/**
*****************************************
* 清除缓存
*****************************************
*/
function clear(file) {
// 清除缓存
if (Script._cache[file]) {
Script._cache[file] = undefined;
}
// 返回文件地址
return file;
}
exports.clear = clear;
/**
*****************************************
* 刷新脚本依赖
*****************************************
*/
function refresh(script, files) {
const refreshAll = !files.length;
// 清除子脚本
function refreshChildren(children) {
if (children && children.length) {
return children.filter(refreshScript);
}
}
// 清除函数
function refreshScript(script) {
const file = script.filename;
const children = refreshChildren(script.children);
// 清除当前模块
if (refreshAll || files.includes(file) || (children && children.length)) {
return !!clear(file);
}
}
// 清除缓存
script.children && script.children.forEach(refreshScript);
}
exports.refresh = refresh;
/**
*****************************************
* 解析依赖
*****************************************
*/
function findDependencies(script) {
const cached = new Set();
const deps = [];
// 遍历函数
function each(list) {
// 遍历子模块
if (list && list.length) {
list.forEach(script => cached.has(script) || add(script));
}
// 返回依赖列表
return deps;
}
// 添加依赖
function add(script) {
const filename = script.filename;
// 添加缓存
cached.add(script);
// 过滤三方模块
if (filename.indexOf('node_modules') === -1) {
// 添加文件
deps.push(filename);
// 处理子模块
each(script.children);
}
}
// 遍历子节点
return each(script.children);
}
exports.findDependencies = findDependencies;
//# sourceMappingURL=vm.js.map