typescriptwebpackts-loader

ts-loader doesn't recognize typescript syntax


What I have:

webpack.config.js:

located in the root of project

//@ts-check

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


// module.exports = {
/**
 * @type {import('webpack').Configuration}
 */
const config = {
    // entry: './source/index.tsx',
    entry: './source/test.index.ts',
    mode: 'production',
    module: {
        rules: [
            {
                test: /\.tsx?$/,
                use: 'ts-loader',                
                exclude: /node_modules/,
            },
            {
                test: /\.module.css$/,
                use: [
                    {
                        loader: "css-loader",
                        options: {
                            esModule: true,
                            // modules: {
                            //     namedExport: true, 
                            // },                            
                            modules: true, // Раз — и готово
                        },
                    },
                ],
            },
            {
                test: /\.(tsx|jsx|ts|js)?$/,
                use: "babel-loader",
                exclude: /node_modules/,
            }            
        ],
    },
    resolve: {
        extensions: ['.tsx', '.ts', '.js', '.jsx', '', '.*'],
        alias: {
            'react/hooks': 'preact/hooks',
            'react': 'preact/compat',
            'react-dom': 'preact/compat',
        },        
    },    
    output: {
        path: path.resolve(__dirname, 'dist\\webpack'),
        filename: 'webpack.bundle.js',
    },    
};

module.exports = config;

tsconfig.json:

Also in the root

{
    "compilerOptions": {
        "target": "ES5",
        "outDir": "./release/built",
        "jsx": "react-jsx",
        "rootDir": "./",
        // "jsx": "preserve",
        "jsxImportSource": "preact",
        // "jsxFactory": "React.createElement",
        "allowJs": true,
        "strict": false,
        // "allowImportingTsExtensions": true,
        "esModuleInterop": true,        
        "moduleResolution": "Node",
        "module": "ES2020",
        "plugins": [
            {
                "name": "typescript-plugin-css-modules",
                "options": {
                    "classnameTransform": "dashes",
                    "customMatcher": "\\.module\\.css$",
                    // "customRenderer": "./myRenderer.js",
                    "dotenvOptions": {},
                    "postcssOptions": {},
                    "rendererOptions": {}
                }               
            }
        ],
        "skipLibCheck": true,
        "baseUrl": "./",        
        "paths": {
            "react": [
                "./node_modules/preact/compat/"
            ],
            "react/jsx-runtime": [
                "./node_modules/preact/jsx-runtime"
            ],
            "react-dom": [
                "./node_modules/preact/compat/"
            ],
            "react-dom/*": [
                "./node_modules/preact/compat/*"
            ]
        }       
    },
    "include": [
        // "./source/**/*",
        "./source/test.index.ts"
    ],
}

And to simplify example I have just one source code file test.index.ts lacated to source directory (source/test.index.ts) with following content:

let r: string = '44'
console.log(r)

And with these configurations I faces a following trouble:

SyntaxError: Missing semicolon. (1:5)

enter image description here

As I little read before, the trouble often raises because of incorrect include/exclude options. But even knowing this, I can't imagine what might be wrong in my case


Solution

  • It's important to understand that Webpack Loaders are ordered, and run in bottom-to-top order. ts-loader, while placed first, actually runs last, hence the error being thrown by babel-loader (as it's the first to run).

    webpack's docs on ordering.


    On an unrelated note, there is no such thing as react/hooks, so you can remove that alias. It does nothing.