Search code examples
typescriptexpressimporttyping

Typescript importing html files as a string (Express)


I'm trying to import an html file with import template as "./template.html" as a string in order to provide it to the user through Express's res.end(template); function.

I have created an index.d.ts file in the root directory of my project with the following inside:

declare module '*.html' {
    const value: string;
    export default value;
}

It lets me import template.html without any issues but when I run the program it says

/home/koen/Workspace/xyz/src/template.html:1
<!DOCTYPE html>
^

SyntaxError: Unexpected token <
    at Module._compile (internal/modules/cjs/loader.js:723:23)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:789:10)
    at Module.load (internal/modules/cjs/loader.js:653:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:593:12)
    at Function.Module._load (internal/modules/cjs/loader.js:585:3)
    at Module.require (internal/modules/cjs/loader.js:692:17)
    at require (internal/modules/cjs/helpers.js:25:18)
    at Object.<anonymous> (/home/koen/Workspace/xyz/out/index.js:11:41)
    at Module._compile (internal/modules/cjs/loader.js:778:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:789:10)

It's almost as if it's trying to run the html as Javascript or something. Any ideas why this is happening? I'm stuck...


Solution

  • Fixed it by installing Babel. Thanks to index.d.ts typescript knew what type the content would be (String). But it didn't know how to parse it.

    In case anyone else if having the same issue:

    1. Install babel core and cli

    Run the following command: npm install --save-dev @babel/cli @babel/core

    2. Install the Typescript preset

    Babel is going to take over the transpilation of Typescript to Javascript. In order to do this we have to install the preset-typescript preset.

    Run the following command: npm install --save-dev @babel/preset-typescript

    Now open babel.config.json in the root dir of your project (If it doesn't exist, create it) and add the following:

    {
        "presets": [
            "@babel/preset-typescript"
        ]
    }
    

    3. Prevent tsc from transpiling

    We are not completely getting rid of tsc here. We will still use it in order to check types. But as mentioned before, Babel is taking over the transpilation process and we don't want a conflict. Inside of tsconfig.json, set compilerOptions.noEmit to true.

    4. Optional: install the @babel/preset-env preset

    If you are planning on using ES2015+ syntax, you have to install this syntax. The process is the same as in step 2.

    5. Install babel-plugin-transform-html-import-to-string

    Oh boy... Yes. I know it's a long name. This is a Babel plugin that will let us import html files.

    Run the command: npm install --save-dev babel-plugin-transform-html-import-to-string

    Open the .babelrc file in the root dir of your project (Once again, if it doesn't exist, create it) and add the following:

    {
        "plugins": [
            "transform-html-import-to-string"
        ]
    }
    

    6. Add a script to package.json to build and run the application

    "scripts": {
        "start": "tsc && babel src --out-dir lib --extensions '.ts,.tsx' && node lib/index.js"
    }
    

    tsc will make sure that all the typing is correct, babel will take over the transpilation part.