debug icon indicating copy to clipboard operation
debug copied to clipboard

Use ESModules instead of module.exports

Open jehon opened this issue 5 years ago • 25 comments

Today, debug use module.exports facility. But nodejs and browser can support import / export notation, aka es6 modules. While preparing the v5, why not going into that mode? #656 ?

jehon avatar Oct 06 '20 07:10 jehon

It's not supported natively, so a build step would be required. Unfortunately, package management for the different types of modules still is pretty terrible. This is why most large modules are still CJS exported.

Qix- avatar Oct 06 '20 08:10 Qix-

You are right...

Conditional exports be a solution when not experimental anymore, or for next major:

// package.json { "main": "./main-require.cjs", "exports": { "import": "./main-module.js", "require": "./main-require.cjs" }, "type": "module" }

https://nodejs.org/dist/latest-v15.x/docs/api/packages.html#packages_conditional_exports

Storing it here to not loosing this...

jehon avatar Nov 03 '20 10:11 jehon

Any news on this topic?

tverilytt avatar May 21 '21 12:05 tverilytt

In Node.js ESM this works for me:

import debugModule from 'debug'; const debug = new debugModule('foo');

tverilytt avatar May 21 '21 12:05 tverilytt

Yep, v5 will be pure ESM.

Qix- avatar May 21 '21 15:05 Qix-

It would be cool to see debug being a ESM only package, It would put pressure on many packages towards upgrading their commonjs packages to ESM as well and benefit the hole js ecosystem in the end. otherwise they can still use a older version of debug

jimmywarting avatar Jul 10 '21 08:07 jimmywarting

Hi @Qix-, we've been working on ESM support for ms, and it would be great to get your feedback if you have some time: https://github.com/vercel/ms/pull/163

This work is also published as 3.0.0-beta.2.

mrmckeb avatar Aug 25 '21 17:08 mrmckeb

Yep, v5 will be pure ESM.

choose:

1. merge the working patch by @Konakona-chan today 2. make your users wait forever for your "perfect" esm rewrite (i hope it can fly me to the moon, too)

just another personality test, i guess ...

milahu avatar Nov 27 '21 09:11 milahu

@milahu I refuse to take such rude and unconstructive feedback on my repositories. I owe you nothing, sir.

Have some respect for people who do this out of their free time, and perhaps consider that there are other factors that affect the frequency of updates to a package that gets downloaded billions of times a month.

Qix- avatar Nov 27 '21 09:11 Qix-

then publish as debug-esm, problem solved.

milahu avatar Nov 27 '21 10:11 milahu

Not really, no. Please take your negativity elsewhere.

Qix- avatar Nov 27 '21 10:11 Qix-

The workaround suggested in the comment above

In Node.js ESM this works for me:

import debugModule from 'debug'; const debug = new debugModule('foo');

didn't work for me with the version 4.3.3.

I get the error TypeError: debugModule is not a constructor.

Generally if I have "type": "module" in my package.json an import results in an empty object {}. Importing it in a cjs module results in a function.

Any other workaround for usage in an es module? Or do I better wait for the next major release?

lubomir-haralampiev avatar Jan 06 '22 17:01 lubomir-haralampiev

import makeDebug from 'debug';
const debug = makeDebug('foo:bar');
debug.enabled = true;
debug('hi');

Works fine for me.

Qix- avatar Mar 04 '22 17:03 Qix-

we should at least discourage this antipattern var debug = require('debug')('http')

it's bad to call/chain require, it only makes it harder for those who wish to swtich to esm at some point later should rather be

const debugFactory = require('debug')
const debug = debugFactory('foo:bar')

jimmywarting avatar Mar 04 '22 18:03 jimmywarting

@jimmywarting agreed, PR welcome. That's a good start.

Qix- avatar Mar 04 '22 19:03 Qix-

Debug is not a class. Don't call it with new.

Qix- avatar Mar 08 '22 00:03 Qix-

Debug is not a class. Don't call it with new.

Thank you, @Qix. I deleted my comment since it was incorrect.

jmcombs avatar Mar 08 '22 12:03 jmcombs

import makeDebug from 'debug';
const debug = makeDebug('foo:bar');
debug.enabled = true;
debug('hi');

@Qix- The same doesn't seem to log anything in a browser (using import makeDebug from "https://cdn.skypack.dev/debug"; or https://esm.run/debug)

dmnsgn avatar May 13 '22 08:05 dmnsgn

@dmnsgn please open a new issue next time. Make sure your filters are set to show "Debug" or "Verbose" levels.

Qix- avatar May 13 '22 09:05 Qix-

I've been doing similar research into CJS/ESM for metalsmith and documented findings in this issue. TLDR:

Tests using a linked metalsmith package on diffferent Node versions with NVM resulted in inconvenient results for either the user (both ESM/CJS) or the maintainer:

  • specifying a package.json exports property will almost certainly result in a semver-major breaking change
  • specifying a shallow index.mjs wrapper and declaring"type": "commonjs" was inconvenient for ESM users as you needed to import from '/index.mjs'
  • declaring "type": "module" would require including a bundler with dual ESM/CJS builds
  • unit testing (with mocha) was a pain

In the case of debug, potentially even more build outputs would be required to work with native browser imports & bundlers.
The only "safe" option to support both CJS/ESM with no rewrite required in Node was using a single module.exports = default export as debug does in v4

webketje avatar Jun 03 '22 10:06 webketje

Not using ESModules is breaking my build. This lib is buried deep in dependency chain of a lib I wanted to use and it is now not usable beucause of the incorrect modules.export usage. So, please fix soon, as this might break down many builds.

mariusrak avatar Feb 21 '24 16:02 mariusrak