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 withouttype="module"(see e.g. this post), but scripts are loaded viaangular.jsonhere, so they should already be loaded as modules (as it appears from here). The default value formoduleintsconfigises2020, so this post does not seem to apply.typings do not seem to be in effect. I can e.g. remove the string argument from
sayHelloandng buildsucceeds, despite the argument being declared intypes.d.ts(and of course I get no typed intellisense in VSCode forsayHello).
