2017-08-01 8 views
1

Wie liest man die Klassen aus einer Datei?Knoten lesen ts Modul/Code lesen

.src/my-a.service.ts

export class MyAService { 
    ... 
} 

.src/my-b.service.ts

export class MyBService { 
    ... 
} 

./read-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'] 
}); 

Ich weiß, Sie könnten einige String-Parsing tun, aber gibt es eine High-Level-Möglichkeit, js/ts Exporte aus einer Datei zu lesen (nicht den Code importieren, sondern nur die Namen der exportierten Klassen).

Bearbeiten 1: Es gibt X Anzahl der * .service.ts Dateien my-a.service.ts und my-b.service.ts sind nur Beispiele. Ich versuche nicht, diese Klassen zu importieren oder zu benötigen, um sie im Code zu verwenden, sondern erhalte nur die Klassennamen für die Codegenerierung.

Edit 2: Ich mag tsreflect-compiler aussieht, ist, was ich brauche:

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' ] 
}); 

jedoch tsreflect-compiler nur Typoskript 1.4-Compiler verwendet, und ich brauche neuere 2.x. Gibt es eine modernere Lösung?

Antwort

0

Damit endete meine Lösung ist hoch:

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' ] 
}); 
+0

Es gibt auch dieses Projekt https://dsherret.github.io/ts-simple-ast/ –

0

nicht sicher, was Sie Anwendungsfall sind, ist aber der einfachste Weg wäre -

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

Wenn nicht, müssten Sie mit fs in der Datei lesen und dann einige String-Matching/regex tun, um finde alle exportierten Funktionen, die sehr knifflig sein könnten.

+0

Anwendungsfall ist die Codegenerierung. Ich habe x Anzahl von * .service.ts Dateien 'my-a.service.ts' und' my-b.service.ts' sind nur Beispiele. "lies die Datei mit fs ein und mache dann einen String Matching/Regex, um alle exportierten Funktionen zu finden, was sehr knifflig sein könnte." Deshalb habe ich gehofft, dass es einen hohen Level gibt. –

0

Da Javascript/ES6 eigentlich keine Klassen hat, sollten Sie sich nicht auf Klassennamen verlassen.

Was Sie suchen für den Export benannt:

exports.MyBService = class MyBService { 
    ... 
} 

Auf diese Weise können

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

In node.js tun können, würden Sie Dateien exportieren Commonjs Format für Javascript-Dateien.

Basic-Beispiel für js

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

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

modules.exports = { methods } 

Typoskript bekommt das neue es6-Format zu verwenden, aber Sie müssen Ihre Typoskript Compiler-Setup für sie mit Knoten arbeiten.

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

Ich versuche nicht, die Klassen "neu" zu benutzen oder sie im Code zu verwenden, und es gibt X-Nummern von * .service.ts-Dateien my-a.service.ts und my-b.service.ts sind nur Beispiele. –

+0

ist nur ein Beispiel. Sie können einfach 'someClass.method()' – jemiloii

+0

Nicht versuchen, dies zu tun, nur ein String-Array der Namen von allem, was Datei exportiert, ohne zu wissen, was es exportiert. –