Skip to content
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

Critical dependency: the request of a dependency is an expression #2883

Closed
mattrothenberg opened this issue Apr 2, 2019 · 18 comments
Closed

Comments

@mattrothenberg
Copy link

mattrothenberg commented Apr 2, 2019

🐛 bug report

Howdy! I'm the author of vue-storybook, a library that allows Vue developers to add <story> blocks to their Vue single-file components and have them automatically translated into Storybook stories.

Parcel is my go-to bundler, though I'm experiencing some strange behavior when bundling/publishing my library code and subsequently using it in a freshly scaffolded Vue CLI project. Without fail, when running the Vue development server, I'm getting the following warning:

WARNING in ./node_modules/vue-storybook/dist/index.js 1:292-296
Critical dependency: the request of a dependency is an expression
 @ ./config/storybook/config.js
 @ multi ./node_modules/@storybook/core/dist/server/common/polyfills.js ./node_modules/@storybook/core/dist/server/preview/globals.js ./config/storybook/config.js ./node_modules/webpack-hot-middleware/client.js?reload=true

I'm confused, because I don't see this message when I bundle my library code with Webpack or Rollup. I'm doubly confused because I'm not using any special configuration with Parcel, just a good ole' build command. It's just a warning, so I'm not too concerned. But I've gotten user feedback that this is distracting. I'd like the warning to go away.

🎛 Configuration (.babelrc, package.json, cli command)

There's no Babel configuration for vue-storybook, though freshly scaffolded Vue CLI projects have the following babel.config.js

module.exports = {
  presets: [
    '@vue/app'
  ]
}

🤔 Expected Behavior

When using vue-storybook with a freshly scaffolded Vue CLI project, there should be no such warning about the request of a dependency is an expression

😯 Current Behavior

When using vue-storybook with a freshly scaffolded Vue CLI project, there is a warning about the request of a dependency is an expression

💁 Possible Solution

No ideas. I'm fairly certain this is user error somewhere on my part.

🔦 Context

I'm trying to publish a new version of my library (bundled with Parcel), and I'd like consumers not to see this warning message when using it.

🌍 Your Environment

Software Version(s)
Parcel 1.12.3
Node 10.15.1
npm/Yarn 1.13.0
Operating System OSX 10.14.3
@mischnic
Copy link
Member

mischnic commented Apr 2, 2019

babel.config.js

First of all: Parcel doesn't support that file: #2110

Haven't looked further into your issue, could you please provide some code sample/repo/gist to speed this up?

@mattrothenberg
Copy link
Author

Hi @mischnic, thanks for the prompt reply. To clarify, my library doesn't have a babel.config.js – that file comes from a Vue CLI project where I'm trying to use a library that's been bundled with parcel.

As mentioned, my repository is here: https://github.com/mattrothenberg/vue-storybook/tree/v2

The bundled files live in dist. Let me know if there are any other questions.

@dsadhanala
Copy link

I can confirm, I'm running into the same warning.

To provide context, I have a private npm module which uses parcel to bundle as ES5 compatible build artifacts. When I import this private module into a web app which uses webpack for code bundling, I see below warning during the builds.

WARNING in mymodule/dist/index.js 34:19-36
Critical dependency: the request of a dependency is an expression

Which is pointing to the source at below condition and nodeRequire(name) call.

// Try the node require function if it exists.
if (nodeRequire && typeof name === 'string') {
    return nodeRequire(name);
}

I'm not sure if this is due to the way parcel is bundling the code or some bad config for webpack is causing this warning.

@mischnic
Copy link
Member

mischnic commented Apr 3, 2019

When I import this private module into a web app which uses webpack for code bundling, I see below warning during the builds.

Interesting, this happens because webpack provides it's own require:

var nodeRequire = typeof require === 'function' && require;
// ...

        // Try the node require function if it exists.
        if (nodeRequire && typeof name === 'string') {
          return nodeRequire(name);
        }

@mischnic mischnic removed the Vue label Apr 3, 2019
@mischnic
Copy link
Member

mischnic commented Apr 3, 2019

But I've gotten user feedback that this is distracting. I'd like the warning to go away.

@mattrothenberg Do these warnings happen for you when your library is then consumed by Webpack?

This is a warning by Webpack (not Parcel). That error formatting seemed familiar...

@mattrothenberg
Copy link
Author

@mischnic I'm not sure I understand your question.

If my library is bundled with Parcel, and consumed in a project that uses Webpack, I get the warning.
If my library is bundled with Webpack, and consumed in a project that uses Webpack, I do not get the warning.
If my library is bundled with Rollup, and consumed in a project that uses Webpack, I do not get the warning.

@mischnic
Copy link
Member

mischnic commented Apr 3, 2019

I'm not sure I understand your question.

You did understand 😄 :

If my library is bundled with Parcel, and consumed in a project that uses Webpack, I get the warning.

@giannif
Copy link

giannif commented May 6, 2019

I've had the same issue for a bit now, in my webpack project I'm doing this to hide the warning:

// @giphy/js-brand uses parcel-bundler which has require statements
new webpack.ContextReplacementPlugin(/\/@giphy\/js-brand\//, data => {
  delete data.dependencies[0].critical
  return data
}),

