Vue.js + Asp.NETCore + TypeScriptアプリケーションのRequireJS

ロゴ







Visual Studio 2017でモジュラーアプリケーションVue.js + Asp.NETCore + TypeScriptを作成します。 Webpackの代わりに、TypeScript + Bundler&Minifierコンパイラ(VS2017への拡張)をビルドシステムとして使用します。 ランタイムへのアプリケーションモジュールのロードは、SystemJSまたはRequireJSによって提供されます。 SystemJSだけでなくRequireJSも理解するAMDモジュール(非同期モジュール定義)のフォーマットを検討してください。







すぐに警告します-Vue.jsはAMDを完全にサポートしていないか、バグを含んでいるので、ほとんどハッカーのトリックが適用されますが、すべての人には機能しません。 しかし、この記事により、これがどのように理解されるかを願っています 世界 Vue.js。







この記事はチュートリアルの補足です: Vue.js + Asp.NETCore + Typepack application without Webpack 。 例でSYSTEMモジュールの形式が使用された場所。 SystemJSローダーにのみ賭けるのは怖いです。 この記事の執筆時点では、SystemJSのリリースは0.20であり、API、オプションなどが大幅に変更される可能性があります。







AMDモジュール形式とRequireJSローダーを使用する目的は、SystemJSの根本的な変更を防ぐことで、より一般的なRequireJSローダーとAMDモジュール形式を使用できるようにすることです。







このマテリアルは、VS2017に対応できるように設計されており、プログレッシブJavaScriptフレームワークVue.jsに精通しています。







はじめに



当初、AMDおよびRequireJSの資料は、 Vue.js + Asp.NETCore + Typepack application without Webpackの記事にありました 。 しかし、それは大きすぎることが判明したので、私はピースをカットしなければなりませんでした。 完全を期すために、AMDとRequireJSにも対処することは有益だと思います。







AMDへの切り替え



TypeScriptコンパイラは、{"module": "system"}または{"module": "amd"}オプションがインストールされている場合、すべてのモジュールを1つの出力ファイルに収集します。 オプション「system」で判明したので、「amd」を試す必要があります。 これがないと、RequireJSを適用できません。 このブートローダーは、モジュールのamd形式のみを理解します。







スターターアプリケーション



出発点として、主要な記事で説明したVisual Studio 2017ソリューションからgithubのTryVueプロジェクトを取得できます。 このプロジェクトではさらにアクションを実行できますが、TryVueRequireというコピーを作成することをお勧めします。







アプリケーションとバンドルをビルドすると、次のファイルがwwwroot \ distディレクトリに表示されます:main.js、main.css、app-templates.html。 便利な方法でアプリケーションを起動します(VS2017環境のF5、Ctrl-F5、または外部:dotnet run)。







ブラウザは、スクリーンショットに示されているものに似たものを取得するはずです。







画像







ブラウザはアプリケーションのファイルをキャッシュするので、ページを正しく更新する必要があります(キャッシュをリセットして)。 今後の実験で何か問題があると思われる場合は、ブラウザのキャッシュをリセットしてください。







エラー:vue_3.defaultはコンストラクタではありません



tsconfig.jsonファイルで、コンパイラオプションを{"module": "amd"}に変更し、アプリケーションを再構築して開始しようとします。







ブラウザとコンソールにテキスト「loading ..」が表示されるはずです-開発者モードに切り替えるとエラーが発生します(Chromeの場合-F12キー)。







wwwroot \ dist \ main.jsからいくつかのコードフラグメントを削除することにより、それらがどのように宣誓し、何を正確に知ることができるのです。 main.jsファイルからの抜粋に、クラッシュが発生した行とエラーテキストを引用しています。







