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

[Feature]: Remove _webpack_require__.* + __webpack_exports__.* definitions for CJS format in bundleless mode #594

Open
antitoxic opened this issue Dec 23, 2024 · 1 comment

Comments

@antitoxic
Copy link

antitoxic commented Dec 23, 2024

What problem does this feature solve?

I am in a similar situation to #219. I think it's not the same, so I'm posting a new issue.

From what I know, rsbuild and therefore rslib are reimplementing the webpack algo. And that's cool. What I didn't expect is to use the bundle: false, a.k.a. "bundleless" mode and get a ton of repeated __webpack_require__.* definitions in each file for cjs format.

For example if I get an input file called math.ts with:

export const round = (val: number | null, precision: number = 0) => {
  if (val === null) {
    return Number.NaN;
  }
  const factor = Math.pow(10, precision);

  return Math.round(val * factor) / factor;
};

The bundleless mode of rslib produces ESM output of:

const round = (val, precision = 0)=>{
    if (null === val) return Number.NaN;
    const factor = Math.pow(10, precision);
    return Math.round(val * factor) / factor;
};
export { round };

//# sourceMappingURL=math.mjs.map

Which is fantastic, but the cjs (common js) version of of the same is:

"use strict";
var __webpack_require__ = {};
(()=>{
    __webpack_require__.d = function(exports1, definition) {
        for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
            enumerable: true,
            get: definition[key]
        });
    };
})();
(()=>{
    __webpack_require__.o = function(obj, prop) {
        return Object.prototype.hasOwnProperty.call(obj, prop);
    };
})();
(()=>{
    __webpack_require__.r = function(exports1) {
        if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
            value: 'Module'
        });
        Object.defineProperty(exports1, '__esModule', {
            value: true
        });
    };
})();
var __webpack_exports__ = {};
__webpack_require__.r(__webpack_exports__);
__webpack_require__.d(__webpack_exports__, {
    round: function() {
        return round;
    }
});
const round = (val, precision = 0)=>{
    if (null === val) return Number.NaN;
    const factor = Math.pow(10, precision);
    return Math.round(val * factor) / factor;
};
var __webpack_export_target__ = exports;
for(var __webpack_i__ in __webpack_exports__)__webpack_export_target__[__webpack_i__] = __webpack_exports__[__webpack_i__];
if (__webpack_exports__.__esModule) Object.defineProperty(__webpack_export_target__, '__esModule', {
    value: true
});

//# sourceMappingURL=math.js.map

And that is for every file.

What does the proposed API look like?

No changes of API, changes of output to be more similar to other tools like tsc, rollup, etc.

If this is a fundamental thing for rsbuild and rslib then at least those __webpack_* definitions can be reused and not redefined in every file?

When targetingcjs format, rollup produces:

'use strict';

const round = (val, precision = 0) => {
    if (val === null) {
        return Number.NaN;
    }
    const factor = Math.pow(10, precision);
    return Math.round(val * factor) / factor;
};

exports.round = round;
//# sourceMappingURL=math.cjs.map

When targeting cjs format & configured specifically for node 22 (via tsconfig base), tsc produces:

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.round = void 0;
const round = (val, precision = 0) => {
    if (val === null) {
        return Number.NaN;
    }
    const factor = Math.pow(10, precision);
    return Math.round(val * factor) / factor;
};
exports.round = round;
@fi3ework
Copy link
Member

Thank you for the feedback. We are aware that the runtime of webpack is currently quite verbose and has not yet been optimized. The main reasons are:

  • In scenarios where size (using tree shaking) is a concern, CJS is not supported, and we prioritize the quality of ESM outputs.
  • The verbosity of webpack's runtime is due to its better support for more complex scenarios, even though it might seem excessive for smaller, simpler CJS projects.

We can keep this issue open to see if there are opportunities in the future to optimize CJS outputs or the runtime. However, in the near term, this is not on our roadmap.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants