FormidableLabs/webpack-alternate-require-loader

Name: webpack-alternate-require-loader

Owner: Formidable

Description: Webpack alternate require loader

Created: 2016-11-21 22:20:01.0

Updated: 2017-02-20 04:17:08.0

Pushed: 2017-04-06 10:49:53.0

Homepage: null

Size: 11

Language: JavaScript

GitHub Committers

UserMost Recent Commit# Commits

Other Committers

UserEmailMost Recent Commit# Commits

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:

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

if you try:

rc/index.js
AD: Fails
foo = require("foo");

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

node_modules
_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:

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

And switched our importing code to:

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

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

outside-of-resolution-path/node_modules
node_modules
_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:

m 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:


ODE_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:

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

to:

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

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

Examples

A basic configuration:

le.exports = {
dule: {
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:

m 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:

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

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

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.


This work is supported by the National Institutes of Health's National Center for Advancing Translational Sciences, Grant Number U24TR002306. This work is solely the responsibility of the creators and does not necessarily represent the official views of the National Institutes of Health.