AS P.NET MVCプロジェクトでRequireJSライブラリを使用する使用例

10577 ワード

RequireJSは先端モジュール化によって開発されたファッションツールであり、自身はJavascriptのライブラリファイルであり、すなわちrequire.jsである.RequireJsの主な機能:
(1)jsファイルの非同期的なロードを実現し、ウェブページの応答を失わないようにする.
(2)管理モジュール間の依存性は、コードの作成と維持に便利である.
先端モジュール開発には多くのツールがあります.大体二つの種類に分けられます.一つはドジョジョのような大全書で、ドジョイv 1.8の後にモジュール化開発部品が内蔵されています.もう一つはrequire.jsのようにモジュール開発に専念するツールです.
モジュール化されたルールから区分すると、主にAMD、CMDの2種類に分けられ、dojo、require.jsは前者に従い、sea.jsはCMD規格に従う.
requireは1ページの応用の中で魚のように水を得ることができますが、伝統的な複数ページの応用に対して、requireを使うのは多少困惑して不便です.
本論文ではどのようにASP.NET MVCの構造にrequireを適用するかを説明し、圧縮スクリプトを与え、半自動化圧縮を実現します.
jsコードを分離する一般的にASP.NET MVCのルートの一つはビューに対応しています.ビューのファイル構造は次のようになります.

Views
 |--Shared
 |--_layout.cshtml
 |--Home
 |--Index.cshtml
 |--Blog
 |--Create.cshtml
 |--Edit.cshtml
 |--Detail.cshtml
 |--Index.cshtml
ここで仮説を立てますlayout.cshtmlはすべてのページで共有されています.普通なら、私達は_にいます.layoutでは、jQueryやbootstrapなどの公共のjsライブラリを引用して、他のページではこれらのライブラリをもう一回引用する必要がなく、符号化の効率を高めました.しかし、異なるページは最終的に異なるjsに依存します.特にページ自体の機能を実現するカスタムjsは他のページで特殊なjsを再引用しなければなりません.さらに、jsを直接ページに書いても、例えば下記のコードはよくViewに現れます.


 $(function(){...});

