ASP.NET Core + angular2でやってみよう（その１）

ASP.NET core + angular2アプリケーションを作成する（その1）

[作業リポジトリはこちら](https://github.com/shwld/dotnetcore_angular2)

## 出来上がるもの
- ASP.NET core MVC
- Entity Framework core
- Angular2
- Bootstrap4
- fontawesome
- Webpack
- Typescript
- Sass

今回はViual Studio 2015 Update3でやります。
多少手順は違うが、Macとかでも行けるはず。

## まずはASP.NET Core MVC環境を準備

WebApiプロジェクトにしました

![1468332917162.png](https://qiita-image-store.s3.amazonaws.com/0/51402/677ff618-feab-ed2f-7c24-379cd462107e.png)

### angular2も同じサーバで動かすため、staticファイルを有効にする

dependenciesに追加

``` project.json
"Microsoft.AspNetCore.StaticFiles": "1.0.0"
```

Startup.csのConfigureに追加

```
        public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
        {
            ..

            app.UseStaticFiles();

            ..
        }
```

### angularを実行するためのViewを作る

``` Views/_ViewStart.cshtml
@{
    Layout = "_Layout";
}
```

``` Views/Shared/_Layout.cshtml
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>@ViewBag.Title</title>
    <link rel="stylesheet" href="~/dist/vendor-style.css" />
    <link rel="stylesheet" href="~/dist/app-style.css" />
</head>
<body>
    @RenderBody()

    <script src="~/dist/vendor.bundle.js"></script>
    <script src="~/dist/app.bundle.js"></script>
</body>
</html>
```

``` Views/Home/Index.cshtml
@{
    ViewData["Title"] = "Lanos CRM";
}

<div class="container">
    <my-app class="container">Loading...</my-app>
</div>
```

### コントローラーも作る

``` Controllers/HomeController.cs
using Microsoft.AspNetCore.Mvc;

namespace core_angular2.Controllers
{
    public class HomeController : Controller
    {
    	[Route("")]
        public IActionResult Index()
        {
            return View();
        }
    }
}
```

### Properties/launchSettingsで初期表示するパスを修正する

空白にする

```
"launchUrl": "",
```

ここまでやって実行すると`Loading...`ってのが出ればOK

## Angular2とか必要なものたちを入れる

``` package.json
{
  "name": "core_angular2",
  "version": "1.0.0",
  "scripts": {
    "postinstall": "typings install",
    "tsc": "tsc",
    "tsc:w": "tsc -w",
    "typings": "typings",
    "webpack":  "webpack"
  },
  "license": "ISC",
  "dependencies": {
    "@angular/common": "2.0.0-rc.3",
    "@angular/compiler": "2.0.0-rc.3",
    "@angular/core": "2.0.0-rc.3",
    "@angular/forms": "0.1.1",
    "@angular/http": "2.0.0-rc.3",
    "@angular/platform-browser": "2.0.0-rc.3",
    "@angular/platform-browser-dynamic": "2.0.0-rc.3",
    "@angular/router": "3.0.0-alpha.7",
    "@angular/router-deprecated": "2.0.0-rc.2",
    "@angular/upgrade": "2.0.0-rc.3",
    "angular2-in-memory-web-api": "0.0.12",
    "bootstrap": "^4.0.0-alpha.2",
    "core-js": "^2.4.0",
    "font-awesome": "^4.6.3",
    "jquery": ">=2.0.0 <3.0.0",
    "reflect-metadata": "^0.1.3",
    "rxjs": "5.0.0-beta.6",
    "tether": "^1.3.2",
    "zone.js": "^0.6.12"
  },
  "devDependencies": {
    "css-loader": "^0.23.1",
    "extract-text-webpack-plugin": "^1.0.1",
    "file-loader": "^0.9.0",
    "font-awesome-sass-loader": "^1.0.1",
    "gulp": "^3.9.1",
    "imports-loader": "^0.6.5",
    "node-sass": "^3.8.0",
    "sass-loader": "^4.0.0",
    "style-loader": "^0.13.1",
    "ts-loader": "^0.8.2",
    "typescript": "^1.8.10",
    "typings": "^1.0.4",
    "url-loader": "^0.5.7",
    "webpack": "^1.13.1",
    "webpack-merge": "^0.14.0",
    "webpack-stream": "^3.2.0"
  }
}
```

npm インストール!!

rootフォルダで `npm install` コマンドをたたく。

tscofigも作る

``` tsconfig.json
{
  "compilerOptions": {
    "target": "es5",
    "module": "commonjs",
    "moduleResolution": "node",
    "sourceMap": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "removeComments": false,
    "noImplicitAny": false
  }
}
```

typingsも作る

``` typings.json
{
  "globalDependencies": {
    "core-js": "registry:dt/core-js#0.0.0+20160602141332",
    "jasmine": "registry:dt/jasmine#2.2.0+20160621224255",
    "node": "registry:dt/node#6.0.0+20160621231320"
  }
}
```

### 依存モジュールをTypescriptにまとめる

``` Client/vendor.ts
import '../node_modules/core-js';
import '../node_modules/zone.js/dist/zone';

import "../node_modules/@angular/common";
import "../node_modules/@angular/compiler";
import "../node_modules/@angular/core";
import "../node_modules/@angular/forms";
import "../node_modules/@angular/http";
import "../node_modules/@angular/platform-browser";
import "../node_modules/@angular/platform-browser-dynamic";
import "../node_modules/@angular/router";

import "../node_modules/bootstrap/dist/js/bootstrap";

import '../node_modules/rxjs/Rx';
```

``` Client/vendor-style.ts
import '../node_modules/bootstrap/dist/css/bootstrap.css';
import '../node_modules/font-awesome/css/font-awesome.css';
require("font-awesome-sass-loader");
```

### 自分で定義したスタイルをまとめる

``` Client/app-style.ts
import './styles/sample.scss'; /* 適当なscssを作って試すといい */
```

### angular2のコードをまとめる

``` Client/app/app.ts
import { bootstrap }    from '@angular/platform-browser-dynamic';
import { AppComponent } from './app.component';
bootstrap(AppComponent);
```

``` Client/app/app.component.ts
import { Component } from '@angular/core';
@Component({
    selector: 'my-app',
    template: '<h1>My First Angular 2 App<span class="fa fa-flag"></span></h1>'
})
export class AppComponent { }
```

## webpackで必要なモジュールをまとめて利用する

``` webpack.config.js
var webpack = require('webpack');
var path = require('path');
var ExtractTextPlugin = require("extract-text-webpack-plugin");

// Webpack Config
var webpackConfig = {
    entry: {
        'app': './Client/app/app.ts',
        'vendor': './Client/vendor.ts',
        'app-style': './Client/app-style.ts',
        'vendor-style': './Client/vendor-style.ts',
    },

    devtool: 'source-map',

    cache: true,
    output: {
        path: './wwwroot/dist',
        filename: '[name].bundle.js',
        sourceMapFilename: '[name].map',
        chunkFilename: '[id].chunk.js'
    },

    resolve: {
        extensions: ['', '.ts', '.js']
    },

    plugins: [
      new webpack.ProvidePlugin({
          $: "jquery",
          jQuery: "jquery",
          "window.jQuery": "jquery"
      }),
      new webpack.ProvidePlugin({ "window.Tether": "tether" }),
      new webpack.optimize.CommonsChunkPlugin({ name: ['app', 'vendor', 'polyfills'], minChunks: Infinity }),
      new ExtractTextPlugin("[name].css"),
      new webpack.optimize.DedupePlugin()
    ],

    module: {
        loaders: [
          // .ts files for TypeScript
            { test: /\.ts$/, loader: 'ts-loader' },
            { test: /\.css$/, loader: ExtractTextPlugin.extract("style-loader", "css-loader") },
            { test: /\.scss$/,loader: ExtractTextPlugin.extract("style-loader", "css-loader!sass-loader") },
            { test: /\.sass$/,loader: ExtractTextPlugin.extract("style-loader", "css-loader!sass-loader") },
            { test: /\.less$/,loader: ExtractTextPlugin.extract("style-loader", "css-loader!less-loader") },
            { test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: "url-loader?limit=10000&mimetype=application/font-woff" },
            { test: /\.(ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: "file-loader" }
        ]
    }

};

var webpackMerge = require('webpack-merge');
module.exports = webpackMerge(webpackConfig);
```

## コンパイルして実行しよう

1.rootフォルダで `npm run webpack` を実行

2. Visual Studioでデバッグ実行すると `My First Angular 2 App` ってでるはず

でたら成功



### more
- VisualStudioの機能でビルド前後や起動時にnpmコマンドを挟み込んだりできので、webpackコマンドをどこかに入れると便利
- webpackのコンパイルが遅いのでwebpack-dev-serverを入れると便利

## 次

まだ、ASP.NETとangularが全く絡まないので、絡ませるところとか、EntityFrameworkのセットアップとか、認証周りとかを予定しています。

EFの設定もやりました

http://qiita.com/shwld/items/f4234043a40513b8b304


公式ドキュメントにはお世話になっています。

https://docs.asp.net/en/latest/

https://angular.io/docs/ts/latest/quickstart.html