Systemjs: Automatic file extension?

Created on 27 Sep 2015  路  6Comments  路  Source: systemjs/systemjs

I'm used to RequireJS and wanted to try out SystemJS in combination with Typescript (Typescript compiled to ES5 in _System.register_ format, options: --module system --target ES5). But it seems that SystemJS does not append a _.js_ extension to the file names if it loads imported modules.

This is a bit confusing: On the one hand the main page example imports the file "main.js" with an extension, on the other hand I see many projects referencing the files without any file extension (In TypeScript there are also no extensions). But if I do that in my project it will try to access the sub-module files without extension ("module-xyz" instead of "module-xyz.js") which results in a 404.

My configuration is as follows:

<script src="system/system.js"></script>
<script>
  System.config({
    baseURL: ".",
    paths: {
      "*": "*.js" // should load all libraries with .js appended
    }
  });
  System.import('main');
</script>

Obviously _main_ and _asys_util_ will be found, but anything referenced from _asys_util_ will not be found.

Code from main.ts:

/// <reference path="../dist/asys_util.d.ts" />
import * as asys_util from 'asys_util';

var x = new asys_util.exception.IllegalArgumentException('xxx');
console.log(x);

Compiled to main.js:

System.register(['asys_util'], function(exports_1) {
    var asys_util;
    var x;
    return {
        setters:[
            function (_asys_util) {
                asys_util = _asys_util;
            }],
        execute: function() {
            console.log(asys_util);
            x = new asys_util.exception.IllegalArgumentException('xxx');
            console.log(x);
        }
    }
});

Example content of asys_util.ts:

import {exception} from './asys_util/exception';
export var asys_util = { // treat asys_util like a package
    exception: exception
};

This will be compiled to JavaScript in asys_util.js:

System.register(['./asys_util/exception'], function(exports_1) {
    var exception_1;
    var asys_util;
    return {
        setters:[
            function (_exception_1) {
                exception_1 = _exception_1;
            }],
        execute: function() {
            exports_1("asys_util", asys_util = {
                exception: exception_1.exception
            });
        }
    }
});

Since _'./asys_util/exception'_ has no mapping it should be treated as an relative URL. But it tries to load _'./asys_util/exception'_ instead of _'./asys_util/exception.js'_.

For me it looks like that relative paths have an issue. If I write 'asys_util/exception' instead of './asys_util/exception' I get the correct file with extension.

support

Most helpful comment

Use the System.defaultJSExtensions: true property, or use package configuration to set default extensions:

System.config({
  packages: {
    './path/to/ts-files': {
      defaultExtension: 'js'
    }
  }
});

Note that a package represents a "folder", so even '.' is a valid package name.

All 6 comments

Use the System.defaultJSExtensions: true property, or use package configuration to set default extensions:

System.config({
  packages: {
    './path/to/ts-files': {
      defaultExtension: 'js'
    }
  }
});

Note that a package represents a "folder", so even '.' is a valid package name.

This does not work for me. My config:

System.config({
    baseURL: '.',
    packages: {
        '.': {
            defaultJSExtensions: 'js'
        }
    },
    meta: {
        '*': {
            format: 'register'
        }
    },
});
System.import('asys_util'); // just for test reasons

My asys_util.js:

System.register(['./asys_util/collection', './asys_util/exception', './asys_util/func'], function(exports_1) {
    var collection, exception, func;
    return {
        setters:[
            function (_collection) {
                collection = _collection;
                exports_1("collection", collection);
            },
            function (_exception) {
                exception = _exception;
                exports_1("exception", exception);
            },
            function (_func) {
                func = _func;
                exports_1("func", func);
            }],
        execute: function() {
        }
    }
});

It still tries to access 'asys_util/collection' instead of 'asys_util/collection.js'

It should work - the package property is defaultExtension, not defaultJSExtension which is the global property. See the docs at https://github.com/systemjs/systemjs/blob/master/docs/config-api.md#packages for more info on the packages API.

That typo was my bad. Right. That solves the issue. Thank you very much!

But now i ran into a new one with cyclic dependencies. I will write a separate issue for that.

Hi,

Even though the issue is closed, I think I am in a write thread to ask a relevant question.
I am working on an Angular TS project. I am using an external library which has lot of components (created by me), and loading it locally using npm(verdaccio).

The solution which I am looking for is I want the default extension to be .ts and not .js. So I have tried with following code.

'./path/to/ts-files':{
                defaultExtension: 'ts'
            },

But no luck, it gives me 404 errors as the SysyemJs looks for files with .js extension. But the fact is I only have typescript files. Thanks in advance!
-Sudeep

I am in DJango, and this works for me... i am using sub app named 'app', i solved by updating system.config.js ,
map : { 'app' : 'app' } to map : {'app' : 'app_name/path_to_url' }

Was this page helpful?
0 / 5 - 0 ratings