Skip to content
This repository was archived by the owner on Jul 16, 2025. It is now read-only.

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

@wadjoh

Description

@wadjoh

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    help wantedExtra attention is needed

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions