Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Typescript: how to import non .ts files as raw string

This discussion suggests that in typescript 2, it is possible to import an external, non css file as a string to be used in my class.

I'm trying to take advantage of this to import HTML into my typescript component so that my application will make one HTTP request fetching the component & its HTML template instead of two separate requests. I've tried:

typings.d.ts

declare module "*!text" {
    const value: any;
    export default value;
}

app.component.ts

import htmlTemplate from './app.component.html!text';
...
constructor(){console.log(htmlTemplate)}

The typescript compiler raises no error. However, when I run the application, it crashes after requesting http://localhost/text and getting a 404 not found`

I've also tried: typings.d.ts

declare module "*.html" {
    const value: any;
    export default value;
}

app.component.ts

import htmlTemplate from './app.component.html';
...
constructor(){console.log(htmlTemplate)}

Again no error is raised during compilation but the app requests http://localhost/app.component.html.js and crashes after receiving a 404 not found response.

The template is in app.component.html, in the same folder as the .ts file. I'm running typescript 2.0.2. How can I import my .html templates and .css stylesheets as strings?

like image 253
BeetleJuice Avatar asked Sep 08 '16 15:09

BeetleJuice


1 Answers

Here is how I did it, for my Angular 2 rc.6 application

1 Install typescript 2 if you haven't already. Set it as the compiler

npm install [email protected]

2 Set module to system in tsconfig.json

"compilerOptions": {
    "target": "ES5",
    "module": "system",
    ...
}

3 This broke the app. To fix, edit every component to use system modules; replace...

@Component({
    module: moduleId,
    templateUrl: './app.component.html',
})

with...

@Component({
    module: __moduleName,
    templateUrl: './app.component.html',
})

4 This will raise errors in typescript because __moduleName is unknown. To get rid of it, create a custom definition file (.d.ts) in the same directory as your bootstrap file.

custom.typings.d.ts

/** So typescript recognizes this variable wherever we use it */
declare var __moduleName: string;

/** Will be needed later to import files as text without raising errors */
declare module "*!text"

5 Add a reference to the typed definitions in your bootstrap file so typescript sees them when parsing your code: main.ts

///<reference path="./custom.typings.d.ts"/>

6 Make sure the app still runs. Next, install systemjs-plugin-text:

npm install [email protected]

7 Set the new plugin as a map in systemjs.config.js

System.config({
    map:{
        'app':        'app',
        '@angular':   'node_modules/@angular',
        //'text' map is used to import files as raw strings
        text:         'node_modules/systemjs-plugin-text/text.js'
    }
});

8 Now we're all set to import files as strings

// this line should raise no error if steps 4 & 5 were completed correctly
import htmlTemplate from './app.component.html!text';
console.log(htmlTemplate); //will print the file as a string in console

@Component({
    moduleId: __moduleName,
    template: htmlTemplate, //success!!
})

That's it! Now if you use systemjs-builder or a similar bundling tool, the external template will be inlined.

like image 186
BeetleJuice Avatar answered Nov 03 '22 06:11

BeetleJuice