如何不使用tsc编译来执行TypeScript代码
2023-02-18 16:41:28 时间
Dear,大家好,我是“前端小鑫同学”,?长期从事前端开发,安卓开发,热衷技术,在编程路上越走越远~
通常在编写完TypeScript代码以后总是需要通过其内置的CLI来编译为JavaScript文件,再通过node来执行,当然也有简化操作的库,如:ts-node。下面就来探索一下如何实现类似ts-node可以直接执行TypeScript的功能吧。
前提概要:
1. 涉及知识点:
NodeJs:require函数
TypeScript:Compiler API
2. 任务拆解:
如何让Node认识Ts文件;
如何让Ts文件变为Js文件。
3. require函数的执行过程: module.js
Module.prototype.require(path):
- 根据传入path来确定待加载模块的绝对路径;
- 执行模块加载(顺序:1. 优先缓存,2. 内置模块,3. 生成实例并存入缓存)
Module.prototype.load(filename):
- 通过文件名称识别后缀为.js,.json,.node的文件并读取内容;
- 通过Module内置的_compile函数进行模块化编译。如何识别ts文件:
module中如何识别js文件:
Module._extensions['.js'] = function(module, filename) {
var content = fs.readFileSync(filename, 'utf8');
module._compile(stripBOM(content), filename);
};
仿照module的源码处理来实现识别ts文件:
const fs = require('fs');
require.extensions['.ts'] = function (module, filename) {
var content = fs.readFileSync(filename, 'utf8');
console.log(filename);
console.log(content);
};
require('./index.ts')
将TypeScript代码转义为JavaScript代码,下图为Ts Compiler API的Wiki内容截图提供了最简单的实现API:
const ts = require('typescript');
// 编译前的Ts内容
const content = `
enum PersonType {
MAN = 1,
WOMAN = 2,
}
if (PersonType.MAN === 1) {
console.log('hello ts');
}
`;
const { outputText } = ts.transpileModule(content, {
compilerOptions: { module: ts.ModuleKind.CommonJS }
})
// 编译后的Js内容:
/*
var PersonType;
(function (PersonType) {
PersonType[PersonType["MAN"] = 1] = "MAN";
PersonType[PersonType["WOMAN"] = 2] = "WOMAN";
})(PersonType || (PersonType = {}));
if (PersonType.MAN === 1) {
console.log('hello ts');
}
*/
console.log(outputText);
复制代码
Ts执行器完整代码:
// ts-actuator.js
const path = require('path');
const fs = require('fs');
const ts = require('typescript');
// 从命令行获取下标为2的参数(待执行的ts文件名称)
const filePath = process.argv[2];
// 增加支持.ts文件后缀的检测
require.extensions['.ts'] = function (module, filename) {
// 得到绝对ts文件的路径并读取内容
const fileFullPath = path.resolve(__dirname, filename);
const content = fs.readFileSync(fileFullPath, 'utf-8');
// 通过Ts提供的transpileModule将Ts字符串转为Js字符串
const { outputText } = ts.transpileModule(content, {
compilerOptions: { module: ts.ModuleKind.CommonJS }
})
// 将得到的Js字符串进行模块编译
module._compile(outputText, filename);
}
// 执行模块的require函数
require(filePath);
复制代码
结语:
看了光哥的文章,自己写了两遍找了找感觉,很神奇,光哥的文章地址:手写一个 ts-node 来深入理解它的原理
相关文章
- 论文速递2022.8.17!
- Disco Diffusion VS Stable Diffusion效果对比! 论文速递2022.8.18!
- 论文速递2022.8.19!
- 论文速递2022.8.22!
- 论文速递2022.8.23!
- DataGrip激活码,DataGrip2022最新_DataGrip使用说明
- 帅爆! 赛博朋克特效实现
- 论文速递2022.8.24!
- STABLE Diffusion 权重公布! 注册可下载使用论文速递2022.8.25!
- 论文速递2022.8.26!
- CVPR2022 | 视频摩尔纹去除 ! 论文速递2022.8.29!
- [javaEE] EL表达式调用java方法
- 赛博朋克特效实现 ! 附源码
- [javaEE] EL表达式获取数据
- 输入位置,控制 StyleGAN 生成图像的布局! 论文速递2022.8.31!
- 论文速递2022.9.1!
- 论文速递2022.9.2!
- X-NeRF!一种基于神经辐射场公式的学习交叉光谱场景表示的新方法! 论文速递2022.9.5!
- ECCV2022 | SimpleRecon 无需 3D 卷积的高质量三维重建方案! 论文速递2022.9.7!
- 交通灯数据集,涵盖城市和郊区! 论文速递2022.9.8!