liady / webpack-node-externals

Easily exclude node modules in Webpack
MIT License
1.3k stars 62 forks source link

whitelisted files may point to wrong node_modules #21

Open pwmckenna opened 7 years ago

pwmckenna commented 7 years ago

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);
    }]
};
cettoana commented 6 years ago

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

Pixelatex commented 6 years ago

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

y4h2 commented 6 years ago

Same here

travi commented 5 years ago

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.

richardscarrott commented 4 years ago

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 
dominic-p commented 3 years ago

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.