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

dayjs does not actually support Node.js ESM #1765

Open
CyanSalt opened this issue Jan 13, 2022 · 19 comments
Open

dayjs does not actually support Node.js ESM #1765

CyanSalt opened this issue Jan 13, 2022 · 19 comments

Comments

@CyanSalt
Copy link

CyanSalt commented Jan 13, 2022

Node.js has implemented native support for ESM in the real world, and the community is increasingly recommending the use of ESM instead of CommonJS (e.g: https://blog.sindresorhus.com/get-ready-for-esm-aa53530b3f77).

I noticed that dayjs actually publishes the esm directory, which contains the compiled product of the ESM syntax, see #1298. Although the "module" field of package.json was removed in #1314, the contents of esm are actually still available in the <script type="module"> in browsers or in bundling tools such as webpack.

Unfortunately, Node.js requires more than that for ESM. Since this is a CommonJS package, the ESM files it provides must use the .mjs extension to be properly parsed by Node.js.

I can get a few ways to solve this problem, but perhaps none of them are very good:

  • The easiest way to make it work is to replace the .js extension with .mjs in build/esm.js, but obviously this will cause breaking changes for scenarios that already use ESM files.
  • We can also publish a new node-esm directory for .mjs files for Node.js. But node-esm is not a good name for forward compatibility reasons.
  • Further, as described in fix: remove module entry in package.json #1314, continue to push the implementation of the dayjs-esm package, just like lodash-es.
    • If we take this approach, we also no longer need to use the .mjs extension. Just keep using .js.

I'm not sure if you have plans for this in terms of Node.js ESM, but I think that this is the way to go.

@katerlouis
Copy link

Any news here?

@benmccann
Copy link

2.0 supports ESM

@steffanhalv
Copy link

steffanhalv commented Aug 5, 2022

2.0 supports ESM

import dayjs from 'https://cdn.jsdelivr.net/npm/dayjs@2.0.0-alpha.2/dist/index.mjs'
console.log(dayjs()) // It works 👍🏼

@michaelhays
Copy link

Looks like the 2.0 alpha may be abandoned -- no new commits or releases in 6 months.

Is there a plan to re-open work on 2.0, or to bring ESM support to 1.0?

@neilsoult
Copy link

Looks like the 2.0 alpha may be abandoned -- no new commits or releases in 6 months.

Is there a plan to re-open work on 2.0, or to bring ESM support to 1.0?

BUMP

@MonsterDeveloper
Copy link

Any ETA on ESM arrival on NPM?

@DaniilIsupov
Copy link

I'm also waiting for Node.js ESM support

@Lauro235
Copy link

Would be great to get ESM support!

@andyg3
Copy link

andyg3 commented Sep 29, 2023

Another vote here for ESM support.

@n3ih7
Copy link

n3ih7 commented Oct 5, 2023

Come on! Where is ESM support?

flooey pushed a commit to getcord/sdk-js that referenced this issue Feb 8, 2024
## Summary
Adding `dayjs` to `opensource`, as it's needed by the translation framework.

## Test plan
Place `experimental.PagePresence` on the testbed, hover on avatar of users who haven't been present in a long time, check the tooltip has the right subtitle


## Old summary, before Josh moved us to ESM
This is the second attempt at this. The first one was reverted (#7592) because it crashed at runtime.
The original PR (#7473) had some `@ts-ignore` and was using `require`, which is why the build succeeded even though it should have not.

`import * as dayjs from 'dayjs';` is a valid import according to `tsc`. But then `dayjs(date)` errors
```
Type originates at this import. A namespace-style import cannot be called or constructed, and will cause a failure at runtime. Consider using a default import or import require here instead
```
It also **crashes at runtime**. Changing it to `dayjs.default(date)` doesn't crash at runtime, but `tsc` now complains about it
```
Property 'default' does not exist on type 'typeof import("/Users/albert/monorepo/opensource/sdk-js/node_modules/dayjs/index.d.ts")'
```

`import dayjs from 'dayjs';` is **not** a valid import according to `tsc`
```
This module is declared with 'export =', and can only be used with a default import when using the 'esModuleInterop' flag.
```
But **actually works** (i.e. no runtime crash).

Peeking into `dayjs` codebase, I see an [export default dayjs](https://github.com/iamkun/dayjs/blob/f0c9a41c6ec91528f3790e442b0c5dff15a4e640/src/index.js#L467C21-L467C21), which is ESM syntax, which I would expect to just be able to import (`import dayjs from 'dayjs';`).
My IDE is not complaining, the code is not crashing at runtime, but `npm run tsc-once` is yelling at me.

[There is a long-standing issue in DayJS regarding Node.js ESM](iamkun/dayjs#1765)) which might be related. But I'm still confused 😬

Test Plan:
Use the experimental.PresenceFacepile in the testbed, hover on an avatar, check the tooltip's subtitle is correct.


Reviewers: Netceer, lazybean

Reviewed By: lazybean

Pull Request: getcord/monorepo#7750

monorepo-commit: 9ea55f11df0954eff1e344bcf12c1f9c2a474541
@0x80
Copy link

0x80 commented Feb 10, 2024

Damn I just wasted hours on this 🤦‍♂️ When converting a large codebase to a monorepo, I kept getting errors like this at runtime:

Error [ERR_MODULE_NOT_FOUND]: Cannot find module '/Users/me/myproject/
services/fns/node_modules/dayjs/plugin/advancedFormat' imported from /Users/me/myproject/services/fns/dist/index.js
Did you mean to import dayjs@1.11.10/node_modules/dayjs/plugin/advancedFormat.js?

I couldn't figure it out because my bundled shared packages output looked correct, but I assumed it must be a mistake in some configuration. I tried everything I could think of before landing here.

I did not imagine a popular library like this would not have support for ESM yet in 2024.

I'll give the alpha 2.0 a try. Also found this issue describing that it should work by adding the .js import. It is unexpected, because extension prefixes are only required on ESM imports from relative paths, and never from an external library, but that must be a side effect of the funky not-really-esm exports.

@0x80
Copy link

0x80 commented Feb 10, 2024

The types in 2.0 alpha didn't seem to work for me. For example, TS didn't recognize that .utc() was available after applying the plugin. I ended up sticking .js to the v1 imports and that works for now.

@blackfalcon
Copy link

Running SSR build with Svelte/Vite

(node:29857) Warning: To load an ES module, set "type": "module" in the package.json or use the .mjs extension.
(Use `node --trace-warnings ...` to show where the warning was created)
/Users/dalesande/src/personal/sveltekit-auro/node_modules/dayjs/esm/index.js:1
import * as C from './constant';

Not sure if this is the fix you want, but I simply updated all the JS references to be .mjs and that fixed it. I pushed up a branch of the changes. The tests don't work, but thought this would be easy to see the diff.

dev...blackfalcon:dayjs:dev

@alex-arriaga
Copy link

Another vote here for ESM support.

@codyfrisch
Copy link

Two years on and nothing on proper ESM support tells me this is a dead end project and I need to migrate my code to another library. ESM is the only way forward, that is written on the wall.

@michaelhays
Copy link

Two years on and nothing on proper ESM support tells me this is a dead end project and I need to migrate my code to another library. ESM is the only way forward, that is written on the wall.

Pretty much, I'm just waiting patiently for https://github.com/tc39/proposal-temporal to hit Stage 4 so I can migrate my Day.js code to that 🙏

@codyfrisch
Copy link

Two years on and nothing on proper ESM support tells me this is a dead end project and I need to migrate my code to another library. ESM is the only way forward, that is written on the wall.

Pretty much, I'm just waiting patiently for https://github.com/tc39/proposal-temporal to hit Stage 4 so I can migrate my Day.js code to that 🙏

That would be ideal, but I have a requirement for format strings, and unfortunately I'm dealing with interop where there is an expectation for the moment.js/day.js style formatting strings. I suppose I could write something that converts between them... and use date-fns (I am assuming temporal is going to use unicode tokens like date-fns since its a standard).

@blackfalcon
Copy link

Two years on and nothing on proper ESM support tells me this is a dead end project and I need to migrate my code to another library. ESM is the only way forward, that is written on the wall.

The current version covers my use case, time to fork.

@tangxiangmin
Copy link

looks bad but work fine 🙅🏻‍♀️
image

Has there been any progress on this issue?

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