Init.js:フルスタックJavaScriptの理由と方法のガイド

公開: 2022-03-11

物語

それで、あなたとあなたの共同創設者は、ビジネスのためのこの素晴らしいアイデアを持っていますよね?

あなたはあなたの心の中に機能を追加してきました。

多くの場合、あなたは潜在的な顧客に彼らの意見を求めます、そして彼らは皆それを愛しています。

さて、人々はそれを望んでいます。 儲かるお金さえあります。 そして、彼らがそれを持てない唯一の理由は、あなたがまだそれを実装していないからです。

それで最後に、あなたはある日座って、「やろう!」と言います。 間もなく、アプリのビジネスロジック、つまり製品を前進させるキラー機能を実装する方法を理解しようとしています。それを実行する方法についてのアイデアがあり、実行できることがわかっています。

"終わり! できます!" あなたは言う。 概念実証は成功です! 残っているのは、それをWebアプリにパッケージ化することだけです。

「OK、サイトを作成しましょう」とあなたは言います。

そして、あなたは真実に気づきます。プログラミング言語を選択する必要があります。 (最新の)プラットフォームを選択する必要があります。 いくつかの(最新の)フレームワークを選択する必要があります。 ストレージ、データベース、およびホスティングプロバイダーを構成(および購入)する必要があります。 管理インターフェースが必要です。 許可システムが必要です。 コンテンツマネージャーが必要です。

あなたはスリムになりたい、アジャイルになりたい。 短期的および長期的に成功するのに役立つテクノロジーを使用したいと考えています。 そして、それらを見つけるのは必ずしも簡単ではありません。

何十ものアーキテクチャ上の決定を下す必要があります。 そして、適切なものを作りたいと考えています。迅速な開発、一定の反復、最大の効率、速度、堅牢性などを可能にするテクノロジーを使用したいと考えています。 あなたはスリムになりたい、アジャイルになりたい。 短期的および長期的に成功するのに役立つテクノロジーを使用したいと考えています。 そして、それらを見つけるのは必ずしも簡単ではありません。

「私は圧倒されています」とあなたは圧倒されていると感じながら言います。 あなたのエネルギーはかつてと同じではありません。 あなたは物事をつなぎ合わせようとしますが、それは大変な作業です。

あなたの概念実証はゆっくりと枯れて死んでいきます。

提案

このように自分でたくさんのアイデアを捨てた後、私は解決策を設計することにしました。 私はそれを「Init」プロジェクト(またはinit.js)と呼んでいます。

アイデアの核心は、それらすべてを開始する単一のプロジェクトを持ち、開発者または技術的創設者がこれらの重要な決定をすべて一度に行えるようにし、それらの決定に基づいて適切な開始テンプレートを受け取ることです。 私は、中傷者が「1つの解決策がすべての問題に適用できるわけではない」と言っていることを知っています(嫌いな人は嫌いです)。 そして、彼らは正しいかもしれません。 しかし、私たちはおおよその解決策を作成するために最善を尽くすことができ、Initはかなり近いと思います。

この目的を最もよく達成するには、いくつかの重要なアイデアを念頭に置く必要があります。 Initを開発するとき、私は次のことを考慮しました。

  • コンポーネント

    コンポーネント化は、さまざまなプロジェクト間でソフトウェアコンポーネントを再利用できるため、あらゆるシステムの重要な特徴です。これがInitの主な目的です。 ただし、コンポーネント化には副産物である「交換可能性」も付属しています。これは、「ほぼ」同じソリューションでいくつかの異なる問題を攻撃する上で最善の味方になります。

  • 開発のしやすさ

    いくつかの問題、どこかにBrainf*ckで最もよく書かれた解決策があります。 しかし、そのソリューションを(Brainfuckで)実装することは、読むことはもちろん、書くこともほぼ不可能です。 それはあなたに時間と途方もない量の努力を要します。 一般に、開発を容易にする言語とプラットフォームを使用する必要がありますが、自分(または後で作業する可能性のある人)にとっては難しくありません。

  • コミュニティ

    どのプラットフォームを選択する場合でも、大きなコミュニティがあり、最も一般的および一般的でない問題に役立つコミュニティがあることを確認してください。 覚えておいてください:jQueryは、最速、クリーン、または最もエレガントなライブラリではないかもしれませんが、そのコミュニティのおかげで勝者です。

