Skip to content

fix: ignore context require for moment/locale for webpack#2

Closed
SoonIter wants to merge 2 commits intofilipsobol:mainfrom
SoonIter:webpack-moment
Closed

fix: ignore context require for moment/locale for webpack#2
SoonIter wants to merge 2 commits intofilipsobol:mainfrom
SoonIter:webpack-moment

Conversation

@SoonIter
Copy link
Copy Markdown

@SoonIter SoonIter commented Dec 25, 2024

There is a lib moment which contains code like

var aliasRequire = require
aliasRequire('./locale' + name)

This means require subfoloder in moment dynamically.

Rollup, webpack and Rspack all contains these statements, only webpack/Rspack bundles the sub modules which is correct and more safe. But I think it's better to ignore these to make it more fair

@filipsobol
Copy link
Copy Markdown
Owner

filipsobol commented Dec 26, 2024

Thanks for this PR. It appears that webpack and Rspack are the only bundlers that handle dynamic require() calls out of the box, thus bundling moment translations. Other bundlers either don't support it, or require non-standard configuration.

However, I'm conflicted about this PR. Regardless of whether webpack/Rspack are the only bundlers that handle this correctly, or if this is the correct behavior (I'm not sure), the solutions (either suggested in this PR or using module.noParse=[/moment.js/]) seem to be a bit hacky and target a specific library to improve the results.

Looking at the moment source code, it seems that the intention was to dynamically load the locale files when in the CommonJS environment. Also, according to the docs, in the ESM environment, the locales are expected to be imported explicitly. From this perspective, the current behavior of other bundlers seems correct, if only because of the lack of support for dynamic require() calls.

I want the results to be fair and not disadvantage any of the bundlers. However, in this case, the only solution seems to be to target a specific library to improve the results. I'm not sure if this is the right approach. I can update the article to mention this fix, as it fits perfectly with the overall message it's trying to send — that bundles can be optimized without losing functionality.

I'd like to hear your thoughts on this.

Here are the updated results:

build-size-without-moments-locales

@hardfist
Copy link
Copy Markdown
Contributor

hardfist commented Dec 26, 2024

Handle dynamic require is important to support many commonjs library which heavily use dynamic require, even other bundlers work right for this case but may not work for other case by default(they may support it by plugins).

But I don't think it's wrong that other bundlers don't support dynamic require, different bundler target different users and can have different default supported users.

So I think it's worth to point out that there's a tradeoff( safety vs bundle size vs build performance vs compat) every bundler need to decide.

Actually webpack | rspack may choose conservative way by default about some optimization than other bundlers(pure analysis is one of the key factors which affects bundle size but may bring safety risk), which doesn't mean it can't do more advanced or aggressive optimization. we will expose more optimization option to users to finetune the optimization in the future.

Thanks for your detailed benchmark which helps us spot some improvement we can do, we'll share more about the optimization detail we find in the near future.

Maybe we can choose external moment for all bundlers consider it works differently between bundlers and it's hard to say which does the right thing.

@chenjiahan
Copy link
Copy Markdown

It seems that moment is a special case. As moment has been deprecated, modern developers are more likely to use dayjs instead of moment.

Externalizing moment, or replacing it with other modern libraries should make this benchmark more in line with modern web development.

@filipsobol
Copy link
Copy Markdown
Owner

we'll share more about the optimization detail we find in the near future.

Awesome, can't wait for that!


The point of this article was never to show which bundler can produce the smallest possible bundle because, as we can see, it requires dependency-specific optimizations and configurations. These optimizations may not translate well to other projects or libraries, and don't have much value in a general article like this.

The point was to show that there are many opportunities to optimize bundle size. This is one of them. That's why, in this particular case, I wouldn't focus on the initial bundle sizes or introduce specific optimizations for one library or another.

I've updated the Aggregated results and added the Bundler-specific optimizations sections to the article, which explain the differences in bundle sizes and show webpack/Rspack-specific optimizations. I think this is fair and in line with the rest of the article.

@filipsobol filipsobol closed this Dec 30, 2024
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

Successfully merging this pull request may close these issues.

4 participants