-

   rss_rss_hh_new

 - e-mail

 

 -

 LiveInternet.ru:
: 17.03.2011
:
:
: 51

:


[ ] Babel

, 01 2017 . 19:30 +
javascript. , , . , , ? , babel-. , , , babel.


. , (visitors). babel-core. babel-types.

export default function({types: t}) {
    return {
        visitor: {}
    };
}

visitor, (), , FunctionDeclaration StringLiteral ( ), (path) . Identifier.

export default function({types: t}) {
    return {
        visitor: {
            Identifier(path, {opts: options}) {

            }
        }
    };
}

, .opts . , . :

.babelrc
{
    plugins: [[
        "babel-plugin-auto-import",
        { declarations: [{name: "React", path: "react"}] }
    ]]
}

. .


Babel ( ), , . , , . , . , . .["is" + ](). , path.isIdentifier(). , .find(callback), , .findParent(callback). .parentPath .

. . Identifier . . , :

React.Component

:

{
    type: "MemberExpression",
    object: {
        type: "Identifier",
        name: "React"
    },
    property: {
        type: "Identifier",
        name: "Component"
    },
    computed: false
}

.type , , . MemberExpression. . Object . . computed , , x["a" + b]. Property , , .

-, Identifier : React Component . React, Component. , MemberExpression, , .object MemberExpression. :

export default function({types: t}) {
    return {
        visitor: {
            Identifier(path, {opts: options}) {
                if (!isCorrectIdentifier(path))
                    return;
            }
        }
    };

    function isCorrectIdentifier(path) {
        let {parentPath} = path;

        if (parentPath.isMemberExpression() && parentPath.get("object") == path)
            return true;
    }
}

. .

function isCorrectIdentifier(path) {
    let {parentPath} = path;

    if (parentPath.isArrayExpression())
        return true;
    else
    if (parentPath.isArrowFunctionExpression())
        return true;
    else
    if (parentPath.isAssignmentExpression() && parentPath.get("right") == path)
        return true;
    else
    if (parentPath.isAwaitExpression())
        return true;
    else
    if (parentPath.isBinaryExpression())
        return true;
    else
    if (parentPath.bindExpression && parentPath.bindExpression())
        return true;
    else
    if (parentPath.isCallExpression())
        return true;
    else
    if (parentPath.isClassDeclaration() && parentPath.get("superClass") == path)
        return true;
    else
    if (parentPath.isClassExpression() && parentPath.get("superClass") == path)
        return true;
    else
    if (parentPath.isConditionalExpression())
        return true;
    else
    if (parentPath.isDecorator())
        return true;
    else
    if (parentPath.isDoWhileStatement())
        return true;
    else
    if (parentPath.isExpressionStatement())
        return true;
    else
    if (parentPath.isExportDefaultDeclaration())
        return true;
    else
    if (parentPath.isForInStatement())
        return true;
    else
    if (parentPath.isForStatement())
        return true;
    else
    if (parentPath.isIfStatement())
        return true;
    else
    if (parentPath.isLogicalExpression())
        return true;
    else
    if (parentPath.isMemberExpression() && parentPath.get("object") == path)
        return true;
    else
    if (parentPath.isNewExpression())
        return true;
    else
    if (parentPath.isObjectProperty() && parentPath.get("value") == path)
        return !parentPath.node.shorthand;
    else
    if (parentPath.isReturnStatement())
        return true;
    else
    if (parentPath.isSpreadElement())
        return true;
    else
    if (parentPath.isSwitchStatement())
        return true;
    else
    if (parentPath.isTaggedTemplateExpression())
        return true;
    else
    if (parentPath.isThrowStatement())
        return true;
    else
    if (parentPath.isUnaryExpression())
        return true;
    else
    if (parentPath.isVariableDeclarator() && parentPath.get("init") == path)
        return true;

    return false;
}



, . scope. , . .bindings. .parent. , .

export default function({types: t}) {
    return {
        visitor: {
            Identifier(path, {opts: options}) {
                if (!isCorrectIdentifier(path))
                    return;

                let {node: identifier, scope} = path;

                if (isDefined(identifier, scope))
                    return;
            }
        }
    };

    // ...

    function isDefined(identifier, {bindings, parent}) {
        let variables = Object.keys(bindings);

        if (variables.some(has, identifier))
            return true;

        return parent ? isDefined(identifier, parent) : false;
    }

    function has(identifier) {
        let {name} = this;

        return identifier == name;
    }
}

! , . options :

let {declarations} = options;

declarations.some(declaration => {
    if (declaration.name == identifier.name) {
        let program = path.findParent(path => path.isProgram());

        insertImport(program, declaration);

        return true;
    }
});


. , . .reduce, ImportDeclaration:

function insertImport(program, { name, path }) {
    let programBody = program.get("body");

    let currentImportDeclarations =
        programBody.reduce(currentPath => {
            if (currentPath.isImportDeclaration())
                list.push(currentPath);

            return list;
        }, []);
}

, :

let importDidAppend =
    currentImportDeclarations.some(({node: importDeclaration}) => {
        if (importDeclaration.source.value == path) {
            return importDeclaration.specifiers.some(specifier => specifier.local.name == name);
        }
    });

.

babel-types. t. . importDeclaration. , (.. ) .

. (export default ...). . StringLiteral.

let specifier = t.importDefaultSpecifier(t.identifier(name));
let pathToModule = t.stringLiteral(path);

, , :

let importDeclaration = t.importDeclaration([specifier], pathToModule);

. . , .replaceWith(node), , .replaceWithMultiple([...nodes]). .remove(). .insertBefore(node) .insertAfter(node), .

, . program .body, , . -, pushContainer unshiftContainer. :

program.unshiftContainer("body", importNode);

. API Babel, . , . . , . !
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/330018/

:  

: [1] []
 

:
: 

: ( )

:

  URL