Webpacker: recommended way to use Angular templateUrl?

Created on 16 May 2017  路  10Comments  路  Source: rails/webpacker

Hello,

I'm upgrading from a webpacker based project that was written before https://github.com/rails/webpacker/pull/153

It's an Angular 4 app that uses separate template files which are referenced from components in the same directory.

Previous to https://github.com/rails/webpacker/pull/153 using raw-loader did the trick https://github.com/webpack-contrib/raw-loader That is no longer working, to verify I tested on a newly generated Rails 5.1 app using the rails new webpacker-app --webpack=angular and was unable to find a way to reference an external template.

https://github.com/taboularasa/webpacker-app/tree/master/app/javascript/hello_angular/app

app/javascript/hello_angular/app/app.component.ts:

import { Component } from '@angular/core';

@Component({
  selector: 'hello-angular',
  templateUrl: './app.component.html'
})
export class AppComponent {
  name = 'Angular!';
}

app/javascript/hello_angular/app/app.component.html:

<h1>Hello {{name}}</h1>

Does anyone have an example of this working or any thoughts? I do believe this is a webpacker related issue since I have this working on an earlier version of webpacker. Happy to go into more detail if there is anyone familiar with the problem or thinks they may be able to help

Thanks!

Most helpful comment

@Jeremy-Walton Here is how you would do it:

yarn add html-loader

Add to config/webpacker/loaders/html.js

module.exports = {
  test: /\.html$/,
  use: [ {
    loader: 'html-loader?exportAsEs6Default',
    options: {
      minimize: true
    }
  }]
}

Add to extensions

  extensions:
    - .elm
    - .coffee
    - .html

Setup a custom definition

// app/javascript/packs/angular_app/html.d.ts
declare module "*.html" {
  const content: string;
  export default content;
}

Import Html string

import { Component } from '@angular/core';
import templateString from './template.html'

@Component({
  selector: 'hello-angular',
  template: templateString
})
export class AppComponent {
  name = 'Angular!';
}

Setup a template.html file relative to component

<h1>Hello {{name}}</h1>

That's all 馃憤 馃槃

All 10 comments

I found a solution by adding typings for require js and then using template with require:

import { Component } from '@angular/core';

@Component({
  selector: 'hello-angular',
  template: require('./app.component.html')
})
export class AppComponent {
  name = 'Angular!';
}

@taboularasa Do you have an example of how you set this up using typings for requirejs? I am having the same issue happen and I can't seem to get it working.

@Jeremy-Walton Here is how you would do it:

yarn add html-loader

Add to config/webpacker/loaders/html.js

module.exports = {
  test: /\.html$/,
  use: [ {
    loader: 'html-loader?exportAsEs6Default',
    options: {
      minimize: true
    }
  }]
}

Add to extensions

  extensions:
    - .elm
    - .coffee
    - .html

Setup a custom definition

// app/javascript/packs/angular_app/html.d.ts
declare module "*.html" {
  const content: string;
  export default content;
}

Import Html string

import { Component } from '@angular/core';
import templateString from './template.html'

@Component({
  selector: 'hello-angular',
  template: templateString
})
export class AppComponent {
  name = 'Angular!';
}

Setup a template.html file relative to component

<h1>Hello {{name}}</h1>

That's all 馃憤 馃槃

@gauravtiwari This worked to render the html, but I had to use this configuration for html-loader to prevent angular errors. E.G. Promise rejection: Template parse errors: Can't bind to 'ngforOf' since it isn't a known property of 'tr'

https://coderwall.com/p/rrhcag/using-webpack-html-loader-with-angular2

html.js

module.exports = {
  test: /\.html$/,
  use: [{
    loader: 'html-loader',
    options: {
      minimize: true,
      removeAttributeQuotes: false,
      caseSensitive: true,
      customAttrSurround: [ [/#/, /(?:)/], [/\*/, /(?:)/], [/\[?\(?/, /(?:)/] ],
      customAttrAssign: [ /\)?\]?=/ ]
    }
  }]
}

Awesome @Jeremy-Walton 馃憤 馃挴 Thanks for sharing :)

@gauravtiwari should the angular template be updated to include an example of using external files for templates and styles? I wouldn't mind putting together a PR for that.

@taboularasa Added it here - https://github.com/rails/webpacker#use-html-templates-with-typescript-and-angular

OMG, thanks everyone for this (though the hoops to jump through are鈥 lot). I don't know what declare module actually does (and I did read this), but the linked document from @gauravtiwari worked for me, too. What a nightmare :(

By the way, for anyone else who comes across this like I just did, the documentation for this moved from

https://github.com/rails/webpacker#use-html-templates-with-typescript-and-angular

to:

https://github.com/rails/webpacker/blob/master/docs/typescript.md#html-templates-with-typescript-and-angular

Slight change with the current version of html-loader.
exportAsEs6Default needs the value 'es6' now.

use: [ {
    loader: 'html-loader',
    options: {
        exportAsEs6Default: 'es6',
        minimize: true,
        collapseWhitespace: true,
    }
}],
Was this page helpful?
0 / 5 - 0 ratings

Related issues

christianrojas picture christianrojas  路  3Comments

suhomozgy-andrey picture suhomozgy-andrey  路  3Comments

vtno picture vtno  路  3Comments

ijdickinson picture ijdickinson  路  3Comments

pioz picture pioz  路  3Comments