Webpack - Critical dependency: the request of a dependency is an expression
Asked Answered
A

8

185

I am getting three warning messages when importing request in a barebone webpack project. A minimal example to reproduce the bug is available on GitHub (run npm install and npm start).

Critical dependency: the request of a dependency is an expression

How can I get rid of this warning?


More information:

Webpack tries to resolve require calls statically to make a minimal bundle. When a library uses variables or expressions in a require call (such as require('' + 'nodent') in these lines of ajv), Webpack cannot resolve them statically and imports the entire package.

My rationale is that this dynamic import is not desirable in production, and code is best kept warning-free. That means I want any solution that resolves the problem. E.g.:

  1. Manually configure webpack to import the required libraries and prevent the warnings from occurring.
  2. Adding a hack.js file to my project that overrides the require calls in some way.
  3. Upgrading my libraries. ajv-5.0.1-beta.3 has a fix that silences the warnings. However, if I want to use it, I have to wait until it is released, and then until har-validator and request release subsequent updates. If there is a way to force har-validator to use the beta version of ajv, that would solve my problem.
  4. Other
Antemortem answered 20/3, 2017 at 15:50 Comment(5)
1. github.com/epoberezkin/ajv/issues/117#issuecomment-198328830 2. I don't think it'll work 3. you'll have to wait a bit.Solubility
@esp: that github comment seems to be what I'm looking for, but it doesn't silence the warnings. If I change it to new webpack.IgnorePlugin(/async/, /ajv/), two out of three warnings are gone but webpack Cannot find module "../async". Any idea about the proper magic value to make it work?Antemortem
The link to the github code example is broken. Pls put code directly into the question.Ergocalciferol
For those seeing this after writing dynamic, expression-based imports in your own code, you can bypass the warning with something like import(/* webpackIgnore: true */ "http://example.com/cdn/file.js"). This is not a solution, but a workaround.Amar
@Amar that should be made into the answerColon
A
35

Solved with npm install [email protected] --save

According to the authors of ajv, the issue will likely be resolved in the latest version of request in a few weeks' time.

Antemortem answered 21/3, 2017 at 10:16 Comment(4)
@maembe try npm remove request and reinstall, then in package.json remove the ^ before the version number. If you leave the ^, the package may be updated after an npm update and the warning reappears.Antemortem
Didn't work for me. But the suggestion by @DhirendraNk in a different answer below, which is to replacing the webpack.ContextReplacementPlugin worked for me.Rashidarashidi
for those that follow - request package is now depreciated.Decease
@Decease thanks, but don't you know how to resolve it today? I get ajv as the dependency of eslint -> @eslint/eslintrc (2.1.0). Although there is no "request" on my lock file. Probably the best answer is outdatedJusticiable
E
30

Encountered it while lazy loading a resource

const asset = 'config.json';
lazy(async () => await import(asset));

Solved it by changing the import parameter to string explicitly

const asset = 'config.json';
lazy(async () => await import(`${asset}`));
Empale answered 15/8, 2022 at 10:15 Comment(1)
Perfect for my use case (static testing for an eventual API integration), thankyou.Brittne
B
11

Replace this

new webpack.ContextReplacementPlugin(
        /angular(\\|\/)core(\\|\/)@angular/,
        helpers.root('./src'), // location of your src
        {} // a map of your routes
    ),

with this-

new webpack.ContextReplacementPlugin( /(.+)?angular(\\|\/)core(.+)?/, root('./src'), {} )
Bettor answered 12/11, 2017 at 11:39 Comment(5)
This does work. It would be nice for a more in-depth explanation as to why the regular expression change fixes this issue.Borax
This works for me, it's been annoying to see the warning, thanks.Rashidarashidi
does anyone knows where to find this code? I am unable to find the code to replace.Lat
This works because you are telling the System.Import function where to find source code in the node_modules folder. The path changes depending on the Angular version you are using. It should be handled better by the Angular team, hopefully it has already been.Tipcat
Doesn't work for me, it has nothing to do with Angular.Ellord
L
6

This warning can be linked to packages injections in (dependancies or devDependencies).

If the problem suddenly appears, check the last modification in your package.json.

Consider removing package-lock.json if you plan to relaunch an npm install.

Leonoreleonsis answered 16/4, 2020 at 15:4 Comment(0)
H
2

I got this when attemting a 'procedural' lazy load, webpack needs to understand the import statements at compile time.

//BAD - webpack can't tell this is constant
const pages = ['privacy-policy', 'terms-of-service']
  .map(name => 
    lazy(() => import(`./${name}`)))


//OK - webpack can tell this is constant
const names = ['privacy-policy', 'terms-of-service']
const pages = names.map((name, index) => 
    lazy(() => import(`./${names[index]}`)))

Headsail answered 17/6, 2022 at 2:21 Comment(0)
C
1

I got this in Angular when I imported EventEmitter from 'protractor' by accident. I blame my IDE for even suggesting it!

It should be imported from core:

import { EventEmitter } from '@angular/core';
Commando answered 27/7, 2021 at 16:8 Comment(0)
W
1

I had this same warnnig working with with typeorm and nextjs. I silenced it by doing using the code from here

const FilterWarningsPlugin = require('webpack-filter-warnings-plugin');

module.exports = {
    ...
    plugins: [
        //ignore the drivers you don't want. This is the complete list of all drivers -- remove the suppressions for drivers you want to use.
        new FilterWarningsPlugin({
            exclude: [/mongodb/, /mssql/, /mysql/, /mysql2/, /oracledb/, /pg/, /pg-native/, /pg-query-stream/, /react-native-sqlite-storage/, /redis/, /sqlite3/, /sql.js/, /typeorm-aurora-data-api-driver/]
        })
    ]
};

I added a regex like this to the exclude array above.

/Critical dependency/
Wallacewallach answered 27/4, 2022 at 16:41 Comment(0)
S
0

I have encountered at the same problem. Firstly I've gave up, but now a have the following solution.

webpack.config.js

var entries = {
app: [
    pathToDefaultAssets+'js/app.js',
    pathToDefaultAssets+'scss/index.scss'
],
dev: [
    pathToDefaultAssets+'js/dev.js'
],
...

app.js and index.scss are bootstraps for your project.

and the main part:

dev.js

import { a } from './module-one.js';

module-one.js

var a = function () {
    return 'a';
};

export { a }

I your app.js you can use now:

var src = 'one';
document.body.addEventListener('click', function () {
    import('./module-'+src+'.js').then(function (module) {
        console.log(module.a());
    });
});

And that it is!

Sarmentose answered 1/3, 2024 at 20:7 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.