webpack - Server- och klientsides TypeScript-projektorganisation, kompilering


Hur kan jag kompilera mitt TypeScript-projekt vad

  • Dela kod mellan server och klient
  • Använder TypeScript

Jag kunde inte få webpack att fungera, webbplatsen visar bara en mycket grundläggande komma igång. Jag försökte med gulp, men det var mycket för komplicerat och den inkrementella kompileringen tog väldigt lång tid (mycket längre än vad den borde behöva).

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]

Hur kan jag göra det? Vad ska jag använda?

REDIGERA:

Med gulp använde jag gulp-typescript och tsify, men den inkrementella kompileringen tog mer än 5 sekunder, vilket var alldeles för mycket.

Svar #1

Jag använder npm-skript för att starta 3 "watch"-processer:

  • En som övervakar klientfilerna (webpack) och kompilerar dem sedan till en mapp som kallas public.

  • En som övervakar serverfilerna (tsc) och kompilerar dem sedan till en mapp som heter private

  • En som övervakar utdata-serverkoden (nodemon) och kör node.js-appen när den ändras.

Båda apparna kan importera filer från common och det borde fungera bra.

Min scripts-konfiguration i package.json ser ut som följer:

  "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",
  }

Vi har flera fristående appar inne i "client" och varje app använder en mapp. Så vi använder webpack för att skapa ett paket för varje app.

Min webpack-konfiguration ser ut som följer (Obs: det finns några plugins som du kanske inte behöver i denna konfiguration):

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
};

Jag använder följande versioner:

  "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"
  }

Uppdatering 1 (Lagt till 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"
    ]
}

Svar #2

har du försökt att sätta isolatedModules : true i din tsconfig? Läs mer här: http://weblogs.thinktecture.com/thomas/2016/05/tired-of-waiting-for-typescript-compilation.html

Relaterade artiklar