これらの目標を念頭に置いて、次に、Initを作成する際に私がどのように自分で決定したかを示します。

Initは、その中核として、「フルスタックJavaScript」パラダイムを利用しています(一部の人々は、それまたはそのサブセットをMEANスタックと呼んでいます)。 このようなスタックを使用することで、Initは単一の言語を使用しながら、Webアプリを開発するための非常に柔軟で完全な機能を備えた環境を作成できます。 つまり、Initを使用すると、JavaScriptをクライアントとサーバーの開発だけでなく、ビルド、テスト、テンプレート作成などにも使用できます。

しかし、少し速度を落とし、自問してみましょう。JavaScriptを使用するのは本当に良い考えですか?

JavaScriptを選んだ理由

私は1998年からWeb開発者です。当時、サーバー側の開発のほとんどにPerlを使用していましたが、それ以降もクライアント側でJavaScriptを使用しています。 それ以来、Webサーバーテクノロジーは大きく変化しました。ほんの数例を挙げると、PHP、AP、JSP、.NET、Ruby、Pythonなどの言語やテクノロジーの波が次々と発生しました。 開発者は、クライアント環境とサーバー環境に2つの異なる言語を使用すると、事態が複雑になることに気付き始めました。 単一の言語で統合しようとした最初の試みは、サーバー上にクライアントコンポーネントを作成し、それらをJavaScriptにコンパイルしようとしました。 これは期待どおりに機能せず、それらのプロジェクトのほとんどは失敗しました(たとえば、ASPMVCがASP.NETWebフォームに置き換わり、GWTが近い将来Polymerに置き換わる可能性があります)。 しかし、それは本質的に素晴らしいアイデアでした。クライアントとサーバー上の単一の言語により、コンポーネントとリソースを再利用できるようになりました(これはキーワード: resourcesです)。

答えは簡単でした。JavaScriptをサーバーに配置します。

JavaScriptは実際にはNetscapeEnterpriseServerのJavaScriptServerSideで生まれましたが、その言語は当時準備ができていませんでした。 何年にもわたる試行錯誤の末、JavaScriptをサーバーに配置するだけでなく、ノンブロッキングプログラミングのアイデアを推進し、「fread」(I / O)の記述方法を永遠に変えるNode.jsがついに登場しました(ここを読んでください)多くのための)。

一言で言えば、ノンブロッキングプログラミングは、通常、これらのタスクが完了したときに何をすべきかを指定し、プロセッサがその間に他の要求を処理できるようにすることで、時間のかかるタスクを脇に置くことを目的としています。

しかし、これらのアイデアは新しいものではありませんでした。それでは、なぜそれらがNode.jsでそれほど人気になったのでしょうか。 シンプルでノンブロッキングのプログラミングは、いくつかの方法で実現できます。 おそらく最も簡単なのは、コールバックとイベントループを使用することです。 ほとんどの言語では、これは簡単な作業ではありません。「コールバック」は他の一部の言語では一般的な機能ですが、イベントループはそうではなく、外部ライブラリ(Python、Tornadoなど)に取り組んでいることがよくあります。 しかし、JavaScriptでは、イベントループと同様にコールバックが言語に組み込まれており、JavaScriptに手を出したことのあるほとんどすべてのプログラマーは、コールバックに精通しています(または、イベントが何であるかを完全に理解していなくても、少なくともコールバックを使用したことがあります)。ループは)です。 突然、Earthのすべてのスタートアップは、クライアント側とサーバー側の両方で開発者(つまり、リソース)を再利用して、「PythonGuruNeeded」のジョブポストの問題を解決できるようになりました。

突然、Earthのすべてのスタートアップは、クライアント側とサーバー側の両方で開発者(つまり、リソース)を再利用して、「PythonGuruNeeded」のジョブポストの問題を解決できるようになりました。

これで、信じられないほど使いやすいプログラミング言語(JavaScriptのおかげで)を備えた信じられないほど高速なプラットフォーム(ノンブロッキングプログラミングのおかげで)ができました。 しかし、それで十分ですか? それは続くのでしょうか? JavaScriptは将来重要な位置を占めると確信しています。 理由をお話ししましょう。

  • 関数型プログラミング

    JavaScriptは、関数型パラダイムを大衆にもたらした最初のプログラミング言語でした(もちろん、Lispが最初に登場しましたが、ほとんどのプログラマーはLispを使用して本番環境に対応したアプリケーションを構築したことがありません)。 Javascriptの主な影響力であるLispとSelfは、革新的なアイデアでいっぱいです。 これらのアイデアは、私たちの心を解放して、新しい技術、パターン、およびパラダイムを探求することができます。 そして、それらはすべてJavaScriptに引き継がれます。 モナド、教会番号、または(より実用的な例として)Underscore.jsのコレクション関数を見てください。これにより、行とコード行を節約できます。

  • 動的オブジェクトとプロトタイプの継承

    クラスなし(およびクラスの無限の階層なし)のオブジェクト指向プログラミングは、高速開発(オブジェクトの作成、メソッドの追加、およびそれらの使用)を可能にしますが、最も重要なことは、プログラマーが代わりにオブジェクトのインスタンスを変更できるようにすることで、メンテナンスタスク中のリファクタリング時間を短縮しますクラスの。 このスピードと柔軟性は、迅速な開発への道を開きます。

  • JavaScriptはインターネットです

    JavaScriptはインターネット用に設計されており、最初からここにあり、なくなることはありません。 それを破壊するすべての試みは失敗しました。たとえば、Javaアプレットの崩壊、MicrosoftのTypeScript(JavaScriptにコンパイルされる)によるVBScriptの置き換え、モバイル市場とHTML5によるFlashの終焉を参照してください。 何百万ものウェブページを壊さずにJavascriptを置き換えることは不可能なので、今後の目標はそれを改善することです。 そして、ECMAの技術委員会39よりもこの仕事に適した人は誰もいません。

    わかりました。CoffeeScript、TypeScript、JavaScriptにコンパイルされる何百万もの言語など、JavaScriptの代替手段が毎日生まれています。 これらの代替手段は(ソースマップを介して)開発段階で役立つ可能性がありますが、2つの理由から、長期的にはJavaScriptに取って代わることができません。コミュニティが大きくなることはなく、ECMAスクリプト(JavaScriptなど)で最高の機能が採用されるためです。 )。 JavaScriptはアセンブリ言語ではありません。JavaScriptは理解できるソースコードを備えた高級プログラミング言語なので、理解する必要があります。

これで、Esprimaプロジェクトのおかげで、ソースコードで遊ぶための独自のツールを作成し、ソースコードを変更し、スタイルを変更し、コメントを追加し、インストルメント化するなど、プログラムの抽象構文ツリーで遊ぶことで想像できるあらゆる種類のツールを作成できます。まるでDOMツリーを操作しているように。

エンドツーエンドのJavaScript:Node.jsとMongoDB

したがって、これらがJavaScriptを使用する理由です。 ここで、Node.jsとMongoDBを使用する理由としてJavaScriptを使用します。

  • Node.js

    Node.jsは、高速でスケーラブルなネットワークアプリケーションを構築するためのプラットフォームです。これは、Node.jsサイトが言っていることとほぼ同じです。 しかし、Node.jsはそれだけではありません。I/Oアクセスを備えたJavaScriptアプリケーションに適したランタイム環境です。 Node.jsを使用してメインサーバーアプリケーションを作成する予定がない場合でも、Node.js上に構築されたツールを使用して開発プロセスを改善できます。 例:単体テスト用のMocha.js、自動ビルドタスク用のGrunt.js、またはフルテキストコード編集用のブラケット。

    したがって、サーバーまたはクライアント用のJavaScriptアプリケーションを作成する場合は、Node.jsの例をいくつか確認する必要があります。これは、日常的に必要であり、使用するためです。 いくつかの興味深い選択肢がありますが、それらのどれもNode.jsコミュニティの10%にさえありません。

  • MongoDB

    MongoDBは、クエリ言語としてJavaScriptを使用するNoSQLドキュメントベースのデータベースであり、エンドツーエンドのJavaScriptプラットフォームを完成させることができます。 しかし、それがこのデータベースを選択する主な理由でもありません。

    MongoDBはスキーマのないデータベースであり、オブジェクトを柔軟な方法で永続化できるため、要件の変更により迅速に適応できます。 さらに、拡張性が高く、map-reduceベースであるため、ビッグデータアプリケーションに適しています。 MongoDBは非常に柔軟性があるため、スキーマのないドキュメントデータベース、リレーショナルデータストア(トランザクションはありませんが)、または応答をキャッシュするためのKey-Valueストアとしても使用できます。

