关于babel-plugin-istanbul与babel-plugin-import冲突问题的官方解决方法

Does not work with babel-plugin-import

使用babel7后,按需加载执行报错

以上两个问题都是关于同时使用了istanbul与import的babel插件以后导致的问题。

在这里插入图片描述

编译后的前端代码运行后就会报上述的错误。

首先通过上面的issue我们先清楚的了解到一个问题。
为什么

const { Option } = Select;

就存在有问题,但是通过

const Option = Select.Option;

就没有问题呢?

这里我们就需要先了解经过istanbul插桩后变成了怎么样内容了, 我们可以来看下。


const {
  Option
} = (cov_1eldv8eouu().s[0]++, Select.Option);

const {
  Option
} = (cov_1eldv8eouu().s[0]++, Select);

以上就是经过babel解析后的结果,那么这两个给到babel-plugin-import解析后有什么区别呢?

这里就需要我们先确认下 这两个地方首先他经过babel解析成ast的结果是什么样的了?

const {
  Option
} = (cov_1eldv8eouu().s[0]++, Select.Option);

在这里插入图片描述

可以看到这里有个MemberExpression

 MemberExpression(path, state) {
    const { node } = path;
    const file = (path && path.hub && path.hub.file) || (state && state.file);
    const pluginState = this.getPluginState(state);

    // multiple instance check.
    if (!node.object || !node.object.name) return;

    if (pluginState.libraryObjs[node.object.name]) {
      // antd.Button -> _Button
      path.replaceWith(this.importMethod(node.property.name, file, pluginState));
    } else if (pluginState.specified[node.object.name] && path.scope.hasBinding(node.object.name)) {
      const { scope } = path.scope.getBinding(node.object.name);
      // global variable in file scope
      if (scope.path.parent.type === 'File') {
        node.object = this.importMethod(pluginState.specified[node.object.name], file, pluginState);
      }
    }
  }

可以看到babel-plugin-import 是否这块相应的处理的。
但是针对

const {
  Option
} = (cov_1eldv8eouu().s[0]++, Select);

babel解析的结果为

在这里插入图片描述

babel-plugin-import并没有单独针对Identifier的处理逻辑的。

针对这个问题的解决如下:

buildDeclaratorHandler(node, prop, path, state) {
    const file = (path && path.hub && path.hub.file) || (state && state.file);
    const { types } = this;
    const pluginState = this.getPluginState(state);

    const checkScope = targetNode =>
      pluginState.specified[targetNode.name] && // eslint-disable-line
      path.scope.hasBinding(targetNode.name) && // eslint-disable-line
      path.scope.getBinding(targetNode.name).path.type === 'ImportSpecifier'; // eslint-disable-line

    if (types.isIdentifier(node[prop]) && checkScope(node[prop])) {
      node[prop] = this.importMethod(pluginState.specified[node[prop].name], file, pluginState); // eslint-disable-line
    } else if (types.isSequenceExpression(node[prop])) {
      node[prop].expressions.forEach((expressionNode, index) => {
        if (types.isIdentifier(expressionNode) && checkScope(expressionNode)) {
          node[prop].expressions[index] = this.importMethod(
            pluginState.specified[expressionNode.name],
            file,
            pluginState,
          ); // eslint-disable-line
        }
      });
    }
  }

VariableDeclarator中做处理。

在这里插入图片描述

这样子就能够解析到上述的问题了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值