magic-akari/swc_mut_cjs_exports

TypeError when accessing exported member with "circular" dependency on barrel file

Open

#96 ouverte le 2 janv. 2024

Voir sur GitHub
 (8 commentaires) (0 réactions) (0 assignés)Rust (15 forks)user submission
help wanted

Métriques du dépôt

Stars
 (64 stars)
Métriques de merge PR
 (Aucune PR mergée en 30 j)

Description

Issue

Note that module.type in the swc config is set to commonjs for this issue.

When a member (in this case, a TS enum) is re-exported in a barrel file and a sub-dependency of the barrel file imports that enum through the barrel file and tries to access it, a TypeError is thrown:

TypeError: Cannot read properties of undefined (reading 'A')

This is due to how swc_mut_cjs_exports groups all the require calls at the top of the transpiled file and then adds the keys to the exports object after all of those require.

// task.js
var _enumDep = /*#__PURE__*/ _interop_require_wildcard(require("./enumDep"));
var _anotherDep = /*#__PURE__*/ _interop_require_wildcard(require("./anotherDep"));

/* ...helper functions... */

Object.keys(_enumDep).forEach(function(key) {
    if (key === "default" || key === "__esModule") return;
    if (Object.prototype.hasOwnProperty.call(exports, key)) return;
    Object.defineProperty(exports, key, {
        enumerable: true,
        get: function get() {
            return _enumDep[key];
        },
        configurable: true
    });
});
Object.keys(_anotherDep).forEach(function(key) {
    if (key === "default" || key === "__esModule") return;
    if (Object.prototype.hasOwnProperty.call(exports, key)) return;
    Object.defineProperty(exports, key, {
        enumerable: true,
        get: function get() {
            return _anotherDep[key];
        },
        configurable: true
    });
});

./enumDep exports SomeEnum, and ./anotherDep eventually imports SomeEnum from the task.js barrel file. But since the keys for ./enumDep haven't been added to exports by the time ./anotherDep is required, the SomeEnum ends up being undefined.

Reproduction

I've set up a small repo with the reproduction of this and the README has info on the structure: https://github.com/wadjoh/swc_mut_cjs_exports_debug_ts_enum

This is the structure of the TS code that causes an error when the transpiled code is executed: bug_explanation

Potential Fix

When swc_mut_cjs_exports transpiles star exports, this issue can be avoided by adding the keys to the exports object immediately after the associated require call:

// task.js

// moved helper function definitions to the top
/* ...helper functions... */

// `exports` is populated with module keys immediately after the module's `require` call
var _enumDep = /*#__PURE__*/ _interop_require_wildcard(require("./enumDep"));
Object.keys(_enumDep).forEach(function(key) {
    if (key === "default" || key === "__esModule") return;
    if (Object.prototype.hasOwnProperty.call(exports, key)) return;
    Object.defineProperty(exports, key, {
        enumerable: true,
        get: function get() {
            return _enumDep[key];
        },
        configurable: true
    });
});

var _anotherDep = /*#__PURE__*/ _interop_require_wildcard(require("./anotherDep"));
Object.keys(_anotherDep).forEach(function(key) {
    if (key === "default" || key === "__esModule") return;
    if (Object.prototype.hasOwnProperty.call(exports, key)) return;
    Object.defineProperty(exports, key, {
        enumerable: true,
        get: function get() {
            return _anotherDep[key];
        },
        configurable: true
    });
});

I have manually modified output code in the linked reproduction repo that works fine when executed: https://github.com/wadjoh/swc_mut_cjs_exports_debug_ts_enum/blob/main/results/fixed_output_with_plugin/task.js

Guide contributeur