-
-
Notifications
You must be signed in to change notification settings - Fork 8.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Webpack should have a way to ignore require
calls
#8826
Comments
I totally agree, the current solution is ugly and silly. There should be an easier way to work around this problem... |
I use |
Hi @sindresorhus 👋, thanks for raising this issue. I agree that it must be annoying for you as a maintainer to get these kind of issues. However, I don't think that webpack is to blame for this either. Dynamic imports is something no bundler is able to handle in a good way. If webpack did not print out a warning for dynamic requires, people might get "Could not find module xyz" on runtime which is worst imo. I see the magic comment as a last resort because it's webpack specific. I would like to have something that works with all bundlers. The |
This is not about dynamic imports.
No, they would not get "Could not find module xyz" at runtime because the require call would be behind a conditional that is never hit in the browser. I'm asking for a way to tell Webpack to ignore a
The
Do you have a source for that assertion? Can you point me to the Webpack docs about the
You're asking me to massively refactor my codebase to support Webpack. It's not as easy as just using the All I want is to make Webpack ignore a |
That's correct, but dynamic and conditional imports have similar limitations.
That depends on the quality of the conditional. But I'm sure that you would get it right 😉
No, that's just my experience. It's widely adopted in the NPM ecosystem afaict but I have no stats for it. We have no dedicated page for module authors in our docs, but if you're looking for the issue number: #151
That's true: it's not an easy refactoring. But again, it's not only to support webpack. Other bundlers might just have decided to ignore occurrences of While I personally think that every code base would benefit from this refactoring, I do understand that it's not feasible for module authors with existing code. So I see the use case. How would that comment look like? require(/* ignore */ "./something.js") This would be similar to: import(/* webpackChunkName: "something" */ "./something.js") I guess the Would do other bundler maintainers think about this? @lukastaegert @devongovett @goto-bus-stop |
For the "browser": {
"chalk": false
} AFAIK, browserify, webpack and rollup all support this. If Parcel uses browser-resolve it supports it too (not sure). Meteor doesn't support it, last I checked. Browserify intentionally ignores dynamic requires entirely, so you can do But ideally, the |
The Personally, I am not a fan of introducing a new universal annotation when we have something that is already widely adopted. The Otherwise as we do not natively support dynamic require but only dynamic imports, those are handled rather permissively: If they cannot be resolved at runtime they will be left in the code unchanged, which should not be an issue if the code is never run. I plan to at least print a proper warning when a dynamic import that is just a string cannot be resolved, similar to how we handle unresolved static imports (a warning telling you that we assume this is external). However, I would only print this warning in case the dynamic import is not tree-shaken anyway. To me it seems that at least some parts of this should be solvable via tree-shaking. |
For anyone else encountering this issue and need a workaround, this is probably the best one: https://twitter.com/kamilogorek/status/1102272038411137025 |
@sindresorhus There's no doubt your contributions to the NodeJS/Isomorphic JS ecosystem is considerable. And we are sorry its been a burden so far. The more bundle-able modules are the more positive impact to your modules consumers. So its really important to us, to help you make this easier! You have the maintainers of Rollup (@lukastaegert), Browserify (@goto-bus-stop), and webpack here all verbally in support of the standard that exists today with the browser field. Is there maybe a hotlist of "most requested" modules you own that would need considerable refactoring? As far as I'm concerned we could all try and pitch our respective contributor ecosystems to help PR this code for you! (If you are willing). We're in it together <3 🤗 |
In parcel at least, you can also do this: if (process.browser) {
require('./browser');
} else {
require('./node');
} Not sure about other bundlers. |
We can do similar, but does this error in Browser ENV for non bundler using consumers? That's my hypothesis why it could not be the most feasible for some library authors. |
It will also error when bundled vanilla Rollup as we do not polyfill globals by default (which is partly because otherwise we would mess up those patterns when bundling for libraries, though). |
We do like leveraging |
Parcel inlines |
@devongovett That's interesting, perhaps when we use the |
Yeah non-bundler people would be a problem, but if you're using |
@devongovett Haha I told myself the same thing, but a great example is at Microsoft we have some legacy teams using requireJS, and therefore still can consume require's yet get that kind of Not a deal-breaker for the majority, but a consideration. |
…isplay/api.js` For performance reasons, and to avoid hanging the browser UI, the PDF.js library should *always* be used with web workers enabled. At this point in time all of the supported browsers should have proper worker support, and Node.js is thus the only environment where workers aren't supported. Hence it no longer seems relevant/necessary to provide, by default, fake worker loaders for various JS builders/bundlers/frameworks in the PDF.js code itself.[1] In order to simplify things, the fake worker loader code is thus simplified to now *only* support Node.js usage respectively "normal" browser usage out-of-the-box.[2] *Please note:* The officially intended way of using the PDF.js library is with workers enabled, which can be done by setting `GlobalWorkerOptions.workerSrc`, `GlobalWorkerOptions.workerPort`, or manually providing a `PDFWorker` instance when calling `getDocument`. --- [1] Note that it's still possible to *manually* disable workers, simply my manually loading the built `pdf.worker.js` file into the (current) global scope, however this's mostly intended for testing/debugging purposes. [2] Unfortunately some bundlers such as Webpack, when used with third-party deployments of the PDF.js library, will start to print `Critical dependency: ...` warnings when run against the built `pdf.js` file from this patch. The reason is that despite the `require` calls being protected by *runtime* `isNodeJS` checks, it's not possible to simply tell Webpack to just ignore the `require`; please note [Webpack issue 8826](webpack/webpack#8826) and libraries such as [require-fool-webpack](https://github.com/sindresorhus/require-fool-webpack).
…isplay/api.js` For performance reasons, and to avoid hanging the browser UI, the PDF.js library should *always* be used with web workers enabled. At this point in time all of the supported browsers should have proper worker support, and Node.js is thus the only environment where workers aren't supported. Hence it no longer seems relevant/necessary to provide, by default, fake worker loaders for various JS builders/bundlers/frameworks in the PDF.js code itself.[1] In order to simplify things, the fake worker loader code is thus simplified to now *only* support Node.js usage respectively "normal" browser usage out-of-the-box.[2] *Please note:* The officially intended way of using the PDF.js library is with workers enabled, which can be done by setting `GlobalWorkerOptions.workerSrc`, `GlobalWorkerOptions.workerPort`, or manually providing a `PDFWorker` instance when calling `getDocument`. --- [1] Note that it's still possible to *manually* disable workers, simply my manually loading the built `pdf.worker.js` file into the (current) global scope, however this's mostly intended for testing/debugging purposes. [2] Unfortunately some bundlers such as Webpack, when used with third-party deployments of the PDF.js library, will start to print `Critical dependency: ...` warnings when run against the built `pdf.js` file from this patch. The reason is that despite the `require` calls being protected by *runtime* `isNodeJS` checks, it's not possible to simply tell Webpack to just ignore the `require`; please see [Webpack issue 8826](webpack/webpack#8826) and libraries such as [require-fool-webpack](https://github.com/sindresorhus/require-fool-webpack).
… dependency: ...` warnings from Webpack Since bundlers, such as Webpack, cannot be forced to leave `require` statements alone we are thus forced to jump through hoops in order to prevent these warnings in third-party deployments of the PDF.js library; please see [Webpack issue 8826](webpack/webpack#8826) and libraries such as [require-fool-webpack](https://github.com/sindresorhus/require-fool-webpack). *Please note:* This is based on the assumption that code running in Node.js won't ever be affected by e.g. Content Security Policies that prevent use of `eval`. If that ever occurs, we should revert to a normal `require` statement and simply document the Webpack warnings instead.
… dependency: ...` warnings from Webpack Since bundlers, such as Webpack, cannot be told to leave `require` statements alone we are thus forced to jump through hoops in order to prevent these warnings in third-party deployments of the PDF.js library; please see [Webpack issue 8826](webpack/webpack#8826) and libraries such as [require-fool-webpack](https://github.com/sindresorhus/require-fool-webpack). *Please note:* This is based on the assumption that code running in Node.js won't ever be affected by e.g. Content Security Policies that prevent use of `eval`. If that ever occurs, we should revert to a normal `require` statement and simply document the Webpack warnings instead.
… dependency: ...` warnings from Webpack Since bundlers, such as Webpack, cannot be told to leave `require` statements alone we are thus forced to jump through hoops in order to prevent these warnings in third-party deployments of the PDF.js library; please see [Webpack issue 8826](webpack/webpack#8826) and libraries such as [require-fool-webpack](https://github.com/sindresorhus/require-fool-webpack). *Please note:* This is based on the assumption that code running in Node.js won't ever be affected by e.g. Content Security Policies that prevent use of `eval`. If that ever occurs, we should revert to a normal `require` statement and simply document the Webpack warnings instead.
To close up this issue: Do not try to workaround webpacks parser to create node-only Do use the In future you may also use the Creating parser hacks has multiple disadvantages:
A webpack ignore has also multiple disadvantages:
A package.json field has these advantages:
|
@sokra but how to require something at runtime in a bundle that was created by webpack? |
@wmertens You can bundle something by webpack/other tool, and use |
What about this use case? import Config from '../config' // use a sample/dev config for free typings
function main() {
const config = require(process.argv[2]) as typeof Config
// your `config` is typed
// ...
}
|
So what was the conclusion here? To use I am still running against a wall with third-party node modules that have a
in them, which give me a "module not found" error on build. I added the
So how to solve this? I could fork all the modules that have this and manually patch them but it would be much easier if I could just dummy-out this require because it would never get hit due to the conditional |
You can also do the same in config
You can do that globally or inside of |
@sokra thanks for the quick reply! I tried that method already but without luck - I'm still getting the "Module not found" errors (it also complained when I tried to set it to Using Another thing I tried without luck was setting The modules I'm trying to nop-out is |
Seems like you are using webpack 4 and that's only available for webpack 5. Try this instead: |
Yes you're right, Using |
@msklvsk If you just want webpack bundles correctly, you can use |
https://www.npmjs.com/package/webpack-ignore-dynamic-require |
@dvcrn can you share how you add "externals" in create-react-app? It seems no easy way to modify the webpack configs. |
@hkjpotato I'm not at my machine right now so I can't check the full code but we're using craco to override webpack configuration. Something like this in craco config (copied from a different github issue):
|
How to ignore whole directory from require bundled by webpack?) |
In need of this 5 years on. Coincidentally it was for the |
@rdsedmundo Due perf reasons, but it works if you set https://webpack.js.org/configuration/module/#moduleparserjavascriptcommonjsmagiccomments |
Bug report
What is the current behavior?
Webpack tries to handle all
require()
calls, even those not meant for browser usage. This makes it almost impossible to have a module that works in both Node.js and the browser, but has some added capabilities in Node.js.Note that this is about authoring reusable npm packages, not end-user apps. I don't have the ability to set any Webpack config like the
externals
option since I'm making packages other devs will consume.This is the kind of awfulness we have to do because of Webpack: https://github.com/sindresorhus/ow/blob/d62a06c192b892d504887f0b97fdc842e8cbf862/source/utils/node/require.ts We have wasted countless of hours on this.
Prior discussion that went mostly ignored by the Webpack team: #196 (comment)
What is the expected behavior?
I expected to be able to annotate the code to make Webpack ignore certain
require()
calls.For example with a comment:
I know for certain that this
require()
call will not be used in the browser, so I should be able to have it in my source code without Webpack printing warnings to users or erroring out.I need this as a module maintainer (not user).
Telling users to use the
externals
config is out of the questions, as my package might be a dependency many levels down.Some more examples of where I have to use awful code to work around Webpack:
Other relevant information:
webpack version: 4.29.0 (applies to any version though)
Node.js version: 10.15.0
Operating System: macOS 10.14.3
Additional tools:
The text was updated successfully, but these errors were encountered: