Angular 6/7“依赖的结果是一个表达式”

时间:2018-07-31 13:30:33

标签: angular typescript webpack angular-cli

我正在尝试创建Angular 6库并在Angular 6应用中使用它。我将其简化为一个最小的测试用例。 (更新:自从Angular 7发布以来,我也尝试过这样做。)

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

一个名为“工作区”的应用程序托管一个名为“小部件”的库。另一个名为“产品”的应用程序独立存在。到目前为止,一切都很好。

现在,让我们尝试在“产品”应用中使用“小部件”库。打开由CLI生成的文件product/src/app/app.module.ts。如下所示添加两行。

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 { }

更改之后,当我从产品目录运行ng build时,我会从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

“依赖关系的结果是表达式”是什么意思?我在做什么错了?

4 个答案:

答案 0 :(得分:16)

当使用表达式而不是固定字符串(例如require('horse' + variable)require(function() { return 'horse'+variable })来表示JS依赖关系时,会出现此错误。您的WidgetsModule导入的内容很可能正在导入执行需求形式的库。

Webpack抱怨这一点,因为这意味着它必须将所有文件都包含在一个文件夹中,而不是能够静态地分析要包含哪些文件。它仍然可以工作,但是根据对this Webpack issue的讨论,不应忽略它,并且应该重构有问题的依赖项。

最近在一个项目上将Angular从v5升级到v6的过程中遇到了此错误,如果我没记错的话,一旦我将所有其他依赖项以及最新版本升级到最新版本,它就会消失-我可以不能说是哪个依赖性导致了问题,但是不幸的是,我并没有在看到错误和修复错误之间做出承诺,所以我无法分析到底是什么确切的更改解决了该错误。

虽然确实有很多人遇到类似的问题-例如,参见https://github.com/angular/angular/issues/20357

要清除警告(不解决根本问题),请遵循this process,并添加:

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'),
        {}
    )
]

...到webpack配置。但是,在最新的Angular CLI中,您无法手动编辑Webpack配置(用于此操作的旧ng eject命令已被删除),所以我不认为您现在可以解决该警告。 / p>

所有这些得出的结论是,您将需要Angular CLI的作者通过内部使用的生成的webpack配置掩盖此错误,或者需要Angular的作者更改core.js导入方式。

答案 1 :(得分:16)

在新的Angular 7 cli生成的项目中,我在引用fesm5.js时遇到相同的警告:“依赖项的结果是表达式”。

该特定项目引用了一个本地npm包,该包的相对路径以file://../开头,这似乎会引起警告。

经过一番研究,我发现this Github issue解释了如何在Angular 6+ cli生成的应用程序中对其进行修复。

对我有用的是打开客户端项目的根文件夹(而不是共享库的文件夹)中的angular.json文件,并找到以下路径:

projects > (your project name) > architect > build > options

并添加密钥:

"preserveSymlinks": true

文件的其余所有部分均在此处省略:

{
  "projects": {
    "MyAwesomeProject": {
      "architect": {
        "build": {
          "options": {
            "preserveSymlinks": true
          }
        }
      }
    }
  }
}

添加此选项后,我得到的普通ng build没有警告。希望有帮助!

答案 2 :(得分:15)

主要问题不是为什么您会收到该警告。您访问图书馆的方式不是理想的方式。让我们用您自己的示例步骤来研究一种更好的方法[使用Angular 7],这首先不会导致该问题。


步骤1:[与您相同]

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

步骤2:创建.tgz库文件

cd ../workspace/dist/widgets/
npm pack
cp widgets-0.0.1.tgz ../../../product/

步骤3:在package.json中添加“小部件”库

打开package.json项目的product文件,并在devDependencies下添加以下行:

"widgets": "file:./widgets-0.0.1.tgz",

如果您在本地拥有该库,则需要执行步骤2和步骤3。否则,如果您的库已打包并发布到npm存储库中,则不需要file:关键字。您可以像其他依赖项一样提及该版本。


第4步:安装新添加的库

在产品项目中运行npm install


第5步:使用库

修改app.module.ts文件:

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 { }

第6步:构建产品项目

现在,在产品项目中运行ng build。它将成功运行。

Angular Product Project Build

答案 3 :(得分:5)

BrowserModule引起这样的警告。我不知道原因,但看来这是警告的来源。