Express.jsを使用したサーバーのコンポーネント化

サーバー側のコンポーネント化は決して簡単ではありません。 しかし、Express.js(およびConnect.js)には、「ミドルウェア」のアイデアがありました。 私の意見では、ミドルウェアはサーバー上のコンポーネントを定義するための最良の方法です。 既知のパターンと比較したい場合は、パイプやフィルターにかなり近いです。

基本的な考え方は、コンポーネントがパイプラインの一部であるということです。 パイプラインは要求(入力)を処理し、応答(出力)を生成しますが、コンポーネントは応答全体に対して責任を負いません。 代わりに、必要なものだけを変更してから、パイプラインの次の部分に委任します。 パイプラインの最後の部分が処理を終了すると、応答がクライアントに返送されます。

これらの「パイプラインの一部」を「ミドルウェア」と呼びます。 明らかに、2種類のミドルウェアを作成できます。

  • 中間体:要求と応答を処理するが、応答自体に対して完全な責任を負わないため、次のミドルウェアに委任します。

  • 決勝:最終的な対応に全責任を負う者。 要求と応答を処理および変更しますが、次のミドルウェアに委任する必要はありません。 実際には、アーキテクチャの柔軟性を考慮して(つまり、後でミドルウェアを追加する)、そのミドルウェアが存在しない場合でも(この場合、応答はクライアントに直接送信されます)、とにかく次のミドルウェアに委任することをお勧めします。

具体的な例として、サーバー上の「ユーザーマネージャー」コンポーネントについて考えてみます。 ミドルウェアに関しては、ファイナルとインターミディエイトの両方があります。 決勝戦では、ユーザーの作成やユーザーの一覧表示などの機能があります。 ただし、これらのアクションを実行する前に、認証用の中間体が必要です(認証されていない要求が着信してユーザーを作成することは望ましくないため)。 これらの認証中間体を作成したら、以前に認証されていない機能を認証された機能に変換したい場所にプラグインするだけです。

シングルページアプリケーション

Initプロジェクトは、シングルページアプリケーション(SPA)の作成に重点を置いています。 ほとんどのWeb開発者は、SPAを試してみようと何度も誘惑されてきました。 私はいくつか(ほとんどがプロプライエタリ)を構築しましたが、それらは単にWebアプリケーションの未来であると自信を持って言えます。 SPAをモバイル接続の通常のWebアプリと比較したことがありますか? 応答性の違いは数十秒のオーダーです。

SPAをモバイル接続の通常のWebアプリと比較したことがありますか? 応答性の違いは数十秒のオーダーです。

SPAはWebの未来です。では、なぜレガシー形式で製品を構築するのでしょうか。 私が聞く一般的な議論は、人々がSEOについて心配しているということです。 しかし、あなたが物事を正しく処理するならば、これは問題ではないはずです:グーグル自体はそれをする方法について非常に良いチュートリアルを持っています、そしてここにもいくつかの良いコメントがあります。

Backbone.js、Marionette.js、およびTwitterBootstrapを使用したクライアント側MV*

SPA用のMVC*フレームワークについては多くのことが言われています。 難しい選択ですが、上位3つはBackbone.js、Ember.js、Angular.jsです。

3つすべてが非常に高く評価されています。 しかし、どれがあなたに最適ですか?