define("components/Hello", ..., function (...) { ... exports.default = vue_1.default.extend({ ... }); define("components/AppHello", ..., function (...) { ... exports.default = vue_2.default.extend({ ... }); define("index", ..., function (...) { ... var v = new vue_3.default({ ... });
      
      





 Uncaught (in promise) Error: Cannot read property 'extend' of undefined Uncaught (in promise) Error: vue_3.default is not a constructor
      
      





最初のエラーはvue_1.default.extend、vue_2.default.extendに関連しています。 2番目のエラーはvue_3.defaultに関連しています。 エラーテキストから、vue.jsがデフォルトコンストラクターを定義していないことは明らかです。 これは確認するのが非常に簡単です-vue_1、vue_2、vue_3のポイントの後にこのデフォルトを削除します。







アプリケーションは動作します! Vue.js.インスタンスの未定義のデフォルトプロパティをどうするかを理解することは残っています。







SystemJSのパッチ



確かに、プロジェクトの各ビルド後に手動でwwwroot \ dist \ main.jsファイルから「デフォルト」を削除することは、最も便利なオプションではありません。 そのため、wwwroot \ index.htmlファイルにパッチを作成します。これは、vueをロードし、vueのデフォルトプロパティを設定し、main.jsをロードして、アプリケーションを起動します。







 <!-- wwwroot\index.html--> <!--  : --> SystemJS.import('dist/main.js').then(function (m) { SystemJS.import('index'); }); <!--   : --> SystemJS.import('vue').then(function (m) { if (!m.default) { m.default = m; console.warn('HACK: vue.default was undefined'); } SystemJS.import('dist/main.js').then(function (m) { SystemJS.import('index'); }); });
      
      





アプリケーションは動作するはずです。 このオプションをチェックした後、index-system.htmlにメモリのindex.htmlを保存します。







RequireJSへの切り替え



モジュールのamd形式では、RequireJSの使用は、構成方法とAPI(アプリケーションプログラムインターフェイス)のみがSystemJSと異なります。







RequireJSに切り替えるには、wwwroot \ index.htmlファイルでのみ変更が行われます。 TypeScriptソースコードファイルとプロジェクト設定は影響を受けません。







RequireJSの簡単なパッチオプション



Vue.jsのデフォルトコンストラクターを定義する別のオプションを提案する前に、RequireJSを使用してindex-system.htmlの完全な類似物を作成します。 wwwroot \ index.htmlファイルで、system.js-> require.jsスクリプトのロードを変更するだけです。 次にrequire.jsを設定し、必要なものをダウンロードしてアプリケーションを実行します。 また、不在の場合はデフォルトの処方コードを繰り返します。







 <!-- wwwroot\index.html--> ... <script src="http://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.5/require.js"></script> <script> require.config({ paths: { "vue": "https://cdn.jsdelivr.net/npm/vue@2.5.13/dist/vue", "index": "dist/main" } }); require(['vue'], function (m) { if (m.default === undefined) { m.default = m; console.log('HACK: ' + m.name + '.default was undefined'); } require(['index']); }); </script> ...
      
      





未定義のデフォルトコンストラクターの問題に対する「正しい」バージョンのソリューションをindex.htmlに実装するために、wwwroot \ index.htmlをindex-require.htmlファイルのメモリに保存します。







Vue.js呼び出しのオーバーライド



Vueインスタンスにデフォルトのプロパティがないという問題に対する別の解決策があります。 main.jsでモジュールを定義する前に、「vue」へのすべての呼び出しを閉じ、「vue-parent」(真の「vue」に名前を変更)の修正済みエクスポートを行う小さなアダプターを定義します。







アダプターの実際の定義:







 define("vue", ["require", "exports", "vue-parent"], function (require, exports, vueParent) { Object.defineProperty(exports, "__esModule", { value: true }); exports.default = vueParent.default || vueParent; });
      
      





アダプタの使用に関連するwwwroot \ index.htmlの部分を以下に示します。 この例を単純化するために、index.htmlにアダプターテキストが含まれています。 個別のvue-stub.jsファイルとして保持する方がより正確です。このファイルは、連結子を使用してmain.jsの先頭に接着する必要があります。







 <!-- wwwroot\index.html--> ... <script src="http://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.5/require.js"></script> <script> // vue-stub.js define("vue", ["require", "exports", "vue-parent"], function (require, exports, vueParent) { "use strict"; //if (!vueParent.default) console.warn('HACK: vue.default was undefined'); Object.defineProperty(exports, "__esModule", { value: true }); exports.default = vueParent.default || vueParent; }); </script> <script> require.config({ paths: { "vue-parent": "https://cdn.jsdelivr.net/npm/vue@2.5.13/dist/vue", "index": "./dist/main" } }); require(['index']); </script> ...
      
      





おわりに



おそらく私は何かを理解していないかもしれませんが、Vueインスタンスのvue.jsライブラリは、AMD(非同期モジュール定義)形式モジュールで期待される「デフォルト」プロパティの定義を提供しません。 正直なところ、これはバグまたは機能です-私は知りません。







子猫と一緒にそのようなパイで。







モジュールとRequireJSのamd形式を使用するには、デフォルトを定義するアダプターを挿入する必要がありました。 誰かがより正確な方法を知っている場合-共有。







参照:









UPD 2018年3月1日:







@mayorovpは、amdモジュールの問題に対するより適切な解決策を提案しました。tsconfig.jsonにコンパイラオプション{"esModuleInterop":true}を追加します。







その後、アダプターは不要になり、RequireJSの使用は簡単になります。 したがって、アプリケーションのダウンロードと実行は次のようになります。







 <!-- wwwroot\index.html--> ... <script src="http://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.5/require.js"></script> <script> require.config({ paths: { "vue": "https://cdn.jsdelivr.net/npm/vue@2.5.13/dist/vue", "index": "./dist/main" } }); require(['index']); </script> ...
      
      





githubの VS2017ソリューションに必要なすべての変更が加えられました。







アップデート06/05/2019:







現時点では、 githubのサンプルのソースコードは記事のソースコード若干異なります。 変更は、使用されているコンポーネントのバージョンの更新(Asp.NETCore 2.2への切り替えなど)によって引き起こされます。








All Articles