debug-js / debug

A tiny JavaScript debugging utility modelled after Node.js core's debugging technique. Works in Node.js and web browsers
MIT License
11.08k stars 926 forks source link

Use ESModules instead of module.exports #786

Open jehon opened 3 years ago

jehon commented 3 years ago

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 ?

Qix- commented 3 years ago

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.

jehon commented 3 years ago

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...

tverilytt commented 3 years ago

Any news on this topic?

tverilytt commented 3 years ago

In Node.js ESM this works for me:

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

Qix- commented 3 years ago

Yep, v5 will be pure ESM.

jimmywarting commented 3 years ago

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

mrmckeb commented 2 years ago

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.

milahu commented 2 years ago

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 ...

Qix- commented 2 years ago

@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.

milahu commented 2 years ago

then publish as debug-esm, problem solved.

Qix- commented 2 years ago

Not really, no. Please take your negativity elsewhere.

lubomir-haralampiev commented 2 years ago

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?

Qix- commented 2 years ago
import makeDebug from 'debug';
const debug = makeDebug('foo:bar');
debug.enabled = true;
debug('hi');

Works fine for me.

jimmywarting commented 2 years ago

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')
Qix- commented 2 years ago

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

Qix- commented 2 years ago

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

jmcombs commented 2 years ago

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

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

dmnsgn commented 2 years ago
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)

Qix- commented 2 years ago

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

webketje commented 2 years ago

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

mariusrak commented 5 months ago

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.

amritk commented 3 months ago
import makeDebug from 'debug';
const debug = makeDebug('foo:bar');
debug.enabled = true;
debug('hi');

Works fine for me.

hey @Qix- How do you get this to work? I get the following error: x does not provide an export named 'default'