twinlakes
twinlakes

Reputation: 10228

How to compile typescript for the browser

I have an existing project that I would like to add TypeScript and React support to. Because the project already exists, I can't use a scaffolding project and have been having trouble configuring tsconfig.json properly.

I have been having various issues depending on which settings I use, but generally I have errors from different code in /node_modules/** and often in /node_modules/@types/**. I've included my tsconfig.json with comments as to what errors each setting fixes.

How can I compile my TypeScript + React project without import/module issues?

Current relevant tsconfig.json settings

"module": "amd", // must be 'amd' or 'system' to use 'outFile'
"lib": ["es2015", "dom", "es5", "es6"], // must include some of these to suppress certain errors; adds the 'Set' type
"jsx": "react", // compile jsx to js
"sourceMap": true, // ensure debuggable
"outFile": "./static/js/app.js", // must be under /static/ to be served
"rootDir": "./static/ts",
"moduleResolution": "node", // suppresses issue with `default` or `export`
"esModuleInterop": true

Current Error

ReferenceError: define is not defined (In the browser)

Upvotes: 17

Views: 25469

Answers (2)

twinlakes
twinlakes

Reputation: 10228

I ended up using webpack (with the ts-loader module) instead of tsc as my static bundler.

The only change I had to make to my typescript was to change import React from "react"; to import * as React from "react".

tsconfig.json (abbr)

"target": "es5",
"module": "commonjs",
"lib": ["es5", "es6", "dom"],
"allowJs": true,
"jsx": "react",
"sourceMap": true,
"rootDir": "./client",
"downlevelIteration": true,

webpack.config.js

const path = require('path');

module.exports = {
    context: path.resolve(__dirname, 'client'),
    devtool: 'inline-source-map',
    entry: './main.tsx',
    mode: 'development',
    module: {
        rules: [{
            test: /\.tsx?$/,
            use: 'ts-loader',
            exclude: /node_modules/
        }]
    },
    output: {
        filename: 'client.js',
        path: path.resolve(__dirname, 'static/js')
    },
    resolve: {
        extensions: ['.tsx', '.ts', '.jsx', '.js']
    },
};

Upvotes: 12

Matt McCutchen
Matt McCutchen

Reputation: 30879

If you're happy with a single file for now, then:

  1. If you haven't done so already, follow these instructions to add the React library to your page. (You can download the JavaScript files and host them on your server if you prefer)
  2. Delete the import statements from your file so that TypeScript doesn't treat it as a module, and just refer to the React and ReactDOM global variables that will be defined at runtime by the JavaScript files you added in step 1. The @types/react package will automatically declare these "UMD" global variables at compile time when your code is not a module.

Upvotes: 2

Related Questions