残念ながら、私はAngular.jsの経験が非常に限られていることを認めなければならないので、この議論から除外します(これについて詳しくは、Angular.jsチュートリアルを参照してください)。 現在、Ember.jsとBackbone.jsは、同じ問題を攻撃する2つの異なる方法を表しています。

Backbone.jsは最小限で単純であり、単純なSPAを作成するのに十分なものを提供します。 一方、Ember.jsは、SPAを作成するための完全でプロフェッショナルなフレームワークです。 それはより多くの鐘と笛を持っていますが、より大きな学習曲線も持っています。

アプリケーションのサイズによっては、featuresUsed / featuresAvailableの比率を確認するだけで簡単に決定できるため、大きなヒントが得られます。

Initの場合、ほとんどのシナリオをカバーしたかったので、SPAを簡単に作成するためにBackbone.jsを選択し、コンポーネント化のためにBackbone.Marionette.Viewを選択しました。 このように、すべてのコンポーネントは単純なアプリケーションであり、最終的なアプリは必要に応じて複雑にすることができます。

スタイリングも課題ですが、フレームワークを頼りに私たちを救済することができます。 CSSの場合、Twitter Bootstrapに勝るものはありません。これは、箱から出してすぐに使用でき、カスタマイズも簡単なスタイルの完全なセットを提供します。

BootstrapはLESS言語を使用して作成されており、オープンソースであるため、必要に応じて変更できます。 Bootstrapサイトで十分に文書化されている大量のUXコントロールが付属しています。 さらに、独自のカスタマイズモデルを作成できます。 それは間違いなくその仕事の人です。

ベストプラクティス:Grunt.js、Mocha.js、Chai.js、RequireJS、CoverJS

最後に、いくつかのベストプラクティスを定義し、Initがそれらの実装と保守にどのように役立つかを確認する必要があります。 私たちのソリューションは、Node.js自体に基づくいくつかのツールを中心としています。

  • Mocha.jsChai.js

    これらのツールを使用すると、TDDまたはBDDを適用して開発プロセスを改善し、単体テストを整理するためのインフラストラクチャと、それらを自動的に実行するためのランナーを提供できます。

    JavaScriptには何千ものユニットテストフレームワークがあります。 では、なぜMocha.jsを使用するのでしょうか。 簡単な答え:それは柔軟で完全です。

    長い答え:2つの重要な機能(インターフェース、レポーター)と1つの重要な不在(アサーション)があります。 説明させてください。

    • インターフェース:スイートや単体テストのTDDの概念に慣れている場合もあれば、「説明する」と「すべきである」という動作仕様のBDDの概念を好む場合もあります。 Mocha.jsでは、両方のアプローチを使用できます。

    • レポーター:テストを実行すると、結果のレポートが生成され、さまざまなレポーターを使用してこれらの結果をフォーマットできます。 たとえば、継続的インテグレーションサーバーにフィードする必要がある場合は、それを実行するレポーターを見つけることができます。

    • アサーションライブラリの欠如:問題になるどころか、Mocha.jsは、選択したアサーションライブラリを使用できるように設計されており、さらに柔軟性があります。 たくさんのオプションがありますが、ここでChai.jsが役立ちます。

    Chai.jsは、次の3つの主要なアサーションスタイルのいずれかを使用できる柔軟なアサーションライブラリです。

    • アサーション:TDDオールドスクールのクラシックなアサーションスタイル。 例えば:

       assert.equal(variable, ”value”);
    • 期待:BDDで最も一般的に使用される連鎖可能なアサーションスタイル。 例えば:

       expect(variable).to.equal(“value”);
    • should :BDDでも使用されますが、Shouldは動作仕様で反復的に聞こえるので、Expectを好みます'it( "should do something ..")'。 例えば:

       variable.should.equal(“value”);

    Chai.jsはMocha.jsと完全に結合します。 これらの2つのライブラリだけを使用して、TDD、BDD、または考えられる任意のスタイルでテストを記述できます。

  • Grunt.js

    Grunt.jsを使用すると、ファイルの単純なコピーアンドペーストや連結から、テンプレートの事前コンパイル、スタイル言語(SASSおよびLESS)のコンパイル、単体テスト(mocha.jsを使用)、リンティング、コードの縮小(たとえば、UglifyJSまたはClosureCompilerを使用)。 独自の自動タスクをGruntに追加するか、Gruntレジストリを検索して、何百ものプラグインを利用できます(ここでも、優れたコミュニティを備えたツールを使用することで成果が得られます)。 Gruntは、ファイルを監視し、ファイルが変更されたときにアクションをトリガーすることもできます。

  • RequireJS

    RequireJSは、AMDでモジュールをロードする別の方法のように聞こえるかもしれませんが、それ以上のものであることを保証できます。 その理由を理解するには、最初にモジュールの名前空間(demo.views.helloなど)のアイデアに言及する必要があります。これにより、各モジュールを独自の名前空間でラップすることにより、グローバル名前空間の汚染を回避できます。 問題は、これらのモジュールは再利用できないことです。1つの「インスタンス」の名前空間を変更すると、すべての「インスタンス」の名前空間が変更されます。 それとは対照的に、RequireJSでは最初から再利用可能なモジュールを定義できます。 (さらに、モジュールがグローバル変数にアクセスするのを防ぐために、依存性注入を採用するのに役立ちます。)

  • CoverJS

    コードカバレッジは、テストを評価するための指標です。 名前が示すように、現在のテストスイートでカバーされているコードの量がわかります。 CoverJSは、コードに(JSCoverageのようなコード行ではなく)ステートメントをインストルメント化し、インストルメントされたバージョンのコードを生成することにより、テストのコードカバレッジを測定します。 また、継続的インテグレーションサーバーにフィードするレポートを生成することもできます。