このようにすると、ページが混乱してしまいます.また、ページタグのコードがブラウザにキャッシュされなくなり、ページコードの長さが増しました.さらに重要な欠点は、jQueryなどのライブラリがページにロードして匿名関数を実行するには時間がかかりますが、もしいくつかのページにjQueryが必要でなければ、ページがレイアウトページとしては、jQueryの初期化コードは実行されなくなります.これは無駄です.実は、javascriptのモジュール化ロードの思想はこれらの問題を解決するためです.ボルトp>
<p>次に私達はrequireで私達のjsを計画して、下の構造のjsディレクトリ<p>
<p>lt;bragt;ボルトp>
<div class="jb 51 code"
<pre class=「braush:plin;」gt;13;
js&腣13;
|--app&铉13;
|--home.index.js&菗13;
|--blog.create.js&菵13;
|--blog.edit.js&舳13;
|--blog.detail.js&腣13;
|--blog.index.js&腣13;
|--jquery.js&腣13;
|--bootstrap.js&菵13;
|--undersscore.js&菵13;
|--jquery.ui.js&菗13;
|--jquery.customplugin.js&唵13;
|--config.js&菵13;
|--require.js&腣13;
<pregt;
<div>
<p>共通のクラスのjsモジュールを直接jsディレクトリの下に置いて、ページレベルのjsを一つのアプリのサブディレクトリの下に置いてください.なお、appにおいては、各ページのjsファイルは、それぞれのページのjsを抽出しなければならないという意味であり、このように構造の複雑さを増しましたが、ページに手書き<スクリプト>ラベルの陋習また、jsディレクトリの下の公共ライブラリには、第三者のライブラリの他に、自分で開発したライブラリも含まれています.また、config.jsというファイルもあります.このファイルはとても重要です.後で話します.ボルトp>
<p>それから、私達は削除できます.layoutでは、すべてのjsを引用し、@RenderSectionのコマンドを使用して、サブページにjs参照を提供するように要求します.layout.cshtml:</p>
<div class="jb 51 code"
<pre class=「braush:js;」gt;13;
<headgt;13;
…&腣13;
@RenderSection(「requiremodule」、false)&菗13;
…&腣13;
<headgt;13;
<pregt;
<div>
<p>このようにjsに対する需要はすべてのviewページに置いてあります.requireの使い方によって、私達は各サブビューでrequire.jsを引用して、メインモジュールを指定します.これらのメインモジュールは上のapディレクトリの下のjs<です.p>
<div class="jb 51 code"
<pre class=「braush:js;」gt;13;
@セレクションrequire_jsmodule{&夝13;
<script src=「@Url.Contintent(~/js/require.js)」data-main=「@Url.Content(」~/js/ap/home.index.js")」>
)
すべてのjsコードはapの下のjsに書いてあります.このようにjsを規範化して、ページをより綺麗にします.さらに重要なのはこれらのjsは圧縮されてもいいし、ブラウザにキャッシュされてもいいです.さらに実行効率を高めます.
共通のconfigは、主モジュールがrequire方法を使用する以外に、他のモジュールの経路をrequire.co.nfigによって構成する必要があることを知っています.さらに、shimが必要です.例えば、下のコードは常にメインモジュールの先頭に表示されます.

require.config({
 paths: {
 "jquery": "lib/jquery.min",
 "underscore": "lib/underscore.min",
 "backbone": "lib/backbone.min"
 },
 shim: {
 'underscore':{
  exports: '_'
 },
 'backbone': {
  deps: ['underscore', 'jquery'],
  exports: 'Backbone'
 }
 }
});

メインモジュールは一つしかないので、上のコードを一回書いても大丈夫です.しかし、複数ページの場合、メインモジュールは複数あります.各メインモジュールにはこのようなコードが含まれています.そこで、統一した配置のところがほしいですが、どうやって書くべきですか?これらの構成をモジュールconfig.jsとして考えています.他のメインモジュールにこのモジュールに依存させてもいいです.例えば下のconfig.js:

requirejs.config({
 paths: {
 "jquery": "/js/jquery.min",
 "bootstrap": "/js/bootstrap"
 },
 shim: {
 'bootstrap': {
  deps: ['jquery'],
  exports: "jQuery.fn.popover"
 }
 }
});
config.jsの書き方は特にありません.これからはhome.index.jsで引用します.

require(['../config','jquery', 'bootstrap'], function () {
 //main module code here

});

しかし、このように書くのはやはり違います.主モジュールに依存されているモジュール(ここのconfig、jquery、bootstrap)は、ロードする時、ロード順序は不確定です.しかし、configモジュールは他のモジュールの前にロードする必要があります.どうすればいいですか?一つの折衷案はhome.index.jsを修正して、次のコードになります.

require(['../config'], function () {
 require(['home.index2']);
})
, define("home.index2", ['jquery', 'bootstrap'], function () {
 //main module code here
})
移行として名前付きのモジュールhome.index 2を使用して、メインモジュールで手動requireでconfigがメインモジュールで実行される前にロードされることを保証します.すなわち、home.index 2はロード時に既にconfigをロードしました.
圧縮requireはjsを圧縮して結合するための圧縮ツールを提供します.詳細はここに移動してください.http://requirejs.org/docs/optimization.html.簡単に言えば、requireはr.jsというファイルを提供して、当地のnodeプログラム(Node.js)を通じて、このr.jsを実行していくつかのパラメータを導入して、モジュール間の依存を自動的に分析して、結合と圧縮の目的を達成することができます.同じように、これは一ページのアプリケーションにとっては簡単です.メインモジュールは一つしかないですが、複数ページについてはどうすればいいですか?幸い、この圧縮ツールは構成ファイルを使って圧縮を指導することができます.このようにすれば、私達は次の構成スクリプトのbuild.jsを書くことができます.

var build = {
 appDir: '../js',
 baseUrl: '.',
 dir: '../js-built',
 mainConfigFile: '../js/config.js',
 modules: [
 //First set up the common build layer.
 {
  //module names are relative to baseUrl
  name: 'config',
  //List common dependencies here. Only need to list
  //top level dependencies, "include" will find
  //nested dependencies.
  include: ["bootstrap", "config","jquery"]
 },
 //Now set up a build layer for each page, but exclude
 //the common one. "exclude" will exclude nested
 //the nested, built dependencies from "common". Any
 //"exclude" that includes built modules should be
 //listed before the build layer that wants to exclude it.
 //"include" the appropriate "app/main*" module since by default
 //it will not get added to the build since it is loaded by a nested
 //require in the page*.js files.
 {
 name:"app/home.index",
 exclude:["config"]
 },
 {
 name:"app/blog.create",
 exclude:["config"]
 },
 ...
 ]
}
このコマンドで圧縮を実行し、圧縮の結果はjs-buildディレクトリに保存されます.

node.exe r.js -o build.js
build.jsスクリプトは実際にjsオブジェクトです.私たちはconfigを公共モジュールに加入して、各メインモジュールから除外します.このように、すべての公共ライブラリはconfigを含み、一つのjsに圧縮されるが、メインモジュールは余分なconfigを含まない.このように考えれば、各ページはロード時に最大2つのjsしかダウンロードできないし、共通モジュールのコードは「必要に応じて実行する」ことができます.
上のスクリプトの圧縮を実行するには、nodeがインストールされています.ここからダウンロードできます.
自動スクリプトですが、メインモジュールの増加に伴い、いつでもこのファイルをフォローして修正する必要があります.これも面倒くさいです.そこで、筆者はnode.jsに基づいてbuild-build.jsというスクリプトを開発しました.ディレクトリ構造に基づいて自動的にbuild.jsを生成します.

fs = require('fs');
var target_build = process.argv[2];
//console.log(__filename);
var pwd = __dirname;
var js_path = pwd.substring(0,pwd.lastIndexOf('\\')) + '\\js';
console.log('js path : ' + js_path);
var app_path = js_path + '\\app';
console.log('js app path : ' +app_path);

var app_modules = [];
var global_modules = [];

//build json object
var build = {
 appDir: '../js',
 baseUrl: '.',
 dir: '../js-built',
 modules: [
 //First set up the common build layer.
 {
  //module names are relative to baseUrl
  name: 'config',
  //List common dependencies here. Only need to list
  //top level dependencies, "include" will find
  //nested dependencies.
  include: []
 }
 ]
}

fs.readdir(app_path,function (err,files) {
 // body...
 if (err) throw err;
 for(var i in files){
 //put module in app_modules
 var dotindex = files[i].lastIndexOf('.');
 if(dotindex >= 0){
  var extension = files[i].substring(dotindex+1,files[i].length);
  if(extension == 'js'){
  app_modules.push({
   name: 'app/' + files[i].substring(0,dotindex),
   exclude: ['config']
  });
  }
 }
 }

 for(var j in app_modules){
 build.modules.push(app_modules[j]);
 }
 
 fs.readdir(js_path,function (err,files){
 if (err) throw err;
 for(var i in files){
  //put module in app_modules
  var dotindex = files[i].lastIndexOf('.');
  if(dotindex >= 0){
  var extension = files[i].substring(dotindex+1,files[i].length);
  if(extension == 'js'){
   global_modules.push(files[i].substring(0,dotindex));
  }
  } 
 }

 build.modules[0].include = global_modules;
 //console.log(build);
 var t = pwd + '\\' + target_build;
 console.log(t);
 var fd = fs.openSync(t, 'w');
 fs.closeSync(fd);
 var json = JSON.stringify(build);
 fs.writeFileSync(t, json);
 });
});

ここのコードは複雑ではありません.主にディレクトリを巡回し、オブジェクトを生成し、最後にオブジェクトをbuild.jsに列化します.読者は自分で読んで修正することができます.最後に、batを作成して、ワンタッチの圧縮機能を完成します.

@echo off
set PWD=%~p0
set PWD=%PWD:\=/%
cd "D:
ode" node.exe %PWD%build-build.js build.js node.exe %PWD%r.js -o %PWD%build.js cd %~dp0
このようにして、簡単に複数ページのrequire方案を実現しました.最後のプロジェクトディレクトリはこのようなものかもしれません.

Views
 |--Shared
 |--_layout.cshtml
 |--Home
 |--Index.cshtml
 |--Blog
 |--Create.cshtml
 |--Edit.cshtml
 |--Detail.cshtml
 |--Index.cshtml

build
|--build.js
|--r.js
|--build-build.js
|--build.bat

js
|--app
 |--home.index.js
 |--blog.create.js
 |--blog.edit.js
 |--blog.detail.js
 |--blog.index.js
|--jquery.js
|--bootstrap.js
|--underscore.js
|--jquery.ui.js
|--jquery.customplugin.js
|--config.js
|--require.js