問題:
Does not work with babel-plugin-import
使用babel7后跨蟹,按需加載執(zhí)行報(bào)錯(cuò)
以上兩個(gè)問題都是關(guān)于同時(shí)使用了istanbul與import的babel插件以后導(dǎo)致的問題磨镶。
20201218090823471.png
編譯后的前端代碼運(yùn)行后就會(huì)報(bào)上述的錯(cuò)誤凳枝。
分析
首先通過(guò)上面的issue我們先清楚的了解到一個(gè)問題骡技。
為什么
const { Option } = Select;
就存在有問題,但是通過(guò)
const Option = Select.Option;
就沒有問題呢矢赁?
這里我們就需要先了解經(jīng)過(guò)istanbul插樁后變成了怎么樣內(nèi)容了, 我們可以來(lái)看下排嫌。
const {
Option
} = (cov_1eldv8eouu().s[0]++, Select.Option);
const {
Option
} = (cov_1eldv8eouu().s[0]++, Select);
以上就是經(jīng)過(guò)babel解析后的結(jié)果对粪,那么這兩個(gè)給到babel-plugin-import解析后有什么區(qū)別呢芯勘?
這里就需要我們先確認(rèn)下 這兩個(gè)地方首先他經(jīng)過(guò)babel解析成ast的結(jié)果是什么樣的了箱靴?
const {
Option
} = (cov_1eldv8eouu().s[0]++, Select.Option);
在這里插入圖片描述
可以看到這里有個(gè)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 是否這塊相應(yīng)的處理的。
但是針對(duì)
const {
Option
} = (cov_1eldv8eouu().s[0]++, Select);
babel解析的結(jié)果為
在這里插入圖片描述
babel-plugin-import并沒有單獨(dú)針對(duì)Identifier的處理邏輯的荷愕。
針對(duì)這個(gè)問題的解決如下:
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
中做處理衡怀。
在這里插入圖片描述
這樣子就能夠解析到上述的問題了。