3

I'm a JavaScript beginner. I do not use a "bundler".

For a few days now I've been trying to use moment.js and other date-time libraries in some JavaScript by importing it using ES6 modules (ESM).

I have a JS module I wrote, which is transpiled from TS, and that has this line:

import moment from "../lib/moment/src/moment.js"

My module is itself loaded via an import from a <script type="module" > tag, which works.

I've discovered that the moment package contains what looks like "source" code in its src folder which seems to look more like the JS/TS I'm accustomed to, and has a "default export" at the bottom.

So I'm referencing that "source" version in my transpiled JS module. This gets me past a couple of errors I was getting:

The requested module 'blah' does not provide an export named 'default'

And

Cannot set property 'moment' of undefined (at moment.js:10)

And leaves me stuck with loading the other modules its dependent upon, because I guess, their file extensions are missing.

GET https://blah/lib/moment/src/lib/locale/locale net::ERR_ABORTED 404 (moment.js:37)


After 3 days tearing my hair out I feel like I have been fighting a battle I shouldn't be attempting at all.

I would expect in 2021, what with widespread ESM browser support, that this would just work, but I've tried 5 different date-time libraries and had no success.

I assume the 404s have occurred because the moment authors are NOT expecting people to be using their library like this, so they left off the file extensions knowing full well that it wouldn't load in a browser??

Am I supposed to add an extra step in my client-side build process, Gulp, to add the extensions back on in the moment source code??

Or am I doing something else wrong?

Is it perhaps that everyone uses a "bundler" and these tools fix all this stuff somehow and so these issues never arise for 99% of web devs??

Thanks in advance.

Luke Puplett
  • 42,091
  • 47
  • 181
  • 266
  • 1
    May you share the code as a [mcve]? Stories are useful, but examples are better. – evolutionxbox Jun 08 '21 at 16:34
  • 1
    That's the problem with esm. I use snowpack. Everyone uses a bundler unless they've written 100% of their source. Just adding file extensions isn't going to work. All imports from node_modules don't have full paths. – Charlie Bamford Jun 08 '21 at 16:37

1 Answers1

3

You want to import a bundled version of the lib to be able to do that. Try:

import from 'https://unpkg.com/moment@2.29.1/dist/moment.js' ;

You can download the bundled version and add to your project. Don't forget to put the license as well and check if they are at least MIT or similar.

If you want to refer to the source code you will certainly need to build that. Specifically with libs that are using typescript.

Luke Puplett
  • 42,091
  • 47
  • 181
  • 266
Ricardo Silva
  • 1,221
  • 9
  • 19
  • 1
    @luke-puplett I had the same desire for a bundler-less workflow and found the Skypack CDN seems to work well, is simple to use and single file generated (pointing to only another single all-in-one JS file) means downloading for offline use is easy too, more details in my answer: https://stackoverflow.com/a/69443532/85472 – Maks Oct 05 '21 at 00:05