確かに、JavaScriptでモジュールとクラスを作成するという原則(矛盾していても)に出くわしました。 特定のサービスが機能するためのAPIを提供するWebページに埋め込まれたスクリプトを作成する必要があるとき、そのようなスクリプトの設計に関する価値のある推奨事項を見つけることができませんでした。
そこで、私が遭遇した(かなり明白な)スクリプト要件を以下に示します。
- サードパーティのWebアプリケーションのページに埋め込まれます。
- 彼は仕事を効率的に行わなければなりません。
- すぐにロードされるはずです。
- Webアプリケーションの動作に(予測できないほど)影響を与えてはなりません。
- 安全要件を遵守する必要があります。
- ... //その他:)
実際の実践から、以下に説明する原則が生まれました。 これらは完全にユニークなアイデアではなく、Googleアナリティクスやjqueryライブラリなど、他の人のソリューションで見たベストプラクティスの集合です。
1.組立システム
彼女が必要です。 最初は、すべてを1つのファイルに保持することができます(そこから開始することもできます)が、アセンブリが必要であることが明らかになります。 サードパーティのライブラリが使用されているため。 いくつかのスクリプト配信オプションがあるためです。 スクリプトは必要に応じてリソースファイルをロードできるためです。 また、スクリプト全体を1つのファイルに保持している場合でも、すぐに検討する必要があります。
収集方法 連結のみ。 メインスクリプトはすばやく、つまり1つのファイルでロードする必要があるためです。
これは、すべてを1つのファイルにアップロードする必要があるという意味ではなく、すべてが正常であることを願っています。 オプションで、ライブラリクライアントが適切なメソッドを呼び出すときにのみ追加機能をロードする必要があります。 ただし、カーネルは迅速にロードし、適切にキャッシュし、すぐにクライアントにAPIを提供する必要があります。
スクリプト全体を1つのスコープでラップする必要があります。 明らかに? はい
(function () { // }());
ところで、Gruntでスコープ内のコードをラップするには、 options
banner
とfooter
使用しoptions
。
concat: { injectScriptProd: { src: [...], dest: 'someScript.js', options: { banner: '(function(){\n', footer: '\n}());' } },
2.ローカル構成と実稼働構成を切り替える
アセンブリと構成を簡単に管理するために、1つの構成変数を取得し、それを別個のconfigDev.js
またはconfigProd.js
に入れて、別個のスクリプトアセンブリを作成することができました。 また、他の理由によるアセンブリオプションには3つ以上が必要でした。 その結果、これらの単純なファイルが利用できるようになったため、構築、コーディング、生活が非常に簡単になりました。 連結するときは、スクリプトを作成するファイルを指定するだけで、スクリプトファイル全体の準備が整います。
悪い習慣: <% serverUrl %>/someApi
形式のJavaScriptコード全体で置換可能な変数を使用します。 コードの可読性を損ない、よりゆっくりと収集します。 そして、私は、うなり声の時計が本当に速く動作するようにしたいですか?
prod設定ファイルの例:
var config = { server: "https://www.yourserver.com/api/", resourcesServer: "https://www.yourserver.com/cdn/", envSuffix: "Prod", globalName: "yourProjectName" }; // , !
3. APIを渡す方法は?
さまざまな方法がありますが、今ではこれを行います。
window[config.globalName] = yourApiVar;
これにより、次のことが可能になります。
- ページ上でライブラリのいくつかのバージョンをテストし、互いに干渉しないようにします。
- スクリプト全体を1つの閉じたスコープに入れます。
- (突然必要な場合)互換性の問題を解決します。 APIインスタンスの管理は、ライブラリクライアントのコードではなく、スクリプト自体のコードで行われることがわかります。 したがって、すべてのインスタンスを完全に制御できます。
4.「正しい」モジュールシステム
ここで何を言っても、腐ったトマトは別のモジュールのシステムを好む人から私に飛び込んでくるでしょう。 始めます。
正しいことは:
var module = (function () { // for each module have this structure var someInnerModuleVar; // return { publicMethod: publicMethod }; }());
なぜ正確に? 答えは明らかです。そのようなモジュールのコードを連結すると、モジュール用のライブラリがなくてもすべてが機能します。
5.初期化API
ライブラリに少なくとも何らかの初期化がある場合(そして、あなたが異なって考える場合でもそこにあります)、それを別のメソッドに入れてください。 各モジュールで初期化用の個別のメソッドを作成することもできます。 そして、それらを明示的に呼び出し、それがどのように機能し、どの順序で動作するかを明確に理解します。
おそらく、これで十分でしょう。 結果のモジュールの構造は次のとおりです。
(function () { 'use strict'; var config = {}; var sharedState = {}; var module = (function () { var someInnerModuleVar; // js return { publicMethod: publicMethod, init: init }; }()); start(); }());
テンプレートの改善方法に関するアイデアがあれば、喜んで聞いてください。 私は主にJavaで書いたが、このプロジェクトは私の最も激しいJavaScriptの経験です。 コメントに改善のためのアイデアを書いてください。
また、 cookies
、 localStorage
、db、networkの操作について書くことも考えています。 最も興味深いトピックを書いてください。