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

Posted

技术标签:

【中文标题】Angular 6 / 7“依赖的结果是一个表达式”【英文标题】:Angular 6 / 7 "the result of a dependency is an expression" 【发布时间】:2019-01-07 22:09:04 【问题描述】:

我正在尝试创建一个 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

一个名为“workspace”的应用托管了一个名为“widgets”的库。另一个名为“产品”的应用程序独立存在。到目前为止一切都很好。

现在让我们尝试在“产品”应用中使用“小部件”库。打开由 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

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

【问题讨论】:

我怀疑这里发生的任何事情都是导致此问题错误的原因:NullInjectError: no provider for NgZone 刚刚使用 Angular 6.1 (angular-cli 6.1.2) 再次测试。没有变化。 在生成的widgets.module.ts中是否导入BrowserModule? 基本上,this is what would be needed to clear the warning 但在最新的 CLI 中,ng eject 已经消失,所以我现在不知道您将如何编辑 CLI 使用的 webpack 配置... ... 但至于为什么会在这种情况下特别发生?我放弃了:)不知道!祝你找到解决方案好运,我怀疑它实际上是 Angular 中的错误/功能(CLI 或 fesm5/core.js) 【参考方案1】:

主要问题不是您收到警告的原因。您访问图书馆的方式不是理想的方式。让我们使用您自己的示例步骤来研究一种更好的方法 [使用 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 中添加“widgets”库

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

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

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


第四步:安装新添加的库

在产品项目中运行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。它将成功运行。

【讨论】:

我有同样的问题,这个答案对我有用 - 但在原始帖子中的设置中需要额外的几个步骤(打包到 tgz 并安装它)。 Angular 文档中是否有任何地方明确表示不支持在外部工作区中引用库? 这解决了问题,但完全扼杀了开发:库开发的最后一步是在真实项目中测试它并净化功能......有没有办法直接用原始库测试库建?这样,当库被修改时,目标项目会自动重启...... 太棒了! ng build 有效,但 ng build --prod 无效,知道如何使它也有效吗?【参考方案2】:

我在一个新的 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 没有警告。希望对您有所帮助!

【讨论】:

感谢您的回答。我在测试本地包时遇到了同样的问题 谢谢。终于开始尝试这个(在 Angular 7 上)但没有运气。 如果我能给你 1000 票,我会的!对于我们这些使用“npm link”的人来说,这就是修复。干杯。【参考方案3】:

当使用表达式而不是固定字符串(例如,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 命令已被删除),因此我认为您目前无法修复警告。

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

【讨论】:

谢谢。在这种情况下,我从最新版本的Angular CLI (6.1.1) 开始。 您的 WidgetsModule 的所有依赖项是否与 @PatrickMcElhaney 一样是最新的?可能值得发布 package.json,因为它可能是某种导致警告的依赖项......还是您的意思是您根本没有向ng new ... 生成的基本布局添加任何内容? 是的,所有代码都是使用问题顶部提到的 CLI 命令生成的。除此之外,我唯一改变的是product/src/app/app.module.ts,如上所述。一个好的起点可能是遵循相同的步骤,看看您是否可以重现该问题。 ?? 确实 - 我认为除了“裸”项目之外还有更多代码,现在我明白这只是一个空项目,我会看看我是否看到相同的!【参考方案4】:

BrowserModule 导致了这样的警告。我不知道原因,但似乎它是警告的来源。

【讨论】:

BrowserModule 导入是 CLI 生成的代码的一部分。我可以把它拿出来,但这会导致其他问题。

以上是关于Angular 6 / 7“依赖的结果是一个表达式”的主要内容,如果未能解决你的问题,请参考以下文章

Angular 2+/4/5/6/7:智能、愚蠢和深度嵌套的组件通信

Angular (4, 5, 6, 7) - ngIf 上滑入滑出动画的简单示例

如何将全局样式添加到 Angular 6/7 库

Angular 2/4/6/7 - 使用路由器进行单元测试

Angular 6,7 如何将默认主题颜色应用于 mat-sidenav 背景?

rxjs-websockets - 如何封装为 Angular 6/7 服务