I'm trying to create an Angular 6 library and use it in an Angular 6 app. I've boiled it down to a minimal test case. (Update: since Angular 7 is out, I've tried that as well.)
ng new workspace # accept the defaults
ng new product # accept the defaults
cd workspace
ng generate library widgets
ng build --prod widgets # leave out "--prod" for Angular 7
cd ../product
ng build
An app called "workspace" hosts a library called "widgets". Another app called "product" stands alone. Everything to this point is fine.
Now let's try using the "widgets" library in the "product" app. Open the file product/src/app/app.module.ts
which was generated by the CLI. Add two lines as shown below.
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { WidgetsModule } from '../../../workspace/dist/widgets'; // added
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
WidgetsModule // added
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
After that change, when I run ng build
from the product directory, I get warnings from Webpack.
Date: 2018-07-31T13:13:08.001Z
Hash: 8a6f58d2ae959edb3cc8
Time: 8879ms
chunk {main} main.js, main.js.map (main) 15.9 kB [initial] [rendered]
chunk {polyfills} polyfills.js, polyfills.js.map (polyfills) 227 kB [initial] [rendered]
chunk {runtime} runtime.js, runtime.js.map (runtime) 5.22 kB [entry] [rendered]
chunk {styles} styles.js, styles.js.map (styles) 15.6 kB [initial] [rendered]
chunk {vendor} vendor.js, vendor.js.map (vendor) 4.59 MB [initial] [rendered]
WARNING in ../workspace/node_modules/@angular/core/fesm5/core.js
4997:15-36 Critical dependency: the request of a dependency is an expression
WARNING in ../workspace/node_modules/@angular/core/fesm5/core.js
5009:15-102 Critical dependency: the request of a dependency is an expression
What does "the result of a dependency is an expression" mean? What am I doing wrong?
The main problem is not why you are getting that warnings. The way you are accessing the library is not an ideal way. Let's look into a little better approach [Using Angular 7] with your own sample steps, which will not cause that issue in the first place.
ng new workspace # accept the defaults
ng new product # accept the defaults
cd workspace
ng generate library widgets
ng build --prod widgets # leave out "--prod" for Angular 7
cd ../product
ng build
cd ../workspace/dist/widgets/
npm pack
cp widgets-0.0.1.tgz ../../../product/
Open package.json
file of product
project, and under devDependencies
add the following line:
"widgets": "file:./widgets-0.0.1.tgz",
Step 2 and Step 3 are required if you have the library locally. Otherwise, if your library is packed and publish into npm repository, then you don't need file:
keyword. You can just mention the version like other dependencies.
Run npm install
in product project.
Modify app.module.ts
file:
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { WidgetsModule } from 'widgets'; // new line
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
WidgetsModule // new line
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
Now, run ng build
in product project. It will run successfully.
I encountered the same warning about "the result of a dependency is an expression” referencing fesm5.js
in a new Angular 7 cli generated project.
This particular project has a reference to a local npm package with a relative path beginning with file://../
which seemed to cause the warning.
After some research I found this Github issue which explains how we can fix it in Angular 6+ cli generated apps.
What worked for me was to open the angular.json
file in the client project's root folder (not the shared library's) and find this path:
projects > (your project name) > architect > build > options
and add the key:
"preserveSymlinks": true
with all the rest of the file omitted here are the relevant parts:
{
"projects": {
"MyAwesomeProject": {
"architect": {
"build": {
"options": {
"preserveSymlinks": true
}
}
}
}
}
}
After adding this I get normal ng build
without warnings. Hope that helps!
This error comes out when a JS dependency is expressed using an expression rather than a fixed string - for example, require('horse' + variable)
or require(function() { return 'horse'+variable })
. It is likely that something being imported by your WidgetsModule is importing a library that is doing that form of a require.
Webpack complains about this because it means it has to include all of the files in a folder, rather than being able to statically analyse what files to include. It will still work, but according to the discussion on this Webpack issue it should not be ignored and the dependency in question should be refactored.
I came across this error when in the process of upgrading Angular from v5 to v6 on a project recently, and if I recall correctly, it went away once I upgraded all the other dependencies as well to their latest versions - I can't say which dependency was causing the problem though, and unfortunately I did not commit between seeing the error and fixing it so I can't analyse what exact change addressed the error.
It does seem that many people are having similar issues though - see for example https://github.com/angular/angular/issues/20357
To clear the warning (without fixing the underlying problem), you would follow this process, adding:
plugins: [
// Workaround for Critical dependency
// The request of a dependency is an expression in ./node_modules/@angular/core/fesm5/core.js
new webpack.ContextReplacementPlugin(
/\@angular(\\|\/)core(\\|\/)fesm5/,
helpers.root('./src'),
{}
)
]
... to the webpack configuration. However, in the latest Angular CLI, you cannot manually edit the webpack configuration (the old ng eject
command which used to allow this has been removed), so I don't believe you can fix the warning at this time.
All of which concludes that you would need the authors of either the Angular CLI to mask this error through the generated webpack configuration it uses internally, or the authors of Angular to change the way the core.js does its imports.
It is the BrowserModule
that is causing such warning. I don't know the reason, but it seems that it is the source of the warning.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With