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

Add support for ESM-aware bundlers #5288

Closed
slavafomin opened this issue Nov 12, 2019 · 3 comments
Closed

Add support for ESM-aware bundlers #5288

slavafomin opened this issue Nov 12, 2019 · 3 comments

Comments

@slavafomin
Copy link

Hello!

Thank you for this great library!

However, I believe that the "module" field in package manifest (package.json file) should point to the ESM bundle, e.g. ./src/moment.js.

Bundlers that support ESM (Webpack, Rollup, and others) should be able to find the ESM bundle using module field in order to use modern optimization techniques (like tree shaking). Right now, ./moment.js UMD bundle is used instead.

This causes entire library to be loaded in ESM-enabled projects, even if you import a single symbol from it.

For example, an import like this:

import { isMoment } from 'moment';

will import everything from the library, however, only one function was requested.

And you can't use the import { isMoment } from 'moment/src/moment'; as a workaround in TypeScript projects because it will break the typings.

@slavafomin
Copy link
Author

After looking at the content of ./src/moment.js I'm taking my words back. The content doesn't make any sense from the ESM point of view. Instead of importing and re-exporting useful symbols like Moment, isMoment, etc, it's constructing an object and exports it. I believe it's an entry point for UMD bundle doesn't it?

In order for modern tools to work we need a proper ESM bundle, which will export all useful symbols individually.

I've managed to import the symbols that I need (without loading entire bundle of moment.js) this way:

// @ts-ignore
import { isMoment, Moment } from 'moment/src/lib/moment/constructor';

But I had to suppress the typing errors with @ts-ignore, which allows the import, but breaks all typings for the imported symbols. Also, the path is ugly and shouldn't be used by the end users (because it breaks the encapsulation).


I've just made an experiment. I've created a file called moment.esm.js at the root of the package with the following content:

export { isMoment, Moment } from './src/lib/moment/constructor';

And added a module field to point to it from the package manifest.

Then I imported it in my application:

import { isMoment, Moment } from 'moment';

It imported correctly with the typing declarations working as expected and it also worked correctly during the Webpack and Rollup builds. Only specified symbols were imported without loading an entire bundle with all the locales.

I believe this is a way to go and it can be extended to export other symbols, described in declarations.

@slavafomin slavafomin changed the title The "module" field in package manifest should point to ESM bundle Add support for ESM-aware bundlers Nov 12, 2019
@arswaw
Copy link

arswaw commented Dec 11, 2019

I support this.

@marwahaha
Copy link
Member

See https://momentjs.com/docs/#/-project-status/

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

3 participants