简体   繁体   English

Angular 7+ 上的动态导入

[英]Dynamic import on Angular 7+

I'm trying to build project that contains some components with dynamic imports, like:我正在尝试构建包含一些具有动态导入的组件的项目,例如:

import {Directive, Input, ElementRef} from '@angular/core';

@Directive({
  selector: '[saKnob]'
})
export class KnobDirective {

  @Input() saKnob: any;
  constructor(private el: ElementRef) {
    import('jquery-knob').then(()=>{
      this.render()
    })
  }

  render(){
    $(this.el.nativeElement).knob(this.saKnob || {})
  }
}

The dynamic import on the constructor seems to be the problem.构造函数上的动态导入似乎是问题所在。 I'm getting the following error:我收到以下错误:

ERROR in ./src/app/shared/forms/input/knob.directive.ts 15:8
Module parse failed: 'import' and 'export' may only appear at the top level 
(15:8)
You may need an appropriate loader to handle this file type.
|         var _this = this;
|         this.el = el;
>         import('jquery-knob').then(function () {
|             _this.render();
|         });

As far as I researched, this kind of import is supported since Angular 4, and I'm using Angular 7.据我研究,从 Angular 4 开始就支持这种导入,我使用的是 Angular 7。

Does anyone have an idea on what could be the problem?有没有人知道可能是什么问题?

* UPDATE * * 更新 *

As pointed by some answers, I was already using esnext on my tsconfig.app.file file:正如一些答案所指出的,我已经在我的tsconfig.app.file文件中使用了 esnext:

{
  "extends": "../tsconfig.json",
  "compilerOptions": {
    "outDir": "../out-tsc/app",
    "baseUrl": "./",
    "module": "esnext",
    "types": [],
    "paths": {
      "@app/*": ["app/*"],
      "@env/*": ["environments/*"]
    }
  },
  "exclude": [
    "src/test.ts",
    "**/*.spec.ts"
  ]
}

And here's the contents of the tsconfig.json这是tsconfig.json的内容

{
"compileOnSave": false,
"compilerOptions": {
    "baseUrl": "./",
    "outDir": "./dist/out-tsc",
    "sourceMap": true,
    "declaration": false,
    "moduleResolution": "node",
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "module": "es2015",
    "target": "es5",
    "typeRoots": ["node_modules/@types"],
    "lib": ["es2018", "dom"],
    "paths": {
    "@app/*": ["src/app/*"],
    "@env/*": ["src/environments/*"]
    }
}
}

My typescript version is ~3.1.6 .我的打字稿版本是~3.1.6

In short:简而言之:

It's caused by npm issue appeared with @angular-devkit/build-angular update from 0.12.x to 0.13.x and related webpack update under the hood from 4.28.x to 4.29.x .它是由引起的NPM问题有出现了@angular-devkit/build-angular更新从0.12.x0.13.x引擎盖下和相关的WebPack更新从4.28.x4.29.x

Possible solutions (workarounds):可能的解决方案(变通方法):

  • use @angular-devkit/build-angular 0.12.x使用@angular-devkit/build-angular devkit @angular-devkit/build-angular 0.12.x
  • try workarounds mentioned here .尝试这里提到的解决方法。 One working for me is to add explicit latest acorn dependency (eg npm i --save acorn will add 6.1.1 at the time of writing).对我npm i --save acorn是添加明确的最新acorn依赖项(例如npm i --save acorn在撰写本文时将添加6.1.1 )。 Another popular workaround is to run npm update acorn --depth 20 && npm dedupe .另一种流行的解决方法是运行npm update acorn --depth 20 && npm dedupe
  • use yarn if applicable如果适用,请使用纱线

Details:细节:

Have recently stumbled upon similar issue after project update from Angular 7.2 to Angular 7.3.最近在项目从 Angular 7.2 更新到 Angular 7.3 后偶然发现了类似的问题。 Before update build was fine, and esnext as target was already specified in tsconfig.json .在更新构建之前很好,并且esnext作为target已经在tsconfig.json指定。

After some tests I've revealed that it relates to @angular-devkit/build-angular and found issues ( 13767 , 13793 ) in angular-cli that surprisingly were closed.经过一些测试,我发现它与@angular-devkit/build-angular并发现 angular-cli 中的问题( 1376713793 )出人意料地关闭了。 But alan-agius4 comment in issue 13793 shed some light to real origin: invalid hoisting for peer dependencies;alan-agius4 在 issue 13793 中的评论揭示了真正的起源:对等依赖的无效提升; explained in details by sokra in this comment . sokra 在此评论中详细解释了。

There were already accepted pull request #147 for issue #4794, but then it was reverted in pull request #152 and issue #4794 remains opened at the time of writing.问题 #4794 的拉取请求 #147 已经被接受,但随后它在拉取请求 #152 中恢复,并且在撰写本文时问题 #4794 仍处于打开状态。

You can't just call import like that.你不能就这样调用import You need to import SystemJS first.您需要先导入SystemJS then call its import method.然后调用它的import方法。

import('jquery-knob').then(()=>{
  this.render()
})

stackblitz: https://stackblitz.com/edit/angular-bkbqkj堆栈闪电战: https ://stackblitz.com/edit/angular-bkbqkj

It works when creating a new project using ng new with the latest angular-cli.它在使用ng new和最新的 angular-cli 创建新项目时有效。

I think the problem is your Typescript config.我认为问题在于您的 Typescript 配置。 Try to set these values in you tsconfig.json :尝试在您的tsconfig.json设置这些值:

{
    ...
    "module": "es2015",
    "target": "es5",
    "lib": [
        "es2018",
        ...
    ]
}

This worked for me on Angular 8. First install acorn (acorn will be added in package.json file) then delete node_modules & package-lock.json then npm install.这在 Angular 8 上对我有用。首先安装 acorn(acorn 将添加到 package.json 文件中)然后删除 node_modules 和 package-lock.json 然后 npm install。

npm install acorn
rm -rf node_modules
rm -f package-lock.json
npm install

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM