1

我正在构建一个共享组件库,React 和 Vue 都将使用它。

我正在使用 Styletron,它需要一个特定于框架的适配器,但在其他方面的工作原理几乎相同。

因此,从我的源代码(一堆函数)中,我需要生成一个文件夹,其中的代码正常转译,然后生成另一个文件夹,其中函数稍作修改。

这是我的代码:

const MyComponent = styled('div', ({ isActive, hasBorder}) => ({
  color: 'red'
}))

// should not change
const OtherComponent = styled('div', {
  background: 'blue'
})

它应该变成:

const MyComponent = styled('div', ({ isActive, hasBorder}) => ({
  color: 'red'
}), ['isActive', 'hasBorder'])

const OtherComponent = styled('div', {
  background: 'blue'
})

我实际上有一个在ASTExplorer中工作的工作示例,但是当我尝试用它制作插件时,我遇到了错误Babel plugin error unknown node of type undefined with constructor "String"

这是我的第一个插件,我知道我做错了一些事情,但现在我只需要找出我必须做什么才能在ASTExplorer之外完成这项工作。

这是我在 ASTExplorer 中编写的插件:

export default function(babel) {
  const { types: t } = babel;
  return {
    name: "ast-transform",
    visitor: {
      CallExpression: (path) => {
        if (
          path.node.callee.name === 'styled' && 
          path.node.arguments.length === 2 && 
          t.isArrowFunctionExpression(path.node.arguments[1])
        ) {
          if (t.isObjectPattern(path.node.arguments[1].params[0])) {
            const props = []
            path.node.arguments[1].params[0].properties.map(prop => props.push(prop.value.name))
            path.node.arguments.push(JSON.stringify(props)) // I suspect that the error is from here
          }
        } 

      }
    }
  };
}
4

1 回答 1

0

Babel 转换与 AST 节点一起工作,因此以这种方式将 props 字符串化并将它们推送到参数列表中将无法正常工作。您需要从您的对象实际创建一个 AST 结构。

在这种情况下,Babel 为此提供了一个帮助程序,因此您可以更改

path.node.arguments.push(JSON.stringify(props))

path.node.arguments.push(t.valueToNode(props))
于 2018-04-06T16:39:01.530 回答