GLaDOS
GLaDOS

Reputation: 672

How to create a grunt task that compiles typescript and creates a map for JavaScript files

I'm new to Grunt, Typescript, and Webpack, and loaders; and trying to understand the documentation for these tools. Handily, the ts-loader references this tutorial http://www.jbrantly.com/typescript-and-webpack/, which has been helpful but not quite what I need.

Our project is using Typescript as well as JavasCript and JSX, and we have been using a grunt ts task to compile the typescript to javascript, including a sourcemap. The javascript is finally all compiled together and then compressed so that ultimately a min-file and a corresponding sourcemap file are produced. Unfortunately, the sourcemap never seems to include the typescript javascript in the final product. We know this because we can never see the typescript-created javascript source files from the production environment; only the regular javascript files.

We thought we could try to modify the existing webpack task in the grunt file so that it uses the ts-loader instead of the ts compiler to compile, and to minify and provide a map. I have hopes that the ts-loader will compile and produce the needed map.

The existing grunt task was

 webpack: {
        options: {
            entry: webpackEntry,
            output: {
                path: webpackDest,
                filename: 'our-react-min.js',
                library: ["LIB", "apps"],
                libraryTarget: "assign",
                pathInfo: true
            },
            externals: grunt.file.readJSON('our-ui/webpack-externals.json'),
            stats: {
                // Configure the console output
                colors: true,
                modules: false,
                reasons: true
            },
            progress: true
        },
        prod: {
            stats: {
                colors: false,
                modules: true,
                reasons: true
            },
            plugins: [
                new webpack.optimize.UglifyJsPlugin(),
                new webpack.optimize.OccurenceOrderPlugin(),
                new webpack.optimize.DedupePlugin()
            ]
        },
        dev: {
            debug: true,
            devtool: 'inline-source-map',
            cache: true
        }
    }, ...

And I've now turned it into this:

     webpack: {
        options: {
            entry: webpackEntry,
            output: {
                path: webpackDest,
                filename: 'our-react-min.js',
                library: ["LIB", "apps"],
                libraryTarget: "assign",
                pathInfo: true
            },
            resolve: {
                // Add `.ts` and `.tsx` as a resolvable extension.
                extensions: ['', '.webpack.js', '.web.js', '.ts', '.tsx', '.js']
            },
            module: {
                loaders: [
                    // all files with a `.ts` or `.tsx` extension will be handled by `ts-loader`
                    { test: /\.tsx?$/, loader: 'ts-loader' }
                ]
            },
            ts: {
                "compilerOptions": {
                    "target": "es5",
                    "sourceMap": true,
                    "jsx": "react",
                    "experimentalDecorators": true
                },
                "exclude": [
                    "node_modules"
                ]
            },
                           externals: grunt.file.readJSON('our-ui/webpack-externals.json'),
            stats: {
                // Configure the console output
                colors: true,
                modules: false,
                reasons: true
            },
            progress: true
        },
        prod: {
            stats: {
                colors: false,
                modules: true,
                reasons: true
            },
            plugins: [
                new webpack.optimize.UglifyJsPlugin(),
                new webpack.optimize.OccurenceOrderPlugin(),
                new webpack.optimize.DedupePlugin()
            ]
        },
        dev: {
            debug: true,
            devtool: 'inline-source-map',
            cache: true
        }
    }, ...

Our build calls grunt webpack:dev or grunt webpack:prod depending on the environment.

After this runs, all the JavaScript is minified together using the closure compiler; the commented reference pointing to the map file is then appended to the end of the one min file. The problem I'm trying to solve is the lack of a source map for production typescript-compiled java script. The source map is there for everything but the javascript that was created from typescript.

I have been testing by

  1. Running grunt webpack:prod on the command line, then looking for the min and map files in the right location (they are there; presumably containing the non-ts javascript)

  2. Deploying the war as in prod mode and looking for the expected JavaScript files from a browser dev tool with the source-map setting on.

I'm still not finding the source file in the browser.

Is this grunt task correct? Or is the problem elsewhere...?

Upvotes: 0

Views: 3951

Answers (2)

GLaDOS
GLaDOS

Reputation: 672

I have a partial answer. In the prod piece I was missing the source-map devtool. But, this source map that maps back to JavaScript files, not to the Typescript source files

    ...    },
    prod: {
        devtool: 'source-map',
        stats: {
....

Upvotes: 0

Vassilis Pits
Vassilis Pits

Reputation: 3848

I use grunt ts also but in my case to make everything work correctly I did this:

In my Gruntfile:

    ts: {
        default: {
            tsconfig: true,
        },
        options: {
            fast: 'never'
        }
    }

And in my tsconfig.json this:

{
  "compileOnSave": true,
  "compilerOptions": {
    "removeComments": true,
    "noImplicitAny" : false,
    "module": "commonjs",
    "target": "es5",
    "sourceMap": true,
    "outDir": "compiled",
    "watch": true
  },
  "exclude": [
    "node_modules"
  ]
}

In my case it works perfectly only if i set a tsconfig file.

Hope it will help you.

Ps: Those are my options on tsconfig you can set yours similar to your grunt ts options.

Upvotes: 4

Related Questions