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

Differences in output when dynamically importing commonjs in local dev and production mode #28869

Open
1 task
mattlewis92 opened this issue Nov 15, 2024 · 0 comments

Comments

@mattlewis92
Copy link
Contributor

Command

serve, build

Is this a regression?

  • Yes, this behavior used to work in the previous version

The previous version in which this bug was not present was

No response

Description

When dynamically loading a commonjs module with esbuild, the results differ depending on if you're building for production or in local development.

For local development (e.g. with vite pre-bundling) and with the old webpack builder, dynamically loading a commonjs module with import('commonjs-module') results in an object shape like so, where there is a default property containing all commonjs exports, and the commonjs exports are also available on the top level object:

{default: {export1, export2...}, export1, export2...}

However, when building for production, the dynamically imported module only has a default property like so:

{default: {export1, export2...}}

I believe this is actually a bug with esbuild, but it's been over a year now and the issue is still not fixed: evanw/esbuild#3245

The ask here is if this could be solved within the angular cli - within the esbuild builder, would it be possible to add a simple transform for all dynamically imported modules that essentially transforms:

import('commonjs-module')

to something like this (this was just a quick sketch, and probably not the optimal transform, but you get the idea):

import('commonjs-module').then((m) => ({
  ...m.default,
  ...m,
}));

For context, we are in the middle of migrating from webpack to the application builder but are stuck on this problem. While we can refactor our code to only rely on the default property, the problem becomes more difficult as it's only reproducible when disabling dependency pre-bundling (i.e. building for production), so our team are not even aware there is a problem during local development and will only find the issue after deployment, which is a bit of a footgun. Ideally behaviour during both development and in production builds would be the same.

Minimal Reproduction

gh repo clone mattlewis92/ng-cli-code-splitting-bug
cd ng-cli-code-splitting-bug
npm i
ng serve webpack # Observe browser console of the dynamically imported module contains all commonjs exports on the top level object
ng serve esbuild-with-pre-bundle # Observe browser console of the dynamically imported module contains all commonjs exports on the top level object
ng serve esbuild-no-pre-bundle # Observe browser console of the dynamically imported module only contains a `default` export

Exception or Error


Your Environment

Angular CLI: 18.2.12
Node: 20.15.0
Package Manager: npm 10.7.0
OS: darwin arm64

Angular: 18.2.12
... animations, cli, common, compiler, compiler-cli, core, forms
... platform-browser, platform-browser-dynamic, router

Package                         Version
---------------------------------------------------------
@angular-devkit/architect       0.1802.12
@angular-devkit/build-angular   18.2.12
@angular-devkit/core            18.2.12
@angular-devkit/schematics      18.2.12
@schematics/angular             18.2.12
rxjs                            7.8.1
typescript                      5.5.4
zone.js                         0.14.10

Anything else relevant?

No response

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

No branches or pull requests

1 participant