However, I'm the author of the dependency and I'd rather not have to have people do this in their webpack projects

@mischnic
Copy link
Member

mischnic commented May 9, 2019

As already said in #2883 (comment),

this happens because the bundle emitted by Parcel falls back to a global require() function if the module can't be found otherwise (intended for Node).

@DeMoorJasper Is this part needed for target: browser (line 11, line 33-35) ?

parcelRequire = (function (modules, cache, entry, globalName) {
// Save the require from previous bundle to this closure if any
var previousRequire = typeof parcelRequire === 'function' && parcelRequire;
var nodeRequire = typeof require === 'function' && require;
function newRequire(name, jumped) {
if (!cache[name]) {
if (!modules[name]) {
// if we cannot find the module within our internal map or
// cache jump to the current global require ie. the last bundle
// that was added to the page.
var currentRequire = typeof parcelRequire === 'function' && parcelRequire;
if (!jumped && currentRequire) {
return currentRequire(name, true);
}
// If there are other bundles on this page the require from the
// previous one is saved to 'previousRequire'. Repeat this as
// many times as there are bundles until the module is found or
// we exhaust the require chain.
if (previousRequire) {
return previousRequire(name, true);
}
// Try the node require function if it exists.
if (nodeRequire && typeof name === 'string') {
return nodeRequire(name);
}

Reproduction: https://github.com/jooohn/reproduce-contentful-ui-extensions-error

@DeMoorJasper
Copy link
Member

@mischnic I don't think so.

As long as we don't overwrite the global require it should be fine.

@hughfenghen
Copy link

In my case, in addition to warning ‘Critical dependency’, it will also report ‘can’t find module "xxx"’.
This is detail error info:

vue-router.esm.js?8c4f:1907 Error: Cannot find module 'xlsx'
    at webpackEmptyContext (eval at ./node_modules/simple-xlsjs/dist sync recursive (add-match-task.c2731c8a9457ed35d133.js:157), <anonymous>:2:10)
    at newRequire (index.js?6209:34)
    at localRequire (index.js?6209:53)
    at Object.parcelRequire.7QCb (index.js?6209:131)
    at newRequire (index.js?6209:47)

In the code of the parcel output,replace require with rrr, error message disappears.
image

@rohan-deshpande
Copy link

Also seeing this for libs bundled with Parcel when used in a Wepback project. Kind of bad, would appreciate a fix.

@ostgals
Copy link

ostgals commented Apr 24, 2020

As already said in #2883 (comment),

this happens because the bundle emitted by Parcel falls back to a global require() function if the module can't be found otherwise (intended for Node).

@DeMoorJasper Is this part needed for target: browser (line 11, line 33-35) ?

parcelRequire = (function (modules, cache, entry, globalName) {
// Save the require from previous bundle to this closure if any
var previousRequire = typeof parcelRequire === 'function' && parcelRequire;
var nodeRequire = typeof require === 'function' && require;
function newRequire(name, jumped) {
if (!cache[name]) {
if (!modules[name]) {
// if we cannot find the module within our internal map or
// cache jump to the current global require ie. the last bundle
// that was added to the page.
var currentRequire = typeof parcelRequire === 'function' && parcelRequire;
if (!jumped && currentRequire) {
return currentRequire(name, true);
}
// If there are other bundles on this page the require from the
// previous one is saved to 'previousRequire'. Repeat this as
// many times as there are bundles until the module is found or
// we exhaust the require chain.
if (previousRequire) {
return previousRequire(name, true);
}
// Try the node require function if it exists.
if (nodeRequire && typeof name === 'string') {
return nodeRequire(name);
}

Reproduction: https://github.com/jooohn/reproduce-contentful-ui-extensions-error

It's a real issue in our project where global require() is overwritten by RequireJS. So nodeRequire fails loading modules with no exceptions thrown. We cannot remove RequireJS because it's the vital part of system architecture.

@AllanOricil
Copy link

Im facing the same problem. I bundled a lib with Parcel and Im importing it in Nuxt Js, which uses Webpack, and it shows this warning :/
Im thinking about switching to webpack and see what happens.

@abu3389
Copy link

abu3389 commented Jul 28, 2020

So,What's the best resolution with this proplem ? I think I need help,I'm facing the same situation

@devongovett
Copy link
Member

I think this shouldn't be an issue with Parcel 2. Parcel 1 wasn't really meant for building libraries, but Parcel 2 is. It will output native ESM or CommonJS that can be consumed by another bundler such as webpack rather than code meant to run directly in a browser.

@Cobertos
Copy link

Here's a workaround for anyone still depending on a Parcel 1 project using Webpack

After you install a library that is bundled with Parcel 1, there's a line at the top defining function parcelRequire. In that function/line is a variable u defined as u="function"==typeof require&&require;. It's used later to do a u(t), which handles the fallback to nodejs in Parcel as mentioned.

If you change u="function"==typeof require&&require; to u=function(){}, you'll no-op the nodejs fallback and there will be no more require() with an expression. This will stop the warning. This works for anyone targeting specifically browsers only.

@AllanOricil
Copy link

At the end I switched to Webpack and everything worked as expected. Now that Parcel 2 has a RC version I will try it again.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests