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

webpack-alternate-require-loader

v0.0.3

Published

Webpack alternate require loader

Downloads

9

Readme

Webpack Alternate Require Loader

Build Status

This loader allows webpack to approximate arcane Node.js require semantics for advanced use cases when a normal require doesn't suffice

Background

The Problem

Let's say you have a project like:

src/index.js
src/outside-of-resolution-path/node_modules/foo

if you try:

// src/index.js
// BAD: Fails
var foo = require("foo");

This will fail, because src/outside-of-resolution-path/node_modules is not in the resolution path, which is:

src/node_modules
node_modules

The Module Pattern

One solution to this problem is called the "module pattern", which adds an extra file to start Node.js module resolution from a different directory. Basically, say we add a simple file in a directory outside of the current Node.js require resolution path:

// src/outside-of-resolution-path/require.js
// Re-export the `require` to start resolution from `src/outside-of-resolution-path/node_modules`
module.exports = require;

And switched our importing code to:

// src/index.js
// GOOD: Module pattern (re-exported `require`) works!
var foo = require("./outside-of-resolution-path/require")("foo");

this works because the Node.js resolution path starts from the re-exported require:

src/outside-of-resolution-path/node_modules
src/node_modules
node_modules

Webpack

The above pattern works just fine for Node.js. Unfortunately, this non-standard require usage fails in Webpack.

Enter this loader, which allows a bridge for webpack builds to also use the module pattern / other non-standard requires.

Installation

The loader is available via npm:

$ npm install --save webpack-alternate-require-loader

Usage

The plugin takes a configuration object of a re-exported module path to search for in code and then a resolved path to that same code on disk like:

{
  "CODE_TO_MATCH": require.resolve("REEXPORTED_CODE_PATH")
  "./outside-of-resolution-path/require": require.resolve("./outside-of-resolution-path/require")
}

It will then effectively transform something like:

var foo = require("CODE_TO_MATCH")("foo");
var foo = require("./outside-of-resolution-path/require")("foo");

to:

var foo = require("/RESOLVED/PATH/TO/foo");

This effectively simulates what Node.js would do at execution time to the code.

Examples

A basic configuration:

module.exports = {
  module: {
    loaders: [
      {
        test: /\.js$/,
        loader: "webpack-alternate-require-loader",
        query: JSON.stringify({
          "./outside-of-resolution-path/require": require.resolve("./outside-of-resolution-path/require")
        })
      }
    ]
  }
};

Additional examples are provided in: demo/webpack.config.js. If you have a clone of this repository with devDependencies, you can run:

$ npm run build-demo-wp

and see the results in the demo directory.

Notes

Do I have to use exactly the module / require pattern above?

Yes. Although Node.js can figure out:

var altRequire = require("./outside-of-resolution-path/require");
var foo = altRequire("foo");

This plugin currently cannot because it is naive and uses regexes. You must follow the form:

var foo = require("./outside-of-resolution-path/require")("foo");

Fortunately, if you are using babel-plugin-replace-require, you can easily produce require expressions that work with this plugin.

Why can't I just prepend the non-standard node_modules path in code?

See the module pattern discussion page. Basically, with top-level dependencies you can. But with nested dependencies and modern npm / yarn the real depended on code can be located anywhere in the tree. And you need the node_modules search path to be different than normal.

You're using regexes? Yuck!

Indeed. But that's basically how webpack / some loaders roll. We stick to an easy pattern and avoid the cost of a full babel install + parsing. But, we may be open to real code parsing in the future.

Contributions

Contributions welcome! Make sure to pass $ npm run check.