Moment: Add support for ESM-aware bundlers

Created on 12 Nov 2019  ·  3Comments  ·  Source: moment/moment

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.

BuilRelease Help Wanted

Most helpful comment

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.

All 3 comments

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.

I support this.

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

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Shoroh picture Shoroh  ·  3Comments

vbullinger picture vbullinger  ·  3Comments

ninigix picture ninigix  ·  3Comments

Delgan picture Delgan  ·  3Comments

danieljsinclair picture danieljsinclair  ·  3Comments