4

I start with the following import in my TypeScript file. Note no .ts extension implies that I am importing a TypeScript module:

import githubService from './github.service';

This gets transpiled to:

var github_service_1 = require('./github.service');

When SystemJS tries to load this module, it issues the following HTTP command:

GET /github.service

instead of GET /github.service.js. This obviously does not work.

How can I make TypeScript work with SystemJS?

Here's my tsconfig.json file:

{
    "compilerOptions": {
        "target": "es5",
        "module": "commonjs",
        "outDir": "./dist",
        "declaration": false,
        "noImplicitAny": false,
        "removeComments": true,
        "noLib": false,
        "emitDecoratorMetadata": true,
        "experimentalDecorators": true,
        "sourceMap": true
    },
    "exclude": [
        "node_modules"
    ],
    "compileOnSave": false
}

I also tried to change the module option above to system (changing the generated module format from CommonJS to SystemJS), I still get the same issue.

3 Answers 3

1

I think that your problem is missing js extensions in the module names. Not so long ago System.js changed this and now to be able to resolve them without explicitly specifiyng '.js' you must setup System.js options in your index.html like this:

System.defaultJSExtensions = true;

For more info: defaultJSExtensions

EDIT

As pointed out by @Naresh the defaultJSExtensions is obsolete now. The preferable way as it seems now is to use packages option in config instead.

Hope this helps.

Sign up to request clarification or add additional context in comments.

6 Comments

That works! Thanks, @amid. Reading the docs for this option, it says "Note that this is a compatibility property for transitioning to using explicit extensions and will be deprecated in future." Does that mean that they expect the TypeScript transpiler to generate the correct extentions?
I hope so. Personally I would find it rather strange to write in my typescripts files imports with '.js' extensions in the end. Other options is wait till the time when we do not need to use external loader. Or maybe use other loader.
Thanks for sharing your views, @amid.
and how to use the packages option?
For every package you can specify its own defaultExtension: 'js property. Check the link I have posted
|
1

In System 2.0+ you can use Loader Hooks to customize things

https://github.com/systemjs/systemjs/blob/2.0.0/docs/hooks.md#loader-hooks

For example, to add the .js file extension to modules as they are resolved, you can override the System.prototype.resolve function:

const origResolve = System.constructor.prototype.resolve

System.constructor.prototype.resolve = function(moduleId, ...args) {
  return origResolve.call(
    this, 
    moduleId + '.js', // add .js extension to original module id
    ...args
  )
}

Note that this is a pretty naive example as you may not want to add .js to every module id, but it shows how you can take control of the configuration.

Comments

0

In your tsconfig:

"module": "commonjs",

Since you are using systemjs change your module format to be system.

1 Comment

I have tried that as well (please see the last sentence of my question). Technically SystemJS is expected to be able to load both formats.

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.