2
votes

I am creating a new react project (a very basic one) with TypeScript. I am using webpack to bundle my typescript files to javascript files. But while running webpack I am getting the following error:

ERROR in ./src/components/parent/home.tsx
Module parse failed: Unexpected token (9:2)
You may need an appropriate loader to handle this file type.
|
| render(
|   <Home />,
|   rootEl
| );

Below are the configurations I am using:

tsconfig.json -- I am using TypeScript 2.6.1

{
  "compilerOptions": {
    "target": "es5",
    "module": "commonjs",
    "jsx": "preserve",
    "sourceMap": true,
    "outDir": "dist",
    "strict": true,
    "noImplicitAny": true,
    "strictNullChecks": true,
    "moduleResolution": "node",
    "baseUrl": "./src/",
    "typeRoots": [
      "node_modules/@types"
    ],
    "allowSyntheticDefaultImports": true
  },
  "exclude" : [
    "node_modules"
  ],
  "include" : [
    "./src/"
  ]
}

webpack.config.js -- I am using webpack 3.8.1

const path = require('path');

module.exports = {
  entry: "./src/components/parent/home.tsx", 

  output: {
    path: path.resolve(__dirname, "dist/app"), 
    filename: "home.js"
  },

  module: {

    rules: [
      { 
        test: /\.(ts|tsx)$/, 
        include: path.join(__dirname, "src"), 
        use: ["babel-loader", "awesome-typescript-loader"] 
      }
    ]
  },

  resolve: {

    modules: [
      "node_modules",
      path.resolve(__dirname, "src")
    ],

    extensions: [".ts", ".tsx", ".js", ".jsx", ".json"]

  },

  node: {
      fs: 'empty',
      net: 'empty',
      tls: 'empty'
  },

  devtool: "source-map"
}

home.tsx

import * as React from 'react';
import { render } from 'react-dom';

import Home from '../children/homeContent';

const rootEl = document.getElementById('app');

render(
  <Home />, 
  rootEl
);

homeContent.tsx

import React from 'react';

export default class homeContent extends React.Component<any, any> {

    public render() {
        return (
            <div>
                Hello I am home Page!!
            </div>
        );
    }
}

.babelrc

{
    "presets": ["env", "react"]
}

What am I doing wrong?

Update:

I am getting the below error in my home.tsx on the <Home /> line as well.

[ts]
Argument of type 'Element' is not assignable to parameter of type 'ReactElement<any>'.
  Types of property 'type' are incompatible.
    Type 'string | ComponentClass<any> | StatelessComponent<any>' is not assignable to type 'string | StatelessComponent<any> | ComponentClass<any>'.
      Type 'ComponentClass<any>' is not assignable to type 'string | StatelessComponent<any> | ComponentClass<any>'.
        Type 'React.ComponentClass<any>' is not assignable to type 'React.ComponentClass<any>'. Two different types with this name exist, but they are unrelated.
          Type 'React.Component<any, React.ComponentState>' is not assignable to type 'React.Component<any, React.ComponentState>'. Two different types with this name exist, but they are unrelated.
            Types of property 'render' are incompatible.
              Type '() => string | number | false | Element | ReactPortal | Element[] | null' is not assignable to type '() => false | Element | null'.
                Type 'string | number | false | Element | ReactPortal | Element[] | null' is not assignable to type 'false | Element | null'.
                  Type 'string' is not assignable to type 'false | Element | null'.
import Home
1
Why do you need babel-loader if you can compile your code (even jsx) with Typescript? - felixmosh
@felixmosh I have tried individually with "babel-loader" and "awesome-typescript-loader" as well and still I am facing the same issue. - Mayank Tripathi
use only the awesome-typescript-loader and change the jsx in your tsconfig file to "jsx": "react", - felixmosh
@felixmosh That also didn't work. I noticed that I am getting this weird error in my home.tsx file which I have updated in the question. - Mayank Tripathi

1 Answers

1
votes

So I tried a couple of things and finally tried to do everything from scratch and got it working. Below are the configurations I used.

tsconfig.json

{
    "compilerOptions": {
        "outDir": "./dist/",
        "sourceMap": true,
        "noImplicitAny": true,
        "module": "commonjs",
        "target": "es5",
        "jsx": "react"
    },
    "include": [
        "./src/**/*"
    ]
}

webpack.config.js

module.exports = {
    entry: "./src/index.tsx",
    output: {
        filename: "home.js",
        path: __dirname + "/dist/app/"
    },

    devtool: "source-map",

    resolve: {
        extensions: [".ts", ".tsx", ".js", ".json"]
    },

    module: {
        rules: [
            { test: /\.tsx?$/, loader: "awesome-typescript-loader" },
            { enforce: "pre", test: /\.js$/, loader: "source-map-loader" }
        ]
    },

    watch: true
};

index.tsx

import * as React from "react";
import * as ReactDOM from "react-dom";

import { Hello } from "./components/Hello";

ReactDOM.render(
    <Hello />,
    document.getElementById("example")
);

Hello.tsx

import * as React from "react";

export class Hello extends React.Component {
    render() {
        return <h1>Hello this is home page!</h1>;
    }
}