节点读取ts模块/读取代码文件

时间:2017-08-01 16:15:56

标签: javascript node.js file typescript

如何从文件中读取类?

的.src /我的-a.service.ts

export class MyAService {
    ...
}

的.src /我的-b.service.ts

export class MyBService {
    ...
}

./读modules.js

const fs = require('fs');
const _ = require('lodash');

let files = fs.readdirSync('./src')
    .filter(item => {
        return _.includes(item, '.service.ts')
    });


files.forEach(item => {
    // get ['MyAService', 'MyBService']
});

我知道你可以做一些字符串解析,但有一种高级方法可以从文件读取js / ts导出(不导入代码,只是获取导出类的名称)。

编辑1: 有多个* .service.ts文件my-a.service.tsmy-b.service.ts只是示例。我不是要导入或要求这些类在代码中使用它们只需获取代码生成的类名。

编辑2: 我觉得tsreflect-compiler就像我需要的那样:

const fs = require('fs');
const _ = require('lodash');
const compiler = require('tsreflect-compiler');

let files = fs.readdirSync('./src')
    .filter(item => {
        return _.includes(item, '.service.ts')
    });


let mods = new Map();
files.forEach(item => {
    let diag = compiler.compile(
        [`./src/${item}`],
        {
            noLib: false,
            suppressImplicitAnyIndexErrors: true,
            noImplicitAny: false,
            module: 'ES2015',
            moduleResolution: 'Node',
            target: 'ES5'
        },
        {
            readFile: (filename, onError) => {
                let text;
                try {
                    text = fs.readFileSync(filename, 'utf8');
                } catch (error) {
                    if (onError) {
                        onError(e.message);
                    }
                    text = '';
                }
                return text;
            },
            writeFile: (fileName, data, writeByteOrderMark, onError) => {
                mods.set(item, JSON.parse(data).declares.map(d => d.name));
            }
        }
    );
});

mods.forEach((value, key) => {
    console.log(key); // my-a.service.ts
    console.dir(value); // [ 'MyAService' ]
});

但是tsreflect-compiler只使用TypeScript 1.4编译器,我需要2.x更新。有更现代的解决方案吗?

4 个答案:

答案 0 :(得分:0)

不确定您使用的是什么情况,但最简单的方法是 -

const serviceA = require('./MyAService');
const keys = Object.keys(serviceA);

如果没有,您必须使用fs读取文件,然后执行一些字符串匹配/正则表达式来查找所有导出的函数,这可能非常棘手。

答案 1 :(得分:0)

由于Javascript / ES6实际上没有课程,因此您不应该依赖课程名称。

您正在寻找的是名为exports:

exports.MyBService = class MyBService {
    ...
}

你可以这样做

const allServices = require('./myservices')
console.log(Object.keys(allServices))

答案 2 :(得分:0)

在node.js中,您可以使用javascript文件的commonjs格式导出​​文件。

js的基本示例

const someModule = require('./someModule');

const methods = param => { return param; };

modules.exports = { methods }

Typescript可以使用新的es6格式,但是你需要设置你的typescript编译器才能使用它。

import someClass from './someClass';
someClass.method();
export class name { .. }

答案 3 :(得分:0)

这最终成为我的解决方案:

const fs = require('fs');
const _ = require('lodash');
const ts = require('typescript');

let files = fs.readdirSync('./src')
    .filter(item => _.includes(item, '.service.ts'));

let mods = new Map();
files.forEach(file => {
    let ex = [];
    // https://github.com/Microsoft/TypeScript/wiki/Using-the-Compiler-API#using-the-type-checker
    // Build a program using the set of root file names in fileNames
    let program = ts.createProgram(
        [`./src/${file}`],
        {
            module: ts.ModuleKind.ES2015,
            moduleResolution: ts.ModuleResolutionKind.NodeJs,
            target: ts.ScriptTarget.ES5
        }
    );
    // Get the checker, we will use it to find more about classes
    let checker = program.getTypeChecker();
    // Visit every sourceFile in the program
    program.getSourceFiles()
        .filter(sourceFile => _.includes(sourceFile.fileName, file))
        .forEach(sourceFile => {
            // Walk the tree to search for classes
            ts.forEachChild(sourceFile, node => {
                if (node.kind === ts.SyntaxKind.ClassDeclaration) {
                    // This is a top level class, get its symbol
                    let symbol = checker.getSymbolAtLocation(node.name);
                    ex.push(symbol.getName());
                }
            });
        });
    mods.set(file, ex);
});

mods.forEach((value, key) => {
    console.log(key); // my-a.service.ts
    console.dir(value); // [ 'MyAService' ]
});