简体   繁体   中英

Importing plain JS from TS in Angular

I have to consume some ES6 JavaScript code (so, just a bunch of ES6 files, not a 3rd party library) from a Typescript file, in the context of an Angular app (or library). Given that's a corner usage case, I cannot find much information by googling around (most directions refer to importing JS libraries), except for what I have already done; yet, I'm still having issues.

As a test, I just created a new Angular 13 workspace ( ng new test ), without routing and with plain CSS. Then, I made these changes to its default template:

(1) in tsconfig.json , I added "allowJs": true ( reference here ) to the compiler options. The result is:

{
  "compileOnSave": false,
  "compilerOptions": {
    "baseUrl": "./",
    "outDir": "./dist/out-tsc",
    "forceConsistentCasingInFileNames": true,
    "strict": true,
    "noImplicitOverride": true,
    "noPropertyAccessFromIndexSignature": true,
    "noImplicitReturns": true,
    "noFallthroughCasesInSwitch": true,
    "sourceMap": true,
    "declaration": false,
    "downlevelIteration": true,
    "experimentalDecorators": true,
    "moduleResolution": "node",
    "importHelpers": true,
    "target": "es2017",
    "module": "es2020",
    "lib": [
      "es2020",
      "dom"
    ],
    "allowJs": true
  },
  "angularCompilerOptions": {
    "enableI18nLegacyMessageIdFormat": false,
    "strictInjectionParameters": true,
    "strictInputAccessModifiers": true,
    "strictTemplates": true
  }
}

(2) added a dummy JS module under /src/assets/js/hello.js with this content:

// just to be explicit, yet strict is implied by export:
// see https://developer.mozilla.org/en-US/docs/web/javascript/reference/statements/export
'use strict';

export const SOME_CONSTANT = 10;

export function sayHello(name) {
  console.log('Hello ' + name);
}

(3) included the JS file in the app via angular.json (under architect/build/options/scripts ):

"scripts": [
  "src/assets/js/hello.js"
]

(4) imported sayHello into app.component.ts :

import { Component } from '@angular/core';
import { sayHello } from 'src/assets/js/hello';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  constructor() {
    sayHello('world!');
  }
}

(5) added src/typings.d.ts to include ambient type declarations, with this content:

declare function sayHello(name: string): void;

Now, the app builds, and the function gets invoked and outputs its message on the console; but there are a couple of issues :

  • at runtime I get error Uncaught SyntaxError: Unexpected token 'export' . This would appear to point at a JS script loaded without type="module" (see eg this post ), but scripts are loaded via angular.json here, so they should already be loaded as modules (as it appears from here ). The default value for module in tsconfig is es2020 , so this post does not seem to apply.

  • typings do not seem to be in effect. I can eg remove the string argument from sayHello and ng build succeeds, despite the argument being declared in types.d.ts (and of course I get no typed intellisense in VSCode for sayHello ).

I created a new angular project, without any modifications it works like this for me. Is this what you are looking for? You can also set "noImplicitAny" to false in tsconfig.json and it will work without a d.ts file. 例子

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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