webpack-node-externals icon indicating copy to clipboard operation
webpack-node-externals copied to clipboard

whitelisted files may point to wrong node_modules

Open pwmckenna opened this issue 8 years ago • 6 comments

say you whitelist module 'a', which has a dependency on module 'b'.

node_modules
  a
    node_modules
      b

whitelisting a will pull it into the root directory, at which point require('b') statements in a will start to fail because they now look in the wrong node_modules directory. whitelisted modules may need their require statements rewired to point to absolute paths, or at least new relative paths.

Here's some similar code that I use to rewire require statements inside of a webpack externals function.

webpack.config.js

var resolve = require('resolve');
module.exports = {
    ...
    externals: [function (context, request, callback) {
        var absolute = resolve.sync(request, {
            basedir: context,
            extensions: ['.js', '.json']
        });
        callback(null, 'commonjs ' + absolute);
    }]
};

pwmckenna avatar Dec 23 '16 18:12 pwmckenna

I'm facing the same problem. Is there any updates for this issue?

cettoana avatar Nov 15 '17 02:11 cettoana

This is still an issue it seems.. any fixes?

Pixelatex avatar Jun 08 '18 13:06 Pixelatex

Same here

y4h2 avatar Jul 11 '18 21:07 y4h2

i'm seeing what appears to be this issue as well, but it was tricky to identify since everything was working fine locally, but failed when deployed to production.

i thought it was an issue with being built on CI and then transferred to a different server. however, it instead appears that devDependencies were filling some gaps because I can reproduce the error locally by running npm prune --production.

travi avatar Nov 28 '18 18:11 travi

This is really interesting; I've been adding node_modules to webpack externals for years in many many projects and only just run into this issue. Basically you either need to externalise all node_modules or none at all.

We had this scenario:

node_modules
├─ redux-toolkit
│  └─ immer@4
├─ react-dev-utils
└─ immer@1

Run yarn install --production / npm prune --production

node_modules
├─ redux-toolkit
   └─ immer@4

index.js

const serverBundle = require('./dist/server.js');
serverBundle();

dist/server.js

// webpack boilerplate etc.
// redux-toolkit module (whitelisted)
require('immer'); // Error: Cannot find module 'immer' (because this file does not live where the original 

richardscarrott avatar Feb 20 '20 14:02 richardscarrott

I was recently bitten by this as well. I am also using npm prune --production which I think is what causes it to show up.

I spent some time playing around with a fix. Basically, there needs to be another test added to the conditional here. We not only need to test if the requested module is on the allowlist, but if it is being required by a module on the allowlist.

The problem I ran into is that it's kind of hard to extract the parent module name from the context or contextInfo.issuer paths available in a reliable and cross platform way. Maybe a solution like this one would be better, but I honestly can't follow that code very well.

Anyway, I tend to agree with @richardscarrott using allowlist is a bad idea. Either externalize everything or nothing.

dominic-p avatar Apr 29 '21 06:04 dominic-p