0

When I import a module in a app.ts script, the '.js' file extension is missing in the import line of the compiled js file.

app.ts import {ModuleA} from './ModuleA'

compiled app.js import {ModuleA} from './ModuleA';

I include it in the html file like this <script type="module" src="app.js"></script>

But the browser can't find the module 'ModuleA'.

It only work when I import like this import {ModuleA} from './ModuleA.js'

But I want to work by importing '.ts' module files, not '.js' module files.

I would have hoped the ts compilation add the '.js' extension to the import line.

Any suggestions?

4
  • Can you share the code of the component? At least everything before the constructor. I assume you're using export class componentName in the ts? Commented Mar 17, 2018 at 5:38
  • What does your tsconfig.json file look like? Are you sure that the module and target compilerOptions are what you want them to be? Commented Mar 17, 2018 at 23:34
  • @Steve import {Config} from './config' export class ModuleA {...} Commented Mar 18, 2018 at 14:11
  • @KentWeigel I don't have any tsconfig.json file, I used the typescript project template in Visual Studio 2017. Commented Mar 18, 2018 at 14:13

3 Answers 3

1

Seems this is a bug in typescript. https://github.com/Microsoft/TypeScript/issues/13422 .

There's no resolution in the works. For the moment, your approach is correct.

import {ModuleA} from './ModuleA.js'
Sign up to request clarification or add additional context in comments.

1 Comment

Visual Studio 2017 builds .ts files when they are saved, so there is no real issue to import the .js files. But that's too bad.
1

you could also use webpack to build a single js file. Then you do not need to add the extension.

see guide for setting up webpack for typescript

Comments

1

When you don't specify compiler options on the command line for tsc and you don't have a tsconfig.json file, typescript uses defaults. According to the typescript documentation the defaults are es3 for the language emitted, and commonjs for the module loader. I don't find these options acceptable, so I specify different options in a tsconfig.json file. Try setting up a project as follows and I think you'll be happy with the results. It may seem like a lot of work, but you can export the project to a template when your done, and you won't ever have to do it again. This assumes you have npm set up on your machine.

Create a new project in VS 2017, choosing ASP.NET Web Application(.NET Framework) as the template. I know this may not sound right, but bear with me, as you will end up with a minimal project that doesn't include much that you don't want. On the next page of the wizard, choose Empty and un-check every box and leave it with no authentication. Finish the wizard.

Add the following files at the root level of the project.

package.json:

{
  "version": "1.0.0",
  "name": "asp.net",
  "author": "you",
  "private": true,
  "dependencies": {
    "core-js": "^2.5.3",
    "systemjs": "^0.21.0"
  }
}

tsconfig.json:

{
  "compilerOptions": {
    "module": "system",
    "target": "es5",
    "noImplicitAny": true,
    "noEmitOnError": true,
    "sourceMap": true
  },
  "files": [
    "app/app.ts"
  ],
  "exclude": [
    "node_modules"
  ]
}

system.config.js:

(function (global) {
  SystemJS.config({
    paths: {
      'npm:': '/node_modules/'
    },
    map: {
      app: '/app'
    },
    packages: {
      app: {
        main: 'app.js',
        defaultExtension: 'js'
      }
    }
  })
})(this);

index.html:

<!DOCTYPE html>
<html>
<head>
  <base href="/" />
  <meta charset="utf-8" />
  <title>Typescript with SystemJS and Modules Demo</title>
  <script src="node_modules/core-js/client/shim.min.js"></script>
  <script src="node_modules/systemjs/dist/system.js"></script>
  <script src="system.config.js"></script>
  <script>
    SystemJS.import("app/app.js").catch(function (e) { console.log(e); });
  </script>
</head>
<body>
  <div id="personDiv"></div>
</body>
</html>

Also, create an app folder and put the following 2 files in it:

app.ts:

import { Person } from "./person";

export class App {
  constructor() {
    let person: Person = new Person();
    let div: HTMLDivElement = <HTMLDivElement>document.getElementById('personDiv');
    div.innerHTML = person.getName();
  }
}

// Use this assignment to start execution.
let a: App = new App();

// The following doesn't appear to work with SystemJS. It does with plain TypeScript.
// It is probably because SystemJS already defines a listener for window.onload,
// although I haven't verified that.
//window.onload = () => {
//  let a: App = new App();
//  let person = new Person();
//  alert(person.getName);
//}

person.ts:

export class Person {
  fullName: string;

  constructor() {
    this.fullName = "Test Guy";
  }

  getName():string {
    return this.fullName;
  }
}

Then build and run the app. The results should show you that importing is working correctly.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.