Search code examples
typescriptmodulesystemjs

Typescript & SystemJS: customize module resolution for a specific extension


I use SystemJS and typescript 2.0.2 to develop my application.

systemjs.config.js

var map = {
    'app':   'dist',
};

var packages = {
    'app':  { main: './main.js',  defaultExtension: 'js' }
};

So when I use:

import {Services} from './service.module'

//result: load {baseURL}/dist/service.module.js

How can I overwrite this behavior and get the compiler to not append any extension for a specific file? For instance if I do:

import htmlTemplate from './app.component.html';

//result: 404 Not found - {baseURL}/dist/app.component.html.js

On the other hand, if I use absolute path:

import htmlTemplate from 'app.component.html';

//result: 404 Not found - {baseURL}/app.component.html

I'd like {baseURL}/dist/app.component.html without having to use the full path in the import


Solution

  • I believe that systemjs by itself can not load html. I use systemjs-plugin-text for that:

    npm install systemjs-plugin-text
    

    Then, this config works for me:

    var map = {
        'app':   'dist',
        'plugin-text': 'node_modules/systemjs-plugin-text/text.js'
    };
    
    var packages = {
        'app':  {
            main: './m1.js',
            defaultExtension: 'js',
            meta: { '*.html' : { loader: 'plugin-text' }}
        }
    };
    
    SystemJS.config({
        map: map,
        packages: packages
    });
    

    because apparently loader, when it applies, overrides any other setting in package config.

    NOTE1 this will work only if module in typescript compilerOptions is set to system.

    NOTE2 for the HTML import to typecheck with typescript 2.0, you have to add this wildcard ambient declaration to declarations.d.ts file:

    declare module "*.html" {
        const templateString: String;
        export default templateString;
    }
    

    I added example repo on github