ブランチを使用して機能を切り替える

Initを開始したとき、ユーザーがプロジェクトで必要になる可能性のあるさまざまな機能をアクティブ化および非アクティブ化する方法が必要でした。 この機能を実装するために、gitのブランチシステムに根本的なアプローチを取ることにしました。

本質的に、各ブランチは、ユーザーが含めることができる1つまたは複数の機能を表します。 プロジェクトをゼロから開始する場合は、必要な最小限のブランチから始めてから、目的のブランチとマージして他のテクノロジーを追加します。 たとえば、Backbone.jsとMarionette.jsを使用してプロジェクトを開始するとします。 さて、Backbone.jsブランチから始めて、それをMarionetteブランチとマージし、追加したい機能のすべてのビットを続けていくことができます。

init.jsとJavascript

今のところ、機能を追加するためにマージするというこのアイデアは、テクノロジーテンプレート(Backbone、Node、Expressなど)にのみ使用できます。 ただし、将来的には、バックエンド(MongoDBからPostgresなど)とクライアントの実装を切り替えることができるようになります。

Initを使用してプロジェクトを開始し、HerokuTodayにデプロイします

プロジェクトを開始するためのより簡単な方法はかつてありませんでした。 GitHubリポジトリに移動し、最新のコミットがあるブランチを確認します(現在はusermanagerですが、将来変更される可能性があります)。

  1. プロジェクトのディレクトリを作成します(または既存のディレクトリを使用します)。
  2. 「gitinit」を使用してリポジトリを作成します(または既存のリポジトリを使用します)。
  3. initでリモコンを追加する

     git remote add init git://github.com/picanteverde/init.git
  4. 必要なブランチを取得します

     git pull init usermanager
  5. Herokuプロセスファイルを取得する

     git pull init heroku-webprocess
  6. Heroku Toolbeltをインストールして、Herokuアプリを作成します

     heroku create
  7. マスターブランチをHerokuにプッシュします

     git push heroku master
  8. Herokuで稼働しているアプリにアクセスしてください!

これで、ほんの数行のコードでキラー機能の開発を開始できます。 それだけでなく、可能な限り自動化された開発スイートで、最新の最も効率的なテクノロジーを使用して開発することになります。

Initを使用して、次の大きなアイデアを開始できることを願っています。 Initリポジトリで新しい修正や機能を確認することを忘れないでください。その開発は非常に活発であり、皆様からのフィードバックをお待ちしております。