micromark: `assert` is not browser friendly

Initial checklist

Affected packages and versions

latest

Link to runnable example

No response

Steps to reproduce

https://github.com/browserify/node-util/pull/62#issuecomment-908343918

Expected behavior

Use console.assert instead.

Actual behavior

assert is a node built-in module.

Runtime

Node v14

Package manager

yarn v1

OS

macOS

Build and bundle tools

Vite

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Reactions: 2
  • Comments: 28 (23 by maintainers)

Commits related to this issue

Most upvoted comments

Thanks @ChristianMurphy for updating the types. I’ve released all micromark extensions to not include node:assert in their development builds, but to instead use power-assert.

Sorry, misread some of the back-and-forth.

An alternative solution that I would be more than happy to contribute is just adding a utility function to this package with the same behavior as assert.

The advantages here would be fewer dependencies with more control over behavior. Disadvantages being its more code to maintain for this package.

Re @JounQin:

  1. always use if (process.env.NODE_ENV != 'production') before assert or debug statement.

Please look at how micromark works, here’s a small example: https://github.com/micromark/micromark/blob/b866e34551cf3ad34250c58e92f322714ba9d8da/packages/micromark-util-normalize-identifier/package.json#L34-L42 It’s using a very new, Node.js-specific, compile time, replacement of that. Defaulting to production code for everyone, and only when asked to load development code with this new feature, loads code with assertions/debug statements.

assert and debug are not available in the default production build. They only exist in development.

  1. custom noop functions for them and add browser mapping in package.json

You can decide if you want that. You implicitly / your bundler explicitly ask micromark to load development code which with assertions. If you don’t want the assertions, you can:

  • Create an issue with vite so that it doesn’t explicitly pass --conditions development by default
  • Create an issue with vite so that they allow assert (and maybe other builtins) in development
  • Configure vite to not load development code explicitly
  • Configure vite to map assert to a local package in development
  • Configure vite to map assert to an empty packcage in development

Re: @jalik:

For micromark, it’s not clear if the lib was made for browser, nodejs or both.

Both.

Why micromark does not add “assert” as a dev dependency, so it’s installed automatically?

Node builtins should not be added to packages. They are not used. Some bundlers replace things with those dependencies though, but that’s left up to the final user (you).


Three ideas for micromark:

  • @JounQin’s suggestion on console.assert — unfortunately console.assert misses features, such as:
    1. It prints a warning instead of throwing an error

    2. It’s not typed in TypeScript (because it doesn’t throw an error):

      function assert(value: unknown, message?: string | Error): asserts value;
      
      interface Console {
        assert(condition?: boolean, ...data: any[]): void;
        // ...
      }
      
  • We could use power-assert, which is also supported by unassert
    1. has a @types/power-assert but without assertions:
      declare function assert(value: any, message?: string): void;
      
  • We could use nested conditions:
     "exports": {
       "node": {
         "development": "./dev/index.js"
       },
       "default": "./index.js"
     },
    
    The downside is that it’s impossible for folks to get the development build outside of Node

[edit: hit send too early]:

Thanks!

The advantages here would be fewer dependencies with more control over behavior.

micromark has a quite modern set up, which was Node specific, to load some extra code when explicitly debugging. To summarize, the extra code is compiled away, you won’t see it in production, so using assert or powerassert won’t impact performance or bundle size. But this problem arose because several tools now started defaulting to this Node-specific debugging code by default.

Upstream PR with fixes for power-assert typings at https://github.com/DefinitelyTyped/DefinitelyTyped/pull/56062

Indeed, I think that’s the blocker. I’ve never used it myself, so perhaps it doesn’t work well, but it says it has the same api as assert, so I think it would work!

But I think browsers should also be able to load development code.

I don’t get your point why browsers should load codes which are node specific module: assert.