Skip to content

Commit

Permalink
feat: provide an ESM build without debug
Browse files Browse the repository at this point in the history
Removing the debug library and the debug calls from the final bundle is
unexpectedly quite hard.

Actually, there are several solutions, each with its own pro and cons:

> use webpack-remove-debug (our previous solution)

Pro: works well, even with ESM imports with a little hack

```js
import debugModule from "debug"; // debug()

const debug = debugModule("my-library"); // debug()

debug("hello world");
```

Cons: only for webpack

See also: https://github.com/johngodley/webpack-remove-debug

> NODE_ENV variable

```js
import debugModule from "debug";

let debug = () => {}

if (process.env.NODE_ENV !== "production") {
  debug = debugModule("my-library");
}
```

Pro: the `debug()` calls are properly removed when bundling for
production

Cons: some bundlers leave the debug library in the bundle, even if it
is not called (for example, rollup needs an additional
"moduleSideEffects: true")

Reference: https://rollupjs.org/guide/en/#treeshake

> dynamic import

```js
let debug = () => {}

if (process.env.NODE_ENV !== "production") {
  import("debug").then(debugModule => {
    debug = debugModule.default("my-library");
  });
}
```

Pro: the sanest solution, which allows to use debug in development

Cons: will likely break some bundlers due to the dynamic import (for
example, not supported for UMD bundles)

> browser field

```json
{
  "browser": {
    "debug": "./noop.js"
  }
}
```

Pro: the safest solution from a compatibility point of view

Cons: some bundlers leave the noop debug calls, even after minification

> remove debug from the source code

We could also remove the debug calls, but the ability to turn them with
a single env variable on is quite appealing (at least in a Node.js
environment):

```
DEBUG=* node index.js
```

> dual packaging (our selected solution)

We provide two ESM builds, one with debug and one without.

Pros:

- no tricky configuration for bundlers
- debug logs are still available in Node.js

Cons:

- no more debug logs in the browser

We will go with the latest solution for now, until there is a better
alternative.
  • Loading branch information
darrachequesne committed Oct 8, 2021
1 parent b2c7381 commit 00d7e7d
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 2 deletions.
7 changes: 5 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@
"main": "./build/cjs/index.js",
"module": "./build/esm/index.js",
"exports": {
"import": "./build/esm/index.js",
"import": {
"node": "./build/esm-debug/index.js",
"default": "./build/esm/index.js"
},
"require": "./build/cjs/index.js"
},
"types": "build/esm/index.d.ts",
Expand Down Expand Up @@ -70,7 +73,7 @@
"zuul-ngrok": "4.0.0"
},
"scripts": {
"compile": "rimraf ./build && tsc && tsc -p tsconfig.esm.json && cp ./support/package.cjs.json ./build/cjs/package.json && cp ./support/package.esm.json ./build/esm/package.json",
"compile": "rimraf ./build && tsc && tsc -p tsconfig.esm.json && ./postcompile.sh",
"test": "npm run format:check && npm run compile && if test \"$BROWSERS\" = \"1\" ; then npm run test:browser; else npm run test:node; fi",
"test:node": "mocha --bail --reporter dot --require test/support/server.js test/index.js",
"test:browser": "zuul test/index.js",
Expand Down
8 changes: 8 additions & 0 deletions postcompile.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/bin/bash

cp ./support/package.cjs.json ./build/cjs/package.json
cp ./support/package.esm.json ./build/esm/package.json

cp -r ./build/esm/ ./build/esm-debug/

sed -i '/debug(/d' ./build/esm/*.js ./build/esm/**/*.js

0 comments on commit 00d7e7d

Please sign in to comment.