Rails + Angular で テンプレートに html ファイルを使えるようにした

ほぼこれの通りにやるだけなんだけど一応メモ https://github.com/rails/webpacker/blob/master/docs/typescript.md#html-templates-with-typescript-and-angular

デフォルトだとどうなるか?

環境は rails new で webpack=angular にしただけ。

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

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

これでやるとデベロッパーツールの console に http://localhost:5000/app.component.html 404 (Not Found) が出る。

解決方法

  1. webpack に html も取り扱ってもらえるようにする
    $ yarn add html-loader
    
  2. config/webpack/loaders/html.js というファイルを作成して以下のように記述
    module.exports = {
      test: /\.html$/,
      use: [{
        loader: 'html-loader',
        options: {
          minimize: true,
          removeAttributeQuotes: false,
          caseSensitive: true,
          customAttrSurround: [ [/#/, /(?:)/], [/\*/, /(?:)/], [/\[?\(?/, /(?:)/] ],
          customAttrAssign: [ /\)?\]?=/ ]
        }
      }]
    }
    
  3. config/webpack/environment.js に追記
    const { environment } = require('@rails/webpacker')
    const typescript =  require('./loaders/typescript')
    const html = require('./loaders/html') // 👈 追加
    
    environment.loaders
      .append('typescript', typescript)
      .append('html', html)                // 👈 追加
    module.exports = environment
    
  4. config/webpacker.yml の extensions に .html を追加する

  5. index.ts のあるディレクトリに html.d.ts ファイルを作成する

    declare module "*.html" {
      const content: string
      export default content
    }
    

    *.d.ts ファイルは TypeScript の型定義をなんやするらしい。まだよくわかっていない。

結果

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

@Component({
  selector: 'hello-angular',
  template: templateString
})

export class AppComponent {
  name = 'Angular!'
}

templateUrl でファイルを見に行くのではなく import したものを template に埋め込むことで実現できる

注意点として、
import templateString from './template.html'
import templateString from 'template.html' にしてしまうと
Uncaught Error: Cannot find module "appTemplate.html" でエラーになる