Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

import * as x 会有额外的 default export 的问题 #1026

Open
sorrycc opened this issue Apr 7, 2024 · 2 comments
Open

import * as x 会有额外的 default export 的问题 #1026

sorrycc opened this issue Apr 7, 2024 · 2 comments
Labels
bug Something isn't working

Comments

@sorrycc
Copy link
Member

sorrycc commented Apr 7, 2024

背景

内网有个 umi 插件,会把一个空文件添加为 runtime plugin。runtime plugin 有检测 export 属性,如果有非法 export,会报错。以下是检测到 default export 时的报错截图。

image

问题

以下代码,(./nothing 为空文件)。

import * as nothing from './nothing';
console.log(nothing);

mako 构建后输出 { default: {} },webpack 构建后输出 {}。多一个属性看起来问题不大,但和 umi 的 runtime plugin 对 exports key 的检测结合,就会报错了。

分析

为啥 mako 会额外输出 default key?

mako 会把以上代码编译成这样。

__mako_require__.d(exports, "__esModule", {
    value: true
});
var _interop_require_wildcard = __mako_require__("@swc/helpers/_/_interop_require_wildcard");
var _nothing = /*#__PURE__*/ _interop_require_wildcard._(__mako_require__("src/nothing.ts"));
console.log(_nothing);

然后 _interop_require_wildcard._ 的内容如下(注意倒数第四行)。

function _interop_require_wildcard(obj, nodeInterop) {
    if (!nodeInterop && obj && obj.__esModule) return obj;
    if (obj === null || typeof obj !== "object" && typeof obj !== "function") return {
        default: obj
    };
    var cache = _getRequireWildcardCache(nodeInterop);
    if (cache && cache.has(obj)) return cache.get(obj);
    var newObj = {};
    var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
    for(var key in obj)if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
        var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
        if (desc && (desc.get || desc.set)) Object.defineProperty(newObj, key, desc);
        else newObj[key] = obj[key];
    }
    newObj.default = obj;
    if (cache) cache.set(obj, newObj);
    return newObj;
}

方案

感觉不太能从构建层解这个问题,先提 pr 给 umi,校验时额外允许 default 吧。

@fz6m
Copy link
Member

fz6m commented Apr 8, 2024

能判断下 obj 是不是空对象,是的话不给 default 赋值么。

@stormslowly
Copy link
Member

能判断下 obj 是不是空对象,是的话不给 default 赋值么。

我也这么想,在 interop 里面判断如果 obj 是 空对象,那么就直接返回空对象即可。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants