2017-05-02 14 views
1

Ich schreibe ein Babel-Plugin, das jeden Import in einen Funktionsaufruf umwandeln sollte, der eine Transformation durchführt. Die Idee ist, diesen Code zu aktivieren:Wie werden grundlegende Importe in Alias-Importe umgewandelt?

import { member } from "module-name"; 
import { member as alias } from "module-name"; 

in diese:

import { member as _member } from "module-name"; 
const member = someTransform(_member); 
import { member as _alias } from "module-name"; 
const alias = someTransform(_alias); 

Also für aliased Importe (siehe AST documentation), habe ich den Namen des Alias ​​ändern möchten; Basisimporte sollten in Aliasimporte umgewandelt werden, damit ich ihre Kennung ändern kann. Das Hinzufügen der Zuweisungen ist trivial, daher werde ich es für den Rest dieser Frage ignorieren.

Gemäß der AST-Dokumentation sind Basis- und Aliasimporte identisch modelliert. Der einzige Unterschied besteht darin, dass die Felder imported und local für einen Basisimport identische IDs enthalten, während sie sich bei einem Aliasimport unterscheiden.

Also dachte ich, ich brauchte nur die local ID für alle ImportSpecifier s zu ändern. Dadurch sollten grundlegende Importe automatisch in Alias-Importe umgewandelt werden. Bei Aliasimporten sollte der Alias ​​geändert werden.

Hier ist mein Code (try it out in the AST explorer).

function transformImportDeclaration(path) { 
    const importSpecifierPaths = path.get('specifiers'); 
    for (const importSpecifierPath of importSpecifierPaths) { 
    const node = importSpecifierPath.node; 
    const id = node.local; 
    node.local = path.scope.generateUidIdentifier(id.name); 
    } 
} 

export default function (babel) { 
    const t = babel.types; 

    return { 
    visitor: { 
     Program(programPath) { 
     const declarations = programPath.get('body').filter(path => t.isImportDeclaration(path)); 
     declarations.forEach(transformImportDeclaration); 
     }, 
    }, 
    }; 
} 

Das Problem ist, dass der resultierende Code ist dies:

import { _member } from "module-name"; 
import { member as _alias } from "module-name"; 

Also nur die zweite Zeile mit dem Alias-Import korrekt umgewandelt. Die erste Zeile mit dem Basisimport wird jedoch nicht in einen Aliasimport konvertiert. Stattdessen bleibt es ein einfacher Import, der jetzt auf den falschen Export hinweist. Ich verstehe nicht, warum das so ist, weil die imported ID des AST immer noch die ursprüngliche ID enthält.

Antwort

0

Dies scheint ein Fehler in Babel zu sein. Ich habe a bug report dort erstellt.

Als Workaround a commenter suggested Ersetzen der Importspezifizierer mit einer modifizierten Kopie. Er fügte auch a working demo on AST explorer hinzu.

Der entsprechende Code ist dies:

importSpecifierPath.replaceWith(
    t.importSpecifier(
    path.scope.generateUidIdentifier(node.imported.name), 
    t.clone(node.imported) 
) 
); 
Verwandte Themen