Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Import html from typescript with webpack

I am trying to import html into a variable in typescript using webpack.

Here is my setup:

package.json:

{
  "devDependencies": {
    "awesome-typescript-loader": "^3.2.3",
    "html-loader": "^0.5.1",
    "ts-loader": "^2.3.7",
    "typescript": "^2.5.3",
    "webpack": "^3.6.0"
  }
}

webpack.config.js:

const path = require('path');
const webpack = require('webpack');

module.exports = {
  context: path.join(__dirname),
  entry: './main',
  output: {
    path: path.join(__dirname, 'dist'),
    filename: 'app.js'
  },
  resolve: {
    // Add '.ts' and '.tsx' as resolvable extensions.
    extensions: [".ts", ".js"],
    modules: [
      "node_modules",
      path.join(__dirname, 'app'),
    ],
  },
  module: {
    rules: [
      {
        enforce: 'pre',
        test: /\.html$/,
        loader: 'html-loader',
      },
      // Faster alternative to ts-loader
      { 
        test: /\.tsx?$/, 
        loader: 'awesome-typescript-loader',
        options: {
          configFileName: 'tsconfig.json',
        },
        exclude: /(node_modules)/,
      },
    ],
  },  
};

main.ts:

import template from './template.html';
console.log(template);

template.html:

<p>Hello World !</p>

When I try to compile with with webpack:

$ ./node_modules/.bin/webpack 

[at-loader] Using [email protected] from typescript and "tsconfig.json" from /tmp/test/tsconfig.json.


[at-loader] Checking started in a separate process...

[at-loader] Checking finished with 1 errors
Hash: d06d08edc313f90c0533
Version: webpack 3.6.0
Time: 2194ms
 Asset     Size  Chunks             Chunk Names
app.js  2.72 kB       0  [emitted]  main
   [0] ./main.ts 136 bytes {0} [built]
   [1] ./template.html 40 bytes {0} [built]

ERROR in [at-loader] ./main.ts:1:22 
    TS2307: Cannot find module './template.html'.

I've been on this for half a day so you can be sure template.html is where it is supposed to be.

From what I understand from webpack config is that the html-loader is supposed to process the file first, so it should load the content of the html file into the variable. At least, this used to work with es6...

Can anyone tel me how to load html into a variable with webpack / typescript? Or at least what is wrong with my approach.

like image 262
Luke Skywalker Avatar asked Sep 30 '17 14:09

Luke Skywalker


1 Answers

An easy workaround is to stick with CommonJS "require" when loading non-TypeScript assets:

const template = require('./template.html');

If you'd prefer to keep using import, it's possible to configure the TypeScript compiler to load the file as a string. The method below worked for me under TypeScript 2.4.2.

Add this block to your project's type declarations file (mine is called typings.d.ts):

// typings.d.ts
declare module '*.html' {
  const content: string;
  export default content;
}

You should now be able to import html files like this:

// main.ts
import template from './template.html';
console.log(template); // <p>Hello world !</p>

Full disclosure: my project used different loaders from yours (see below).

// webpack.config.js
config.module = {
  rules: [
    {
      test: /\.ts$/,
      loader: '@ngtools/webpack'
    },
    {
      test: /\.html$/,
      use: 'raw-loader'
    }
  ]
}

There's a Github thread here where other solutions are discussed.

like image 104
mamacdon Avatar answered Sep 27 '22 23:09

mamacdon