ホームページ >ウェブフロントエンド >jsチュートリアル >ASP.NET MVC プロジェクトでの RequireJS ライブラリの使用例_JavaScript ヒント
RequireJS は、フロントエンドのモジュラー開発用の人気のあるツールであり、require.js という名前の Javascript ライブラリ ファイルです。
RequireJs の主な機能:
(1) Web ページの応答が失われないように、js ファイルの非同期読み込みを実装します。
(2) モジュール間の依存関係を管理して、コードの作成とメンテナンスを容易にします。
フロントエンドのモジュラー開発には多くのツールがあり、一般に 2 つのカテゴリに分類されます。1 つは dojo v1.8 以降の組み込みのモジュラー開発コンポーネントを備えたハイエンド ツールです。 .js が必要です。sea.js はモジュール開発に焦点を当てたツールです。
モジュール分割のルールから、主に AMD と CMD の 2 つのカテゴリに分類されます。Dojo と require.js は前者に従い、sea.js は CMD 仕様に従います。
require は単一ページのアプリケーションでは適切に機能しますが、従来の複数ページのアプリケーションの場合、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
<script type="text/javascript"> $(function(){...}); </script>
次に、require を使用して js を計画し、次の構造の js ディレクトリを構築します
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
次に、_layout 内のすべての js 参照を削除し、@RenderSection コマンドを使用して、サブページに js 参照、_layout.cshtml を提供するよう要求します。
<head> ... @RenderSection("require_js_module", false) ... </head>
の上のappディレクトリ
@section require_js_module{ <script src="@Url.Content("~/js/require.js")" data-main="@Url.Content("~/js/app/home.index.js")" ></script> }
パブリック構成
メイン モジュールは、require メソッドの使用に加えて、require.config を通じて他のモジュールのパスを設定する必要があり、さらに 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' } } });
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 を次のコードになるように変更することです:
使用一个命名的模块home.index2作为过渡,在主模块中手动require,这样可以保证config在主模块执行之前加载,也就使得home.index2在加载的时候已经加载了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。这样可想而知,每个页面在加载时最多只会下载两个js,而且公共模块的代码会“按需执行”。
执行上面的脚本压缩,需要安装有node。可以在从这里下载。
自动脚本
但是,随着主模块的增加,需要随时跟踪和修改这个build文件,这也是很麻烦的。于是,笔者基于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,完成一键压缩功能,build.bat:
@echo off set PWD=%~p0 set PWD=%PWD:\=/% cd "D:\node" 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