Search code examples
node.jstypescriptwebpackts-loader

Webpack output compiled typescript as (javascript) string


Does anyone know how to output compiled typescript as string which can be extracted using the Extract-Text-Webpack-Plugin?

Currently I use "ts-loader" to transform the TypeScript file into JavaScript file. However, the result is not as expected because the output JavaScript is integrated with the Js which will be executed by NodeJs.

The expected result is to compile the TypeScript content into a JavaScript string just like what Css loader does so I can use Extract-Text-WebPack-Plugin to render the compiled Javascript content into the output file (a bundled js file which will be used as a browser side javascript library).

Not sure which webpack plugin / loader is able to solve this problem?

webpack.config.js

var webpack = require("webpack");
var ExtractTextPlugin = require("extract-text-webpack-plugin");

var exCss = new ExtractTextPlugin('[name].bundle.css');
var exScss = new ExtractTextPlugin('[name].bundle.css');


module.exports = {
    entry: {
        entry:"./src/entry.js"
    },
    devtool: "source-map",
    output: {
        path: __dirname + "/bundle",
        publicPath: "/assets/",
        filename: "[name].bundle.js"
    },
    resolve: {
        // Add `.ts` and `.tsx` as a resolvable extension.
        extensions: ['', '.webpack.js', '.web.js', '.ts', '.tsx', '.js', '.jsx']
    },
    module: {
        loaders: [
            { test:/\.ts$/, loader: "ts-loader" },
            { test: /\.css$/, loader: exCss.extract(["css"]) }
        ]
    },
    plugins: [exScss, exCss]
};

tsconfig.json

    {
  "compilerOptions": {
    "target": "es5",
    "module": "commonjs",
    "moduleResolution": "node",
    "sourceMap": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "removeComments": true,
    "noImplicitAny": false
  },
  "exclude": [
    "node_modules",
    "typings"
  ]
}

TypeScript File: test.ts

class FirstType{
    firstProp: "ok";
}

let obj = new FirstType();
console.log(obj.firstProp);

Expected Result: test.bundle.js

"use strict";
var FirstType = (function () {
    function FirstType() {
        this.firstProp = "ok";
    }
    return FirstType;
}());
var obj = new FirstType();
console.log(obj.firstProp);

Unwanted Actual Result: test.bundle.js

/******/ (function(modules) { // webpackBootstrap

......

function(module, exports) {

    "use strict";
    var FirstType = (function () {
        function FirstType() {
            this.firstProp = "ok";
        }
        return FirstType;
    }());
    var obj = new FirstType();
    console.log(obj.firstProp);
}
]);

Solution

  • You can achieve that by using a customized loader.

    module.exports = function(source){
        var src = source;
        src = src.replace(/\\/ig, "\\\\");
        src = src.replace(/\'/ig, "\\'");
        src = src.replace(/\"/ig, "\\\"");
        src = src.replace(/\r/ig, "\\r");
        src = src.replace(/\n/ig, "\\n");
        return 'var content = "'+src+'";module.exports = content;';
    };