「这是我参加2022首次更文挑战的第1天,流动详情查看:2022首次更文挑战」。

Dear,大家好,我是“前端小鑫同学”,长期从事前端开发,安卓开发,热衷技术,在编程路上越走越远~

通常在编写完TypeScript代码当前总是须要通过其内置的CLI来编译为JavaScript文件,再通过node来执行,当然也有简化操作的库,如:ts-node。上面就来摸索一下如何实现相似ts-node能够间接执行TypeScript的性能吧。

前提概要:

1. 波及知识点:

  1. NodeJs:require函数
  2. TypeScript:Compiler API

    2. 工作拆解:

  3. 如何让Node意识Ts文件;
  4. 如何让Ts文件变为Js文件。

    3. require函数的执行过程: module.js

  5. Module.prototype.require(path):

    1. 依据传入path来确定待加载模块的绝对路径;
    2. 执行模块加载(程序:1. 优先缓存,2. 内置模块,3. 生成实例并存入缓存)
  6. Module.prototype.load(filename):

    1. 通过文件名称辨认后缀为.js,.json,.node的文件并读取内容;
    2. 通过Module内置的_compile函数进行模块化编译。

      如何辨认ts文件:

  7. module中如何辨认js文件:

    Module._extensions['.js'] = function(module, filename) {  var content = fs.readFileSync(filename, 'utf8');  module._compile(stripBOM(content), filename);};
  8. 仿照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.jsconst 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 来深刻了解它的原理


欢送关注我的公众号“前端小鑫同学”,原创技术文章第一工夫推送。