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

node-webpackify

v2.1.2

Published

Utility for redirecting require() requests in Node to Webpack's module compiler

Downloads

29

Readme

node-webpackify

Redirects all your Node require() calls to Webpack's module compiler, making it into a JIT (just-in-time) compiler.

It can serve as a replacement for babel-register or ts-node.

Based on the provided webpack config, node-webpackify will use:

  • webpack's resolvers (including resolving of aliases, resolve plugins, etc.)
  • webpack's rules (loaders)

But NOT webpack's plugins (or at least that remains untested)! The reason is that node-webpackify will only run a handful of hooks required to setup the resolvers and loaders.

Yes, this means you can use things like css-loader with Node or Electron. Think: ditching karma-webpack in place of electron-mocha for much faster testing.

Usage

node-webpackify exposes a register function, which you can use by calling it with the following arguments:

const webpackOptions = require('./webpack.config.js')
require('node-webpackify')(
  // webpack options object:
  webpackOptions,
  // node-webpackify options object (optional):
  {
    // (optional) function(request: string, parentPath: string): boolean
    // can be used to limit which requests are run through the resolvers and loaders
    // when left undefined,
    //
    // @param request is the string passed into: require(request)
    // @param parentPath is the full, absolute path to the module that the request is located in
    test: (request: string, parentPath: string): boolean => true,

    testTransform: (filename: string, loaders: Array<Loader>, request: string, parentFilename: string): boolean => true,

    // (optional) override webpack's target (default = 'node'), useful for Electron
    target,
  }
)

I'd recommend creating a register-webpack.js file with similar contents to the file above.

Then, you can simply run your code by executing:

node -r ./register-webpack src/entry

Output code must be valid NodeJS code

You need to ensure none of the output code contains ES6 imports (whether static or dynamic).

If using Babel or TypeScript, ensure you set a CommonJS target for the module system.

If you use dynamic import()s, you could add a babel plugin to transpile them into promisified require()s:

  • https://github.com/airbnb/babel-plugin-dynamic-import-node

Why?

  • NodeJS-based testing without mocking non-JS files, e.g. running jest or mocha under Electron (which is Node + Chromium):
    • no build/rebuild step necessary
    • native watch mode
    • test your (post)CSS/SASS/CSSinJS with measuring and rendering, but without bundling
  • one config to rule them all: why should you need a different config for your testing platform, and a different one for your production?
  • run a Node REPL that uses your webpack configuration (resolvers, loaders, aliases), and behaves like webpack (supporting inline syntax like require('!graphql-loader!./schema.graphql'))
  • debug your serverless functions without serverless-webpack: no bundles, no sourcemap mess, no rebuilding!
  • things I didn't even think of 😄.
  • Edit this README if you have an interesting use-case!

ES6 modules support

node-webpackify does not add hooks to the ES6 modules system when the --experimentalModules flag is enabled.

It shouldn't be too hard to add, as there are official APIs for hooking into that system. If you want to give it a go, send me a PR! :-)

Performance

We're transforming and loading each file on-demand, while all require calls are synchronous. Unfortunately this means any top-level requires will cascade down making the boot-up of your application slow.

The way to solve this problem is to delay the imports as much as possible, which could be achieved using a babel plugin (explained below). It's likely not all codepaths in your application will be taken, meaning some files can be unnecessary, and others could be transformed and loaded just-in-time for their first use.

This is really important in node, because require is synchronous, and cannot be parallelized. If you require any file and that contains top-level requires or static imports, all of those files, and all of their dependencies will have to be resolved and transformed before any other code is executed.

If you're using babel, I recommend adding one of these plugins to the config passed into node-webpackify (it might not make sense in other cases):

  • https://github.com/zertosh/babel-plugin-transform-inline-imports-commonjs
  • https://github.com/princjef/babel-plugin-lazy-require

They will make your require's evaluate at the first moment they're used, rather than all upfront, making the start-up times much, much better.

You could even try experimenting with transpiling the node_modules code with these, to get even better boot times!

Open PRs with improvements!

Since loaders can be slow, and require's are synchronous, a lot could still be done to make node-webpackify faster:

  • long-term caching based on file timestamps (like babel-register)
  • improving logic for early bailing
  • resolve-only before creating the Webpack module
  • profile, find and eliminate bottlenecks!

Debugging

Lunch your app with a DEBUG=node-webpackify:* environment variable, e.g.:

DEBUG=node-webpackify:* node -r ./register-webpack src/entry

Using the compiler directly

It might be useful for you to just use the extracted compiler, for example to write a jest transform plugin out of it.

See the src/compiler.test.ts for details on usage.