使用typescript來修改js文件

原理

使用typescript把源代碼讀成ast,然后修改ast結(jié)構(gòu),然后將ast重新還原成js代碼,最后將js代碼重新寫入文件。

具體步驟

將需要修改的代碼以字符串的形式讀進(jìn)來

var file = fs.readFileSync(path, 'utf-8');

使用ts提供的一系列工具函數(shù)來生成和修改ast

const ts = require('typescript')

關(guān)鍵的轉(zhuǎn)換代碼

function transformTS(source, transformer) {
    const sourceFile = ts.createSourceFile(
        'test.ts', source, ts.ScriptTarget.ES2015, true, ts.ScriptKind.TS
    );
    const printer = ts.createPrinter();
    const result = ts.transform(
        sourceFile, [transformer]
    );
    const transformedSourceFile = result.transformed[0];
    const newContent = printer.printFile(transformedSourceFile)
    result.dispose()
    return newContent
}

這個函數(shù)主要是接受一個源代碼字符串,可以是任意的js代碼或者ts代碼,還接受一個transformer,用來對生成的ast(抽象語法樹)進(jìn)行遍歷,根據(jù)需要在對應(yīng)的位置插入或修改。
一個transformer是一個函數(shù),要寫成下面這樣的格式提供給ts.transform函數(shù)

 const transformer = (context) => {
        return (rootNode) => {
            function visit(node) {
                node = ts.visitEachChild(node, visit, context);
                if (ts.isArrowFunction(node)) {
                    console.log(node.body.statements);
                    let newLine = ts.createExpressionStatement(
                        ts.createCall(
                            ts.createPropertyAccess(
                                ts.createIdentifier('router'), 'get'), undefined,
                            [
                                ts.createLiteral(`/${namespace}/${pageName}`),
                                ts.createPropertyAccess(ts.createIdentifier('controller'),
                                    ts.createPropertyAccess(ts.createIdentifier(namespace), pageName))
                            ]))
                    node.body.statements = node.body.statements.concat(newLine);
                }
                return node;
            }
            return ts.visitNode(rootNode, visit);
        }
    }

這個函數(shù)主要是遍歷ast的node節(jié)點,對于匹配的節(jié)點進(jìn)行編輯操作,這個例子中遍歷節(jié)點,在ts.isClassDelaration(node)這里判斷是不是類聲明,如果是的話就給這個類添加一個新的成員方法node.members = node.members.concat(createControllerMethod(pageName))。
將代碼轉(zhuǎn)換之后并沒有執(zhí)行寫入操作,需要將修改后的代碼重新寫入

fs.writeFileSync('app/router.ts', result);
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容