EvanHahn / HumanizeDuration.js

361000 becomes "6 minutes, 1 second"
https://evanhahn.github.io/HumanizeDuration.js/
The Unlicense
1.64k stars 175 forks source link

Issues with import into es6 project #153

Open RobMaskell opened 5 years ago

RobMaskell commented 5 years ago

I've pulled this into my project from NPM and I'm trying to import it into a webcomponent but

import { humanizeDuration } from 'humanize-duration/humanize-duration.js'; gives an error that there is not export named humanizeDuration

So I tried

import 'humanize-duration/humanize-duration.js'; but this gives an error Uncaught (in promise) TypeError: Cannot set property 'humanizeDuration' of undefined from the following line 1118 code

  humanizeDuration.humanizer = humanizer;

  if (typeof define === 'function' && define.amd) {
    define(function () {
      return humanizeDuration;
    });
  } else if (typeof module !== 'undefined' && module.exports) {
    module.exports = humanizeDuration;
  } else {
    this.humanizeDuration = humanizeDuration;
  }
})(); // eslint-disable-line semi

basically the last line of real code in the above snippet.

Any ideas how to get around it?

EvanHahn commented 5 years ago

This seems like an issue with how CommonJS imports are being rewritten with imports.

Does import humanizeDuration from 'humanize-duration work?

RobMaskell commented 5 years ago

Fair shout, I gave it a try and this was the result Uncaught (in promise) SyntaxError: The requested module '../../node_modules/humanize-duration/humanize-duration.js' does not provide an export named 'default'

EvanHahn commented 5 years ago

Are you using anything to transpile ES6 imports to be compatible with CommonJS exports?

RobMaskell commented 5 years ago

It's a polymer app, so currently just running with npm start without any transpiling, babel used for prod though

EvanHahn commented 5 years ago

Okay. Are you able to import any other CommonJS modules this way?

RobMaskell commented 5 years ago

I seem to remember having similar issues with time-elements that I also use, but I think they now have two versions and modern one and a legacy. I did try adding the script tag to index.html and while that does work in dev it breaks when the proper build script runs which is what reminded me of time-elements. I think the polymer dev server does something for imports in terms of rewriting them but I'm not sure exactly what.

EvanHahn commented 5 years ago

Could you try writing a simple CommonJS module and using it? Here's a simple one:

module.exports = function () {
  return 'Hello world!'
}

My guess is that this isn't a problem with Humanize Duration but instead a problem with some module setup.

RobMaskell commented 5 years ago

Hmmm I just found this PWA Stater Kit FAQ maybe it just needs a ESM. I'll have a play with script tags and see if I can make it work.

andrew-c-tran commented 5 years ago

@RobMaskell see https://github.com/EvanHahn/HumanizeDuration.js/pull/159

RobMaskell commented 5 years ago

Thanks @andrew-c-tran I'll check this out at the weekend when I have a little more time

RobMaskell commented 5 years ago

Ok I tried and changed my imports as follows

import { LitElement, html } from 'lit-element';

import * as humanizeDuration from 'humanize-duration';

import '@polymer/marked-element/marked-element.js';
import '@polymer/paper-spinner/paper-spinner-lite.js'
import '@polymer/paper-fab/paper-fab.js';
import '@polymer/iron-icons/iron-icons.js';
import '@polymer/iron-icons/device-icons.js';

I get the following error

humanize-duration.js:1185 Uncaught (in promise) TypeError: Cannot set property 'humanizeDuration' of undefined
    at humanize-duration.js:1185
    at humanize-duration.js:1187

it doesn't like the line

this.humanizeDuration = humanizeDuration;
EvanHahn commented 5 years ago

@RobMaskell I suspect this is an issue with your build setup. How are you bundling dependencies?

RobMaskell commented 5 years ago

I call npm start which runs prpl-server --root server/build which I guess is local dev web server node I suspect for serving sites without much packaging for dev purposes. It all comes from https://github.com/Polymer/pwa-starter-kit but I've had no issues with any other imports although I take your point that it's probably some interaction between this server and your code.

EvanHahn commented 5 years ago

It might make sense for us to start publishing an ES module version (sorta like lodash-es).

Are you aware of precedent for that? I want to make sure to maintain backwards compatibility but also want to support ES modules.

RobMaskell commented 5 years ago

I had the same problem back in the day with https://github.com/github/time-elements and then I think they sorted it in a new version, might be worth a look?

EvanHahn commented 5 years ago

Looks like they publish two exports and use the not-standard-but-used module key in package.json. Not exactly sure what this library should do yet, but wanted to comment about my findings.

EvanHahn commented 5 years ago

Node has an official recommendation not to publish ES modules right now. That may change in the future, but for now, I think I'm going to do nothing.

rokerkony commented 5 years ago

Please do not publish any ES module packages intended for use by Node.js until this is resolved.

But it can be used on frontend without node as well...

EvanHahn commented 5 years ago

True, but I'd prefer to only ship one thing. I fear that in trying to address some use cases (eg, a browser build that wants ECMAScript modules) I could break some other cases (eg, a setup that expects CommonJS).

I think I'd like to wait for Node to have a recommendation before continuing here.

EvanHahn commented 4 years ago

Revisiting this, it seems like Node is still working on ES module support. Is anyone aware of the best practices here?

dasa commented 3 years ago

Sindre Sorhus has been moving his packages to pure ESM.

MMK21Hub commented 2 years ago

This kind of import works correctly when using Vite + TypeScript:

import humanizeDuration, { HumanizerOptions } from "humanize-duration"

The @types/humanize-duration package provides typings.