ASP.NET CoreでTypeScriptとwebpack

Visual Studio 2017でASP.NET Core + TypeScript + webpackを試せる環境を作るまでのメモです。

まずは試した環境から。

いつものようにASP.NET Coreの空のテンプレートから始めたいと思います。

プロジェクトを作成する

ASP.NET Core Web アプリケーションのプロジェクトを選択してプロジェクトを作ります。

Startupクラスを設定する

Razor Pagesと静的ファイルを扱うために、Startupクラスを次のように修正します。

public class Startup {
    // 使用するサービスを設定
    public void ConfigureServices(IServiceCollection services) {
        // MVCを追加
        services.AddMvc();
    }

    // ミドルウェアを設定
    public void Configure(IApplicationBuilder app, IHostingEnvironment env) {
        if (env.IsDevelopment()) {
            app.UseDeveloperExceptionPage();
        }

        // MVC(Razor Pages)を使う
        app.UseMvc();

        // 静的なファイルを使う
        app.UseStaticFiles();
    }
}

TypeScriptを実行するcshtmlを準備する

TypeScriptを実行するcshtmlを作りましょう。プロジェクトの直下にPagesフォルダを作って、その中にIndex.cshtmlを作ります。

Pages/
   └─ Index.cshtml

Index.cshtmlではこれから作るJavaScriptを指定します。指定している~/js/bundle.jsを、このあとwebpackで出力するようにしていきたいと思います。

@page
@model WebApp.Pages.IndexModel
@{
    Layout = null;
}
<!DOCTYPE html>
<html>
<head>
   <meta name="viewport" content="width=device-width" />
   <title>Index</title>
</head>
<body>
    <h1>Hello!</h1>
    @* これから作るjsファイルを指定しておく *@
    <script src="~/js/bundle.js"></script>
</body>
</html>

まだJavaScriptは作っていませんが、これでデバッグ実行できるようになりました。実行してあいさつをすませておきましょう。

ちなみにここまでは以前の記事とほぼ同じです・・・。

実行するTypeScriptファイルを準備する

プロジェクト直下にScriptsフォルダを作って、その中にapp.ts、lib.tsを作ります。

Scripts/
   ├─ app.ts
   └─ lib.ts

app.tsでは、lib.tsでエクスポートしたクラスをインポートするようにしています。

// lib.ts
// あいさつ文を作るクラスをエクスポート
export class Greeter {
    public static greet(message): string {
        return `Hello, ${message}!`;
    }
}

// app.ts
// lib.tsのGreeterクラスをインポート
import { Greeter } from "lib";

// あいさつする
alert(Greeter.greet("world"));

モジュールというやつですね。TypeScriptでは問題ないのですが、JavaScriptでモジュールのインポートをどうすればいいのかわからず苦労しました。今回はwebpackを使いましたが、他にもいい方法があるような気も。

TypeScriptのモジュールの説明はこちら。

TypeScriptの構成ファイルを準備する

TypeScript JSON 構成ファイル(tsconfig.json)を作ります。

{
    "compileOnSave": true,
    "compilerOptions": {
        "noImplicitAny": false,
        "noEmitOnError": true,
        "removeComments": false,
        "sourceMap": true,
        "target": "es5",
        "module": "es2015"
    },
    "exclude": [
        "node_modules",
        "wwwroot"
    ]
}

npmでwebpackをインストールする

npmでwebpackとtypescript、ts-loaderをインストールします。typescriptとts-loaderは、webpackがTypeScriptを処理するために必要なものです。具体的にはnpm 構成ファイル(package.json)を次のようにします。

{
    "version": "1.0.0",
    "name": "asp.net",
    "private": true,
    "devDependencies": {
        "webpack": "3.10.0",
        "typescript": "2.6.2",
        "ts-loader": "3.2.0"
    }
}

webpackの構成ファイルを準備する

プロジェクト直下にwebpack.config.jsを作ります。Scriptsフォルダにあるapp.tsとインポートしているib.tsをまとめて、wwwroot/js/bundle.jsを作成するように指定します。

const path = require("path");

const config = {
    devtool: "inline-source-map",
    // webpackがバンドルの構築を開始するエントリポイント
    entry: path.resolve(__dirname, "scripts/app.ts"),
    output: {
        // 出力するファイル名
        filename: "bundle.js",
        // 出力フォルダ
        path: path.resolve(__dirname, "wwwroot/js")
    },
    module: {
        rules: [
            // TypeScriptを処理するローダー
            { test: /\.ts$/, loader: "ts-loader" }
        ]
    },
    resolve: {
        extensions: [".ts", ".js"],
        // モジュールを探すフォルダ(node_modulesとscriptsフォルダを対象にする)
        modules: [
            "node_modules",
            path.resolve(__dirname, "scripts")
        ]
    }
};

module.exports = config;

webpackやTypeScriptのドキュメントを参考にしながら手探りで書きました。

WebPack Task Runnerをインストールする

Visual StudioにWebPack Task Runnerをインストールしておきます。インストールすると、タスク ランナー エクスプローラでwebpackを実行できるようになります。

webpackでバンドルする

タスク ランナー エクスプローラにあるRun - DevelopmentWatch Developmentをダブルクリックしてwebpackを実行すると、wwwroot/jsフォルダにbundle.jsファイルが作成されます。

デバッグ実行してアラートであいさつができれば今回の目標クリアです。