我有一些AMD / Require.js问题。我对模块化的js和AMD都很陌生,所以如果有人能帮我解决这个问题会很棒。
假设我的系统有2个不同的区域,定义为模块(“define()”函数 - 我正在使用Backbone,顺便说一句)
我注意到,如果用户当前正在访问网站的“图书”部分,则DVD部分中的文件也包含在Require.js中。我有以下问题:
任何想法都会很好。
答案 0 :(得分:3)
这是可能的,但在很大程度上取决于您如何构建JS应用程序。另外,我假设你在这里有一个Backbone应用程序。不同的框架有不同的方法。
例如,您可能会看到app.js
,如下所示:
define([
'DvdItemView', 'DvdModel', 'DvdCollection',
'BookItemView', 'BookModel', 'BookCollection'
], function(DvdView, DvdModel, DvdCol, BookView, BookModel, BookCol) {
// router declarations go here
});
由于您根据上述模块“定义”此模块,因此在运行路由器代码之前始终会加载它们。正如@alexndm指出的那样,如果你在这上面运行r.js,你实际上可以将所有模块合并为一个。
然而,正如您所提到的,一旦应用程序达到一定大小,您想要的是根据用户与之交互的内容来延迟加载不同的部分。这更像是一个应用程序问题,而RequireJS在这方面只能帮助你。我认为最好的方法是在路由器中。
routes: {
'/books': 'booksList',
'/books/:id': 'booksDetail',
'/dvds': 'dvdList',
'/dvds/:id': 'dvdDetail'
},
booksList: function() {
if (!booksDepsLoaded) {
// Here we go and load the appropriate files
require(['BooksArea'], function(BooksArea) {
// BooksArea.Model, BooksArea.Collection, etc...
// do stuff to render a book list..
})
}
},
...
这是非常天真的伪代码。您可能希望编写一些通用代码来处理仍需要加载依赖项的路由,以及错误处理等。
要掌握的重要概念是,您需要在应用程序/路由器启动之前定义路由 - 然后您需要异步代码来处理提取模块。
答案 1 :(得分:3)
查看require-lazy,这是一个在运行时和编译时都插入的小库(r.js)我写的就是按你的要求去做。基本用法是:
(来自main.js
脚本:)
define(["lazy!modules/books", "lazy!modules/dvds"], function(books, dvds) {
...
});
modules/books
和modules/dvds
脚本与往常一样。上面定义函数中的books
和dvds
变量实际上是实际模块的 promises 。他们自己的模块不预先加载。然后,在main.js
中的某个位置,代码决定显示哪个视图:
if( view === "books" ) {
books.get().then(function(realBooks) {
...
});
}
else if( view === "dvds" ) {
dvds.get().then(function(realDvds) {
...
});
}
答案 2 :(得分:2)
实际上可以通过稍微不同的项目结构来实现这一点。
詹姆斯伯克有一个回购详细说明如何在这里进行,https://github.com/requirejs/example-multipage-shim
基本思想是你有多个“main.js”文件可以为你网站的不同区域加载依赖项。
因此,在您的情况下,您可能会有main-books
和main-dvd
个文件。
在不同领域的HTMl中,只需加载两个区域所需的通用模块,然后加载特定的主文件......
require(['./js/common'], function (common) {
require(['app/main-books']);
});
希望有所帮助!
答案 3 :(得分:1)
在生产中使用require.js时,建议运行r.js http://requirejs.org/docs/optimization.html
它的作用是: - 将相关脚本组合到构建层中,并通过UglifyJS(默认值)或Closure Compiler(使用Java时的选项)缩小它们。 - 通过内联@import引用的CSS文件并删除注释来优化CSS。
这意味着所有脚本将被连接成一个文件,并且不会有任何额外的http请求。