Tamás
Tamás

Reputation: 1112

Server & client-side TypeScript project organization, compilation

How can I compile my TypeScript project what

I couldn't get webpack working, the website just shows a very basic getting started. I tried gulp, but it was far too complex and the incremental compilation took a very long time (way more than it should need).

src/
    common/
        data.ts
        [other files that are needed on both client and server-side]
    server/
        server.ts
        search.ts
    client/
        sw.ts
        resources/
             [other static resources like index.html]
[configuration files like package.json]

How can I do it? What should I use?

EDIT:

With gulp, I used gulp-typescript and tsify but the incremental compilation took more than 5 seconds, which was way too much.

Upvotes: 3

Views: 3712

Answers (2)

Remo H. Jansen
Remo H. Jansen

Reputation: 24941

I use npm scripts to start 3 "watch" processes:

  • One that watches the client files (webpack) and compiles then into a folder called public.

  • One that watches the server files (tsc) and compiles then into a folder called private

  • One that watches the output server code (nodemon) and runs the node.js app when it changes.

Both apps can import files from common ans it should work fine.

My scripts config in package.json looks as follows:

  "scripts": {
    "watch-all": "npm run watch-server & npm run watch-client & nodemon --inspect private/server.js",
    "watch-server": "tsc -p tsconfig.json -inlineSourceMap -outDir private --watch",
    "watch-client": "webpack --watch",
  }

We have multiple standalone apps inside "client" and each app uses a folder. So we use webpack to create one bundle for each app.

My webpack config looks as follows (Note: there are some plugins that you may not need in this config):

const { CheckerPlugin, TsConfigPathsPlugin } = require("awesome-typescript-loader");
const Visualizer = require("webpack-visualizer-plugin");
const webpack = require("webpack");
const CopyWebpackPlugin = require("copy-webpack-plugin");
const TypedocWebpackPlugin = require("typedoc-webpack-plugin");

const corePlugins = [
    new CheckerPlugin(),
    new webpack.DefinePlugin({
        "process.env.NODE_ENV": JSON.stringify(process.env.NODE_ENV || "development")
    }),
    new Visualizer({
        filename: "./debug/statistics.html"
    }),
    new CopyWebpackPlugin([
        // ...
    ])
];

const devPlugins = [
    new TypedocWebpackPlugin(
        {
            name: "ORG",
            out: "../private/docs",
            mode: "file",
            tsconfig: "./tsconfig.json"
        },
        "./src"
    )
];

const prodPlugins = [
    new webpack.optimize.UglifyJsPlugin()
];

const plugins = process.env.NODE_ENV === "production" ? corePlugins.concat(prodPlugins) : corePlugins.concat(devPlugins)

module.exports = {
    entry: {
        "app1/": "./src/client/app1/index.ts",
        "app2/": "./src/client/app2/index.ts",
        // ...
    },
    devServer: {
        inline: true
    },
    output: {
        filename: "[name]bundle.js",
        path: __dirname + "/public",
        publicPath: "/public"
    },
    devtool: "source-map",
    resolve: {
        extensions: [".webpack.js", ".web.js", ".ts", ".tsx", ".js"],
        plugins: [
            new TsConfigPathsPlugin({ configFileName: "tsconfig.json" })
        ]
    },
    module: {
        rules: [
            {
                enforce: "pre",
                test: /\.js$/,
                loader: "source-map-loader",
                exclude: [ /node_modules/, /experimental/ ]
            },
            {
                enforce: "pre",
                test: /\.(ts|tsx)$/,
                loader: "tslint-loader",
                exclude: [ /node_modules/, /experimental/ ]
            },
            {
                test: /\.(ts|tsx)$/,
                loader: "awesome-typescript-loader",
                exclude: [ /node_modules/, /experimental/ ]
            },
            {
                test: /\.scss$/,
                use: [{
                    loader: "style-loader",
                    options: {
                        sourceMap: true
                    }
                }, {
                    loader: "css-loader",
                    options: {
                        sourceMap: true
                    }
                }, {
                    loader: "sass-loader",
                    options: {
                        sourceMap: true
                    }
                }]
            }
        ]
    },
    plugins: plugins
};

I'm using the following versions:

  "devDependencies": {
    "awesome-typescript-loader": "^3.0.0-beta.18",
    "chai": "^3.5.0",
    "copy-webpack-plugin": "^4.0.1",
    "css-loader": "^0.28.0",
    "html5-history-api": "^4.2.7",
    "mocha": "^3.2.0",
    "node-sass": "^4.5.2",
    "nodemon": "^1.11.0",
    "nyc": "^10.1.2",
    "phantomjs-prebuilt": "^2.1.14",
    "sass-loader": "^6.0.3",
    "sequelize-auto": "^0.4.25",
    "sinon": "^2.0.0-pre.5",
    "source-map-loader": "^0.2.1",
    "sourcemap-istanbul-instrumenter-loader": "^0.2.0",
    "style-loader": "^0.16.1",
    "supertest": "^3.0.0",
    "tmp": "0.0.31",
    "ts-node": "^3.0.2",
    "tslib": "^1.6.0",
    "tslint": "^5.1.0",
    "tslint-loader": "^3.5.2",
    "typedoc": "^0.5.10",
    "typedoc-webpack-plugin": "^1.1.4",
    "typescript": "^2.2.2",
    "webpack": "^2.3.3",
    "webpack-dev-server": "^2.4.2",
    "webpack-visualizer-plugin": "^0.1.10",
    "xlsx": "^0.9.10",
    "yargs": "^7.0.2"
  }

Update 1 (Added tsconfig.json)

{
    "compilerOptions": {
        "target": "es5",
        "lib": ["es6", "dom", "dom.iterable"],
        "downlevelIteration" : true,
        "module": "commonjs",
        "moduleResolution": "node",
        "jsx": "react",
        "experimentalDecorators": true,
        "emitDecoratorMetadata": true,
        "noImplicitAny": true,
        "preserveConstEnums": true,
        "suppressImplicitAnyIndexErrors": true,
        "strictNullChecks": true,
        "noImplicitReturns": false,
        "noImplicitThis": true,
        "baseUrl": "src",
    },
    "exclude": [
        "./node_modules"
    ]
}

Upvotes: 4

erosb
erosb

Reputation: 3141

have you tried setting isolatedModules : true in your tsconfig? Read more here: http://weblogs.thinktecture.com/thomas/2016/05/tired-of-waiting-for-typescript-compilation.html

Upvotes: 0

Related Questions