Include html into typescript using webpack

Attempting to include HTML content into a variable using TypeScript and webpack has been my challenge.

This is the current 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: {
    // Include '.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>

Upon attempting to compile with webpack:

$ ./node_modules/.bin/webpack 

[at-loader] Using <a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="d5b1bcd5e5bfccd5c9dfccc288d8ffedbcb9">[email protected]</a> from typescript and "tsconfig.json" from /tmp/test/tsconfig.json.


[at-loader] Validation carried out in a separate process...

[at-loader] Finished verification with 1 issue
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: Module './template.html' not found.

I've spent half a day on this task and can confirm that template.html is located where it should be.

Based on the webpack configuration, the html-loader should preprocess the file first so as to load the HTML content into the variable. It worked correctly with ES6 previously...

Could someone advise me on loading HTML content into a variable using webpack/typescript? Alternatively, point out any flaws in my approach.

Answer №1

If you're looking for a simple solution, try sticking with CommonJS "require" instead of using import when loading non-TypeScript assets:

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

However, if you prefer to continue using import, you can configure the TypeScript compiler to load the file as a string. The following method worked well for me with TypeScript 2.4.2.

Just add this code block to your project's type declarations file (I named mine typings.d.ts):

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

Now you can import HTML files like this:

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

Keep in mind that my project may have utilized different loaders compared to yours (as shown below).

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

If you're interested, there is a discussion about other solutions on a Github thread available here.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Troubleshooting import errors with Typescript for C3 and D3 libraries

I have recently started working on a project using the C3 graphing library within an Ionic2/Angular2 TypeScript setup. After installing C3 via npm and the type definitions via tsd, I imported it into my own TypeScript file like this: import {Component} fr ...

What is the best way to send the body in a GET request using Angular 2+?

My API's GET method is located at "http://abc/abc" Typically, the GET method includes parameters as get(url, options), with only two arguments. However, in my scenario, I need to include a body with the request. The body structure is as follows: { ...

developing TypeScript classes in individual files and integrating them into Angular 2 components

We are currently putting together a new App using Angular2 and typescript. Is there a more organized method for defining all the classes and interfaces in separate files and then referencing them within angular2 components? import {Component, OnInit, Pi ...

Show the user's chosen name in place of their actual identity during a chat

I'm facing an issue where I want to show the user's friendly name in a conversation, but it looks like the Message resource only returns the identity string as the message author. I attempted to retrieve the conversation participants, generate a ...

Issue: Unable to load the file named 'script.ts' while employing chrome.scripting.executeScript

Currently, I am working on developing a chrome extension using Vite with React and Typescript along with CRXJS. This is my initial project in this domain. The issue I am encountering is related to executing a script on the current tab when a button is clic ...

Creating a personalized aggregation function in a MySQL query

Presenting the data in tabular format: id | module_id | rating 1 | 421 | 3 2 | 421 | 5 3. | 5321 | 4 4 | 5321 | 5 5 | 5321 | 4 6 | 641 | 2 7 | ...

Developing a type specifically for this function to operate on tuples of varying lengths

I am currently developing a parser combinator library and I am in need of creating a map function that can take N parsers in a tuple, along with a function that operates on those N arguments and returns a parser that parses into the return type specified b ...

Definition of Angular 2 File

I have developed a custom Gantt chart library using D3 in vanilla JavaScript. Now, I am trying to integrate it into my Angular 2 application. After installing D3 via npm and adding the necessary type files and the Gantt chart module to node_modules, I enco ...

A guide on defining global TypeScript interfaces within Next.js

In the process of developing an ecommerce web application with next.js and typescript, I found myself declaring similar interfaces across various pages and components. Is there a method to create global interfaces that can be utilized by all elements wit ...

The connection named "default" was not located

Error ConnectionNotFoundError: Connection "default" was not found. I encountered this error when I implemented the dependency inversion principle in my project. ormconfig.json { "name": "default", "type": " ...

Tips for retaining the value of a variable when the page is reloaded

I need to store the value of the variable loggedIn, as it determines the behavior of a function in appComponent.html. Can you explain how I can achieve this? Template of app component: <li class="nav-item"> <a class ...

React and Typescript Multimap Approach

I'm a beginner in TypeScript and I am struggling to understand how to create a multimap. The code I have is shown below. My goal is to loop through the itemArray and organize the items based on their date values. I want to use the date as the key for ...

The text "Hello ${name}" does not get substituted with the name parameter right away in the message string

I'm struggling to get the basic TypeScript feature to work properly. Everywhere I look on the Internet, it says that: var a = "Bob" var message = 'Hello ${a}' should result in a console.log(message) printing "Hello Bob". Howeve ...

Encounter an issue when running npm commands for Laravel Vue.js with npm runs dev and npm runs watch

Encountering errors with npm runs dev and npm runs watch Can anyone assist me with this? node_modules/cross-env/bin/cross-env.js NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setu ...

"Angular EventEmitter fails to return specified object, resulting in undefined

As I work on a school project, I've encountered a hurdle due to my lack of experience with Angular. My left-nav component includes multiple checkbox selections, and upon a user selecting one, an API call is made to retrieve all values for a specific " ...

Building AngularJS directives using CSS classes

My current approach is as follows: class AService { $http: any; $state: any; static $inject = ['$http', '$state']; constructor($http, $state) { this.$http = $http; this.$state = $state; }; Dealing w ...

Error: You're attempting to read content that has already been accessed

Encountered the following error message: sp-webpart-workbench-assembly_en-us_b854c4b93cc10a271230fd4a9e7b2b9b.js:661 Uncaught (in promise) TypeError: Already read at t.e.json (sp-webpart-workbench-assembly_en-us_b854c4b93cc10a271230fd4a9e7b2b9b. ...

What is the best way to apply multiple array filters to an object list in react.js?

Looking to filter an array of items using multiple filter arrays in order to display only the items that match all selected filters. For example: The main array contains a table with the following data: ID TypeID LocationID Name 1 2 ...

Ways to avoid Next.js from creating a singleton class/object multiple times

I developed a unique analytics tool that looks like this: class Analytics { data: Record<string, IData>; constructor() { this.data = {}; } setPaths(identifier: string) { if (!this.data[identifier]) this.da ...

Accessing information independent of Observable data in TypeScript

When attempting to send an HttpRequest in Typescript, I encountered an issue where the received data could not be stored outside of the subscribe function. Despite successfully saving the data within the subscribe block and being able to access it there, ...