カスタムTransformerとコード生成
ASTを変更するコンパイラ変換を記述します。
「カスタムTransformerとコード生成」はCoddyKit上の無料TypeScript Academyレッスンです。 これはレッスン3/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはTypeScript Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 TypeScript Academyコースには全4レッスンが含まれています。
トランスフォーマーとは
TypeScript のトランスフォーマーは、AST ノードを受け取り、変更されたノードまたは元のノードを返す関数です。コンパイル中に実行され、カスタム出力を生成します。
import ts from "typescript";
type Transformer = ts.TransformerFactory<ts.SourceFile>;トランスフォーマーファクトリの形
トランスフォーマーファクトリはTransformationContextを受け取り、SourceFileノードを変換する関数を返します。
const myTransformer: ts.TransformerFactory<ts.SourceFile> =
(ctx) => (sf) => {
function visit(node: ts.Node): ts.Node {
// Modify node here
return ts.visitEachChild(node, visit, ctx);
}
return ts.visitNode(sf, visit) as ts.SourceFile;
};コンテキストを使った訪問
トランスフォーマー内部では、forEachChildではなくts.visitEachChildを使用します。変更されたノードを正しく再構築できるためです。
function visit(node: ts.Node): ts.Node {
if (ts.isStringLiteral(node)) {
return ts.factory.createStringLiteral(node.text.toUpperCase());
}
return ts.visitEachChild(node, visit, ctx);
}ts.factory による新しいノードの作成
ts.factoryオブジェクトには、あらゆる種類の AST ノードを作成するメソッドが用意されています。
const newCall = ts.factory.createCallExpression(
ts.factory.createIdentifier("console.log"),
undefined,
[ts.factory.createStringLiteral("hello")]
);プログラムへのトランスフォーマーの適用
トランスフォーマーをprogram.emitのcustomTransformersオプションに渡します。
program.emit(undefined, undefined, undefined, false, {
before: [myTransformer],
});コード生成: ノードの印刷
ts.createPrinterを使うと、完全なコンパイラーを実行せずに AST ノードをソースコード文字列へ戻せます。
const printer = ts.createPrinter({ newLine: ts.NewLineKind.LineFeed });
const result = printer.printNode(
ts.EmitHint.Unspecified,
newCall,
sf
);
console.log(result); // console.log("hello")ソースファイル全体の生成
ts.factory.createSourceFileを使うか、ステートメントノードのリストを組み立てることで、完全なソースファイルを一から作成できます。
const statements = [
ts.factory.createExpressionStatement(
ts.factory.createCallExpression(
ts.factory.createIdentifier("console.log"),
undefined,
[ts.factory.createStringLiteral("generated!")]
)
),
];インポートの変換
よくある用途はインポートパスの変換です。たとえば、出力時にエイリアスパスを相対パスへ書き換えます。
if (ts.isImportDeclaration(node)) {
const spec = node.moduleSpecifier as ts.StringLiteral;
if (spec.text.startsWith("@app/")) {
return ts.factory.updateImportDeclaration(
node, node.modifiers, node.importClause,
ts.factory.createStringLiteral(spec.text.replace("@app/", "../")),
node.assertClause
);
}
}トランスフォーマーのテスト
小さなソースファイルにトランスフォーマーを適用し、印刷された出力が期待する文字列と一致することを確認してテストします。
const result = ts.transpileModule("const x = 'hello';", {
compilerOptions: { target: ts.ScriptTarget.ES2020 },
transformers: { before: [myTransformer] },
});
console.log(result.outputText);プラグインシステム
一部のビルドツール(ttypescript / ts-patch など)では、トランスフォーマーを tsconfig のプラグインとして登録できます。これにより、開発ワークフローから意識せずに利用できます。
// tsconfig.json with ts-patch:
// "plugins": [{ "transform": "./my-transformer.js" }]まとめ: カスタムトランスフォーマー
トランスフォーマーを使うと、コンパイル中に AST レベルで TypeScript コードを書き換えられます。再帰的な走査にはts.visitEachChild、ノードの作成にはts.factory、ソーステキストの生成にはts.createPrinterを使用します。
理解度チェック
トランスフォーマーで新しい AST ノードを作成するには、どのオブジェクトを使いますか?
学習内容
カスタムトランスフォーマーは、コンパイル時に TypeScript AST を変更します。再帰にはts.visitEachChild、新しいノードの構築にはts.factory、適用にはcustomTransformersを指定したprogram.emitを使用します。
よくある質問
「カスタムTransformerとコード生成」レッスンは無料ですか?
はい。「カスタムTransformerとコード生成」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、TypeScript Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 TypeScript Academyコースには全4レッスンが含まれています。
「カスタムTransformerとコード生成」で何を学びますか?
ASTを変更するコンパイラ変換を記述します。 ブラウザで直接実行するハンズオンコードでTypeScript Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
TypeScript Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのTypeScript Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン3/4です。
「カスタムTransformerとコード生成」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このTypeScript Academyレッスンでコードを書いて実行できますか?
はい。すべてのTypeScript Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- APIによるTypeScriptプログラムの作成
- VisitorによるASTの走査
- カスタムTransformerとコード生成
- 簡単なLintツールの構築