Upgrade to Pro — share decks privately, control downloads, hide ads and more …

ASP.NET CoreやTypeScriptの力を借りてレガシー寄りの環境に立ち向かいたかった話

ASP.NET CoreやTypeScriptの力を借りてレガシー寄りの環境に立ち向かいたかった話

2019/07/20開催のわんくま同盟 大阪勉強会 #76 の資料です。

masanori_msl

July 20, 2019
Tweet

More Decks by masanori_msl

Other Decks in Programming

Transcript

  1. ASP.NET CoreやTypeScriptの
    力を借りて
    レガシー寄りの環境に
    立ち向かいたかった話
    2019/07/20 @わんくま同盟 大阪勉強会 #76 by masanori_msl

    View full-size slide

  2. About me
     Name:Masui Masanori
     Work:Unity中心でしたが最近はWeb寄り
     Twitter:https://twitter.com/masanori_msl
     Blog:http://mslgt.hatenablog.com/

    View full-size slide

  3. なんか社内で使うための
    システム作ることになりました。
    あらすじ

    View full-size slide


  4. 割とレガシーな環境

    別のサービスが動いていたりする(あまり新規でインストールしづらい)

    開発環境へは比較的自由にインストールできる( ASP.NET Core や Node.js など)

    社内システムにアクセスするためのライブラリ(dll)がある
    前提(環境)

    View full-size slide


  5. 基本的にぼっち開発。

    特にフロントエンドの経験は少ない。

    レガシーな環境で動かすとはいえ、できるだけモダンな言語やフレームワークを
    使いたい(そして助けてほしい)。
    前提(開発者)

    View full-size slide


  6. Visual Studio Code
    (サーバー・クライアントサイド両方を開発する上で一番使いやすかった)

    PgAdmin 4 (DB Access)

    Node.js、npm、tsc、etc.
    開発ツール

    View full-size slide

  7. サーバーサイド( ASP.NET Core など)でのあれこれ

    クライアントサイド( TypeScript など)でのあれこれ
    お話の流れ

    View full-size slide

  8. サーバーサイドでのあれこれ

    View full-size slide


  9. ASP.NET Core を使う(所属メンバー的に .NET の開発経験がある人が多いため)。

    ただし社内ライブラリを使うところは ASP.NET Frameworkで。
    技術選定(サーバーサイド)

    View full-size slide

  10. 技術選定(サーバーサイド)
    IIS
    Access URL rewrite
    ASP.NET Core
    ASP.NET Framework
    http://localhost:XXXX

    View full-size slide

  11. 開発(サーバーサイド)
    実際の開発については下記から推測してください。
    https://mslgt.hatenablog.com/archive/category/ASP.NET%20Core
    https://mslgt.hatenablog.com/archive/category/Entity%20Framework%20Core

    View full-size slide

  12. 開発(サーバーサイド)
    今回は開発環境に .NET Core が
    インストールされていなくても
    何とかする方法についてだけ。

    View full-size slide

  13. 開発(サーバーサイド)
    発行時に必要なファイル( .NET Core 含む)を一緒に出力することで、
    実行環境に .NET Core がインストールされてなくても実行可能に。
    (Self-contained .NET Core Applications)
    必要なことは① .csproj ファイルへの RuntimeIdentifier 追加と
    ② publish コマンドへのオプション追加。

    View full-size slide

  14. 開発(サーバーサイド)


    netcoreapp2.2
    InProcess
    win-x86






    ① .csproj ファイルへの RuntimeIdentifier 追加

    View full-size slide

  15. 開発(サーバーサイド)
    ② publish コマンドへのオプション追加
    dotnet publish -c Release -r win-x86

    View full-size slide

  16. 開発(サーバーサイド)
    参照
    .NET Core application deployment – .NET Core – Microsoft Docs
    https://docs.microsoft.com/en-us/dotnet/core/deploying/
    How to create a self contained .Net core application?
    https://dotnetthoughts.net/how-to-create-a-self-contained-dotnet-core-application/

    View full-size slide

  17. 開発(サーバーサイド)
    課題
    プロジェクトフォルダー > bin > Release > netcoreapp2.2 > win-x86 > publish に
    発行したファイルが出力される。

    View full-size slide

  18. 開発(サーバーサイド)
    課題
    不要
    これが欲しい

    View full-size slide

  19. あ、Entity Framework Core は PostgreSQL が少々古くても
    問題なくアクセスしてくれてました。よ。
    ※ PgAdmin 4 が IE で動かないっぽいので注意
    開発(サーバーサイド)

    View full-size slide

  20. クライアントサイドでのあれこれ

    View full-size slide


  21. HTML5

    Razor

    TypeScript

    PostCSS

    webpack

    Polyfillあれこれ
    技術選定(クライアントサイド)
    主に使ったもの

    View full-size slide

  22. TypeScript 選択の理由

    やっぱり(静的な)型が欲しい。
    (実際には「静的な」型ではなく「強い」型)

    いざとなったら JavaScript に変換してしまうことだってできる。

    View full-size slide

  23. JavaScript の Framework は?
    Angular 、 React 、 Vue(ABC 順) どれも人気があるが、
    下記の点が気になって今回は選択せず。

    基本的に Node.js を使って動作するため、実行環境にも Node.js が必要。

    半年でメジャーバージョンアップデートする Angular をはじめ(LTSはあるが)、
    更新が速い。(ASP.NET Coreについては目をつぶる方針で。。。)

    自分をはじめ、メンバーの中で開発経験が少ない。

    View full-size slide

  24. PostCSS 選択の理由

    Autoprefixer (CSS のベンダープレフィックスを自動でつけてくれる)が
    使いたかった。

    @import も便利(※)。

    CSS 変数も便利(※)。
    ※PostCSSの機能ではないが、コンパイル時1つのファイルにまとめてくれるため、
    ブラウザ間の対応の違いなどを気にせず使えた。

    View full-size slide

  25. webpack 選択の理由

    きっかけは Pikaday(https://pikaday.com/ シンプルなデートピッカー。
    IE7から対応しているらしい) を使うのに、 import / export が必要になったため。

    TypeScript -> ES3 の JavaScript に変換、というのは tsc で可能だが、
    import / export は別途ツールが必要。

    View full-size slide

  26. Razor を使う

    View full-size slide

  27. Razorを使う

    DB からデータを取得する、かつ同期的にデータを更新する要素で使用。

    head など各画面共通要素をひとまとめにできるの便利。

    静的な HTML ファイルと比較して、サーバーサイドの Controller で
    ルーティングしやすいの便利。

    View full-size slide

  28. Razorを使う

    TypeScript( JavaScript )にデータが渡しづらい。
    (ViewData などは Razor でしか扱えないため、 HTML から TypeScript に
    データを渡す処理を別途書く必要がある)

    複数人で開発する時に、クライアントサイドを分割しづらい。
    課題

    View full-size slide

  29. Razorを使う
    この課題については良いバランスを見つけたいところ。
    (その前に Blazor が来るかもしれない)

    View full-size slide

  30. TypeScript を使う

    View full-size slide

  31. TypeScript を使う

    TypeScript

    tsc (コンパイラ)

    InversifyJS (Dependency Injection)

    reflect-metadata (InversifyJS で使用)

    pikaday (デートピッカー)

    moment (日付を良い感じに扱えるようにする)

    jest (テストツール)
    主に使ったもの

    View full-size slide

  32. TypeScript でハマったところ

    View full-size slide

  33. TypeScript でハマったところ
    主に TypeScript が「静的に」型を持つのではない、ということと、
    最終的に JavaScript に変換される、という点に起因して、
    C# 脳のまま書いていると失敗した、というお話。

    View full-size slide

  34. TypeScript でハマったところ
    export function doSomething(){
    let numbers = [10, 5, 3, 44, 1];
    for(let n of numbers.sort()){
    console.log(n);
    }
    }
    Sort
    結果は 1 -> 10 -> 3 -> 44 -> 5 となる。
    これは引数無しで sort() を実行すると辞書順でソートされる、という JavaScript の
    挙動がそのまま反映されるため。

    View full-size slide

  35. TypeScript でハマったところ
    export function doSomething(){
    let numbers = [10, 5, 3, 44, 1];
    for(let n of numbers.sort((a, b) => a - b)){
    console.log(n);
    }
    }
    数値順でソートするには引数を指定する。

    View full-size slide

  36. TypeScript でハマったところ
    型が保持されない場合がある
    特に型が入れ子構造になっている場合に、クラス間でのデータ受け渡しや
    JSON.parse() による変換を行うと、子の型が保持されず undefined になってしまう、
    といった現象が。。。

    View full-size slide

  37. TypeScript でハマったところ
    。。。と思ったのですが、この資料を作成するときに確認したら再現しませんでした
    (^o^)\
    ※TypeScript のバージョン違いや再現手順の間違いによるものかも。

    View full-size slide

  38. TypeScript でハマったところ
    型が保持されない問題が再現したら
    as Sample と明示的に子どもの型も指定した変数に格納した上で
    (または元のデータ取得時に型を指定して子のデータを入れ直す)使用すると、
    解決していた。

    View full-size slide

  39. TypeScript の好きなところ

    View full-size slide

  40. TypeScript の好きなところ
    強い型を持つ
    少なくとも自分の書くコードでは、その変数(プロパティ)の型が何を気にしなくても、
    間違っていればコンパイラが怒ってくれる。
    さらに Webpack を使って import / export が可能になったことで、
    1 クラス 1 ファイルに分ける、責務ごとに分割、といったことが容易に。

    View full-size slide

  41. TypeScript の好きなところ
    持ちうるデータの制限が容易
    下記の変数は 1, 2, 3 以外を入れようとするとエラーになる。
    let numbers: 1 | 2 | 3;
    numbers = 0; // ERROR
    numbers = 1; // OK

    View full-size slide

  42. TypeScript の好きなところ
    Non-Nullable
    Null になり得るかどうかが指定できる(ただし undefined にはなる)。
    かつ Kotlin でいう Smart cast のように扱われる。
    (Nullable であっても Null チェック後は Non-Nullable として扱われる)

    View full-size slide

  43. TypeScript の好きなところ
    Non-Nullable
    export class User{
    public name: string = “”; // Non-Nullable
    public nickname: string| null = null; // Nullable
    }
    export function doSomething(){
    let newUser = new User();
    newUser.name = null; // ERROR
    let nickname = newUser.nickname.toString(); // ERROR
    if(newUser.nickname !== null){
    let nickname2 = newUser.nickname.toString(); // OK
    }
    }

    View full-size slide

  44. TypeScript の好きなところ
    と言いつつ柔軟性もある
    例えばこんな interface を受け取る関数があるとして。
    export interface Option{
    option1?: string;
    option2?: number;
    }
    export function doSomething(option: Option){
    // あれこれする.
    }

    View full-size slide

  45. TypeScript の好きなところ
    と言いつつ柔軟性もある
    こんな風に引数を渡すことができる。
    doSomething({ option1: “Hello” }); // option2 は undefined

    View full-size slide

  46. 参照
    参照
    Matering TypeScript 3
    https://subscription.packtpub.com/book/application_development/9781789536706
    実践 TypeScript
    https://book.mynavi.jp/ec/products/detail/id=104703
    Interfaces - TypeScript
    http://www.typescriptlang.org/docs/handbook/interfaces.html

    View full-size slide

  47. IE 11 に立ち向かう

    View full-size slide

  48. 一番辛かったところ

    View full-size slide

  49. エラーがでない(場合がある)

    View full-size slide

  50. IEでエラーがでない
    Promise を使ったコードを IE11 で実行すると、 Promise が見つからない、といった
    エラーが発生する。
    しかし、 Array.prototype.find() を使うと、エラーが表示されず、
    かつ処理がそこで止まってしまうため問題を発見しづらい。

    View full-size slide

  51. 解決方法
    IEでエラーがでない

    View full-size slide

  52. 他のブラウザと組み合わせて頑張る
    IEでエラーがでない

    View full-size slide

  53. Polyfill
    先ほどの Promise 、 Array.prototype.find() が IE 対応の必要があるからといって
    使えないのはツラい。
    ということで Polyfill 先生の力を借りることに。

    View full-size slide

  54. Polyfill

    Promise: https://www.promisejs.org/

    fetch: https://github.com/github/fetch

    Array.prototype.find() :
    https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/find

    Array.prototype.findIndex() :
    https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/findIndex

    url-search-params-polyfill: https://github.com/jerrybendy/url-search-params-polyfill
    fetch と ur—search-params-polyfill は npm install 、他はファイルを用意して
    _Layout.cshtml で読み込みました。

    View full-size slide

  55. Polyfill
    注意点として、import 漏れがあっても IE で実行しないと気付かない、
    というのがあります。
    定期的に IE でも確認しましょう(白目)

    View full-size slide

  56. 文字化け

    View full-size slide

  57. 日本語データの文字化け
    URL のパラメータに日本語を渡すと、 IE のみ文字化けする現象が。。。
    encodeURIComponent(文字列) で事なきをえました。
    https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent

    View full-size slide

  58. PostCSS を使う

    View full-size slide

  59. PostCSS を使う
    PostCSS は JavaScript のプラグインによって CSS をあれこれ変換してくれるツール。
    具体的にはベンダープレフィックスを追加してくれる Autoprefixer など。
    (というか Autoprefixer が使いたいがために導入した)
    https://postcss.org/

    View full-size slide

  60. PostCSS を使う

    PostCSS

    postcss-cli

    precss

    autoprefixer
    インストールしたもの

    View full-size slide

  61. PostCSS を使う
    設定ファイル
    module.exports = {
    plugins: [
    require("autoprefixer")({
    "grid": true
    }),
    require("precss")
    ]
    }
    postcss.config.js というファイルを作り(多分ファイル名は何でも良さそう)、
    有効にするプラグイン、 ( Autoprefixer の場合) 有効にする CSS の種類
    ( CSS grid など)を指定する。

    View full-size slide

  62. PostCSS を使う
    設定ファイル
    {
    ~省略~
    "browserslist": [
    "last 2 version",
    "> 1%",
    "maintained node versions",
    "not dead"
    ],
    ~省略~
    }
    対応するブラウザバージョンは、以前 postcss.config.js に書いていたが、
    現在は package.json に書くよう変更されている。

    View full-size slide

  63. PostCSS を使う
    課題
    正直設定ファイルの書き方よくわかりません (^o^)\
    (grid の場合は postcss.config.js で true にすると有効になるが、
    flexbox は browserlist を指定する必要があるとか)

    View full-size slide

  64. PostCSS を使う
    ともあれコンパイル
    npx postcss 変換前の PostCSSファイルパス -c postcss.config.js
    -d 出力先のディレクトリパス
    ※出力先ディレクトリパスに元のファイル名でコンパイル済みの CSS が出力される。
    ※ オプションとして -w をつけると、 CSS ファイルを監視して変更のたびに自動コンパイルしてくれる。

    View full-size slide

  65. PostCSS を使う
    package.json の script に追加する
    ~省略~
    "scripts": {
    “css”: “npx postcss 変換前の PostCSSファイルパス -c postcss.config.js
    -d 出力先のディレクトリパス -w"
    }
    }
    npm run css を実行するとコンパイルを実行してくれる。
    webpack も同じことができるが、両方いっぺんに監視する、というのは難しそう。

    View full-size slide

  66. PostCSS の良いところ

    View full-size slide

  67. PostCSS の良いところ

    何といっても Autoprefixer が便利!

    @import や CSS 変数などもコンパイル時に解決してくれるので、
    IE でも心配せずに使える。

    プラグインが豊富なので、Autoprefixer 以外もあれこれ試すと良さそう。

    View full-size slide

  68. その他あれこれ
    その他七転八倒の様子はこの辺で。
    https://mslgt.hatenablog.com/archive/category/TypeScript
    https://mslgt.hatenablog.com/archive/category/CSS

    View full-size slide

  69. その他の課題

    View full-size slide

  70. Powershell開きまくり
    Webpack .NET Core
    PostCSS Git

    View full-size slide

  71. JavaScript Frameworkは使うべきか
    スキル問題は置いておくとして、結局 Framework を使わなかったとしても、
    オレオレ Framework になってしまう。
    であれば、ある程度スタンダードになっている Framework の流儀に沿って
    作る方がメンテもしやすい?
    ただし更新速度にどう追従するかの問題はある。

    View full-size slide

  72. おわりに
    手探りながらもなんとか形にできたのは、公式や MDN をはじめ、
    インターネット上にたくさんの知識が共有されていたから。
    (特に「新しめの機能 + IE」でググるとほぼ確実にヒットするあたり、
    先人の苦労を感じる)
    JavaScript Framework をはじめ、今後もあれこれ試しつつ自分も
    情報共有していきたい。

    View full-size slide

  73. License
     Google Noto Fonts
    http://www.google.com/get/noto/
    Copyright(c) Google Inc
    SIL Open Font License (https://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=OFL )

    View full-size slide