npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

devlop

v1.1.0

Published

Do things in development and nothing otherwise

Downloads

15,856,149

Readme

devlop

Build Coverage Downloads Size

Some tools to make developing easier while not including code in production.

Contents

What is this?

This package lets you do things in development that are free in production. It contains useful assert functions and a deprecate function that are useful when developing JavaScript packages while being small in production.

If you know Rust, you might know how nice having a debug_assert! is. This is that, and a bit more. For more on why they’re nice, see “Rust’s Two Kinds of ‘Assert’ Make for Better Code”

When should I use this?

Many JavaScript programs do not use assertions at all (perhaps because they’re typed and so assume type safety) or include lots of code to throw errors when users do weird things (weighing down production code). This package hopes to improve the sitation by making assertions free and deprecations cheap.

Install

This package is ESM only. In Node.js (version 16+), install with npm:

npm install devlop

In Deno with esm.sh:

import {deprecate, equal, ok, unreachable} from 'https://esm.sh/devlop@1'
// For development code:
// import {deprecate, equal, ok} from 'https://esm.sh/devlop@1?conditions=development'

In browsers with esm.sh:

<script type="module">
  import {deprecate, equal, ok, unreachable} from 'https://esm.sh/devlop@1?bundle'
  // For development code:
  // import {deprecate, equal, ok} from 'https://esm.sh/devlop@1?bundle&conditions=development'
</script>

Use

Say we have a small ponyfill for the ES5 String#includes function. It’s deprecated, because folks can use String#includes nowadays. It’s nicely typed so users should be able to figure out what to pass but we include assertions to show nicer errors when they get it wrong.

example/string-includes.js:

import {deprecate, ok} from 'devlop'

export const stringIncludes = deprecate(
  includes,
  'Since ES5, please use `String#includes` itself.'
)

/**
 * @deprecated
 *   Since ES5, please use `String#includes` itself.
 * @param {string} value
 *   Value to search in.
 * @param {string} search
 *   Value to search for.
 * @param {number | undefined} [position=0]
 *   Position to search from (default: `0`).
 * @returns {boolean}
 *   Whether the searched for value exists in the searched value after position.
 */
function includes(value, search, position) {
  ok(typeof value === 'string', 'expected string for `value`')
  ok(typeof search === 'string', 'expected string for `search`')
  ok(position === undefined || typeof position === 'number', 'expected number')
  ok(
    position === undefined ||
      (typeof position === 'number' &&
        !(/* #__PURE__ */ Number.isNaN(position))),
    'expected number'
  )
  // eslint-disable-next-line unicorn/prefer-includes
  return value.indexOf(search, position || 0) !== -1
}

example/index.js:

import {stringIncludes} from './example-includes.js'

console.log(stringIncludes('blue whale', 'dolphin')) //=> false
console.log(stringIncludes('blue whale', 'whale')) //=> true

Say we’d bundle that in development with esbuild and check the gzip size (gzip-size-cli), we’d get 1.02 kB of code:

$ esbuild example/index.js --bundle --conditions=development --format=esm --minify --target=es2022 | gzip-size
1.02 kB

But because devlop is light in production we’d get:

$ esbuild example/index.js --bundle --format=esm --minify --target=es2022 | gzip-size
169 B

The bundle looks as follows:

function u(n){return n}var r=u(c,"Since ES5, please use `String#includes` itself.");function c(n,t,e){return n.indexOf(t,e||0)!==-1}console.log(r("blue whale","dolphin"));console.log(r("blue whale","whale"));

It depends a bit on which bundler and minifier you use how small the code is: esbuild keeps the unused message parameter to the deprecate function around and does not know Number.isNaN can be dropped without a /* #__PURE__ */ annotation.

rollup with @rollup/plugin-node-resolve and @rollup/plugin-terser performs even better:

$ rollup example/index.js -p node-resolve -p terser | gzip-size
118 B

The bundle looks as follows:

const l=function(l,e,o){return-1!==l.indexOf(e,o||0)};console.log(l("blue whale","dolphin")),console.log(l("blue whale","whale"));

Rollup doesn’t need the /* #__PURE__ */ comment either!

API

This package exports the identifiers deprecate, equal, ok, and unreachable. There is no default export.

The export map supports the development condition. Run node --conditions development module.js to get dev code. Without this condition, no-ops are loaded.

deprecate(fn, message[, code])

Wrap a function or class to show a deprecation message when first called.

👉 Important: only shows a message when the development condition is used, does nothing in production.

When the resulting wrapped fn is called, emits a warning once to console.error (stderr). If a code is given, one warning message will be emitted in total per code.

Parameters
  • fn (Function) — function or class
  • message (string) — message explaining deprecation
  • code (string, optional) — deprecation identifier (optional); deprecation messages will be generated only once per code
Returns

Wrapped fn.

equal(actual, expected[, message])

Assert deep strict equivalence.

👉 Important: only asserts when the development condition is used, does nothing in production.

Parameters
  • actual (unknown) — value
  • expected (unknown) — baseline
  • message (Error or string, default: 'Expected values to be deeply equal') — message for assertion error
Returns

Nothing (undefined).

Throws

Throws (AssertionError) when actual is not deep strict equal to expected.

ok(value[, message])

Assert if value is truthy.

👉 Important: only asserts when the development condition is used, does nothing in production.

Parameters
  • actual (unknown) — value to assert
  • message (Error or string, default: 'Expected value to be truthy') — message for assertion error
Returns

Nothing (undefined).

Throws

Throws (AssertionError) when value is falsey.

unreachable(message?)

Assert that a code path never happens.

👉 Important: only asserts when the development condition is used, does nothing in production.

Parameters
  • message (Error or string, default: 'Unreachable') — message for assertion error
Returns

Never (never).

Throws

Throws (AssertionError), always.

Types

This package is fully typed with TypeScript. It exports no additional types.

Compatibility

This project is compatible with maintained versions of Node.js.

When we cut a new major release, we drop support for unmaintained versions of Node. This means we try to keep the current release line, devlop@^1, compatible with Node.js 16.

Security

This package is safe.

Related

  • babel-plugin-unassert — encourage reliable programming with assertions while compiling them away in production (can remove arbitrary assert modules, works regardless of conditions, so has to be configured by the end user)

Contribute

Yes please! See How to Contribute to Open Source.

License

MIT © Titus Wormer