Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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)

like image 770
twinlakes Avatar asked Sep 24 '18 16:09

twinlakes


People also ask

Can browsers compile TypeScript?

Because browsers and Node. js process only JavaScript, you have to compile your TypeScript code before running or debugging it. Compilation can also produce source maps that set correspondence between your TypeScript code and the JavaScript code that is actually executed.


2 Answers

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']
    },
};
like image 78
twinlakes Avatar answered Nov 11 '22 23:11

twinlakes


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.
like image 21
Matt McCutchen Avatar answered Nov 12 '22 00:11

Matt McCutchen