简体   繁体   中英

Building a js file with esnext how to use it with angular 2

I have a js file as shown below UserService.js and source.js which is created using transformer typescript my goal is to use this transformed js file in angular.

UserService.js

import { Source } from "./source";

 export class UserService {
    
    source = new Source();
    
    demo() {
        this.source.fun();
    }

}

Sourcr.js

export class Source {
    fun() {
        console.log('hello world');
    }
}

When I try to use the file in app.component.ts as shown below

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {

  userService=new UserService();

  constructor() { }

  ngOnInit(): void {
    this.userService.demo();
  }
}

Below is tsconfig.json

{
  "compileOnSave": false,
  "compilerOptions": {
    "baseUrl": "./",
    "outDir": "./dist/out-tsc",
    "sourceMap": true,
    "declaration": false,
    "downlevelIteration": true,
    "experimentalDecorators": true,
    "module": "esnext",
    "moduleResolution": "node",
    "importHelpers": true,
    "target": "es2015",
    "lib": [
      "es2018",
      "dom"
    ]
}

I get the following error while doing ng serve

ERROR in ./dist/out-tsc/UserService.js 4:11
Module parse failed: Unexpected token (4:11)
You may need an appropriate loader to handle this file type.
| export class UserService {
|     
>     source = new Source();
|     
|     demo() {

Here's what is going on here:

  1. The builder does not understand the syntax in UserService.js (the problematic line is marked with a > ).
  2. This makes the compiler think that the file needs special processing, which is why it suggests using a loader .

Here's why this happens:

  1. You are importing a JavaScript file ( UserService.js ) into a TypeScript file ( app.component.ts ).
  2. This JS file uses syntax from ES2019 (it has a class field).
  3. Angular is not instructed to compile JS files - it only compiles TypeScript by default.
  4. It attempts to use the file as is and fails because it does not know this JS syntax.

Disclaimer - this is empirical reasoning, and I can't provide any comprehensive reference. I'm actually not sure why it does not understand that syntax.

Solution

I can think of a few ways to solve this problem.

  1. Rename UserService.js to UserService.ts . Angular will then properly transpile the file. Although if in the real setting Source.js uses such syntax as well, then it won't be enough.
  2. Add "allowJs": true to tsconfig.json > compilerOptions . This will instruct Angular to treat JS files similar to how it treats TypeScript. This means that all JS files will be transpiled by the compiler.
  3. Don't use such modern syntax in your JS files (the code worked fine when I got rid of the class field).

Note

Since I had a chance to take a look at your repo, I have noticed one issue.

The scripts array under angular.json > projects > sample-app > architect > build > options is typically used for external libraries, which define their exports at the global level (eg jQuery). Since you import Source.js directly into UserService.js , which you import directly into app.component.ts , you shouldn't add these scripts to this array - it really doesn't do anything aside from inflating the size of the bundle.

BTW, if none of the above solutions work for you, it's also possible to use this scripts array to solve the problem, but you'd have to change a few more things in the code, which is why I'm not going into details here.

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