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.
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/
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 likeMoment
,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:
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:And added a
module
field to point to it from the package manifest.Then I imported it in my application:
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.