Home > Software engineering >  Webpack failed to parse TypeScript module: Unexpected token
Webpack failed to parse TypeScript module: Unexpected token

Time:07-04

I'm trying to build a TypeScript browser game using webpack. My current configuration used to work fine, but now I get the following error when running the following command to compile the application into a single .js file and launch it.

npx webpack
asset index.js 1.6 KiB [compared for emit] (name: main)
./src/index.ts 1.22 KiB [built] [code generated] [1 error]

ERROR in ./src/index.ts 11:48
Module parse failed: Unexpected token (11:48)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
|     
|     // Start game listener
>     document.getElementById("start-game-button")!.addEventListener("click", () => {
|         startGame()
|     });

webpack 5.73.0 compiled with 1 error in 115 ms

This is my current TypeScript configuration in the tsconfig.json:

{
    "compilerOptions": {
        "target": "es2016",
        "module": "commonjs",
        "rootDir": "src",
        "esModuleInterop": true,
        "forceConsistentCasingInFileNames": true,
        "strict": true,
        "skipLibCheck": true
    },
    "include": [
        "./src/**/*.ts"
    ],
    "exclude": [
        "node_modules",
        "./src/index.js"
    ]
}

This is the package.json file:

{
  "name": "favicraft",
  "version": "1.0.0",
  "main": "index.js",
  "scripts": {
    "build": "npx webpack",
    "build:watch": "npx webpack -w"
  },
  "devDependencies": {
    "ts-loader": "^9.3.0",
    "typescript": "^4.6.4",
    "webpack-cli": "^4.10.0"
  },
  "dependencies": {
    "webpack": "^5.72.1"
  }
}

And here is my webpack.config.js file:

const path = require('path');

module.exports = {
    mode: 'development',
    entry: './src/index.ts',
    module: {
        rules: [
        {
            test: /\.ts$/,
            use: 'ts-loader',
            exclude: /[node_modules|index.js]/,
        },
        ],
    },
    resolve: {
        extensions: ['.ts', '.js'],
    },
    output: {
        filename: 'index.js',
        path: path.resolve(__dirname, 'src'),
  },
};

From what I can see, the module parsing error points to a line in my index.ts file. However, this file has no syntax errors nor strange characters which could be causing the error at line 11:48.
Just for reference, here's my index.ts file, even though I don't think it would be on any help:

import globals from "./globals";
import { Game } from "./game";
import { sleep } from "./utils";
import { Renderer } from "./renderer";


// Initialize the page
document.addEventListener("DOMContentLoaded", () => {
    
    // Start game listener
    // ###### This is the line that is supposed to be causing the error #########
    document.getElementById("start-game-button")!.addEventListener("click", () => {
        startGame()
    });

    const canvas = document.getElementById("game-canvas") as HTMLCanvasElement;
    
    // Initialize the canvas
    canvas.width = Renderer.WIDTH;
    canvas.height = Renderer.HEIGHT;

    Renderer.init(canvas);   

});


async function startGame(): Promise<void> {

    if (globals.playing) {
        return;
    }

    const startGameButton = document.getElementById('start-game-button') as HTMLButtonElement;
    startGameButton.hidden = true;
    startGameButton.disabled = true;

    const title = document.getElementById("start-game-title") as HTMLHeadingElement;
    document.body.appendChild(title);
    title.innerHTML = "Ready to play?";

    await sleep(1000);

    title.innerHTML = "Then faster your belt...";

    await sleep(1000);

    title.innerHTML = "Go!";

    await sleep(1000);

    title.innerHTML = "";

    const game = Game.getInstance();
    game.start();

}

I have already taken a look at various similar questions and answers, but none of them could solve my problem. Any help would be appreciated.

CodePudding user response:

Is there not a syntax error on that line? There is a rogue "!" here:

document.getElementById("start-game-button")!.addEventListener("click", () => {
                                            ^

CodePudding user response:

I have found a solution to my problem. I have added the following compiler option to my tsconfig.json file:

"sourceMap": true

I have then changed my webpack.config.js file's rules field as such (and also removed some redundant configs):

const path = require('path');

module.exports = {
    mode: 'development',
    entry: './src/index.ts',
    module: {
        rules: [
        {
            test: /\.ts$/,
            use: {
                loader: 'ts-loader'
            },
            exclude: /node_modules/,
        },
        ],
    },
    resolve: {
        extensions: ['.ts'],
    },
    output: {
        filename: 'index.js',
        path: path.resolve(__dirname, 'src'),
  },
};

And now everything compiles successfully. I hope this helps somebody else too.

  • Related