首先,这不是一个独特的解决方案的问题。我将解释我使用RequireJS的方式,它适用于我,并可能适合你:)
二,英语不是我的母语。有关该语言的更正和提示将非常感谢。随意,球员:)
1)是否需要JS甚至实际为不是单页的项目?
这取决于。例如,如果你的项目在页面之间没有共享代码,RequireJS的帮助将是适度的。 RequireJS的主要思想是将应用程序模块化为可重用代码的块。如果你的应用程序只使用页面特定的代码,那么使用RequireJS可能不是一个好主意。
2)不使用优化器,我的每个主文件都以基本相同的配置选项开始。有没有办法避免这种情况?像每个主文件都包含相同的构建配置文件而不必实际构建它?
我看到正在对主文件的配置,或创建一个模块,将配置RequireJS,然后使用该模块作为main.js.第一依赖的唯一途径但这可能会很棘手。我的应用程序中不使用许多main.js文件;我只使用一个充当装载程序的应用程序(请参见下文)。
3)r.js是否应该进入httpdocs_siteroot的父目录?
不一定。你可以把它放在/ media目录中,因为你所有的客户端都在那里。
4)我的应用程序目录结构或使用requirejs有什么明显的错误吗?
我不会那么说。另一方面,结构可能有点过于分散。例如,你可以把所有的'第三方东西'放在一个/ vendor目录中。但这只是糖;你的结构将运作良好,看起来是正确的。我认为主要问题是多个主文件中的requirejs.config()调用。
我现在有同样的问题,我结束了以下解决方案:
1)不要用规定的包装不符合要求的AMD-文件。尽管它起作用,但您可以使用requirejs.config中的“shim”属性(请参见下文)获得相同的结果。
2)在多页面应用程序中,我的解决方案是不要求优化的main.js文件中的页面特定模块。相反,我需要从主文件中获取所有共享代码(第三方和我自己的代码),并在每个页面上加载页面特定的代码。主文件最终只是一个加载器,在加载所有共享/ lib文件后启动特定于页面的代码。
这是我用它来建立与requirejs一个多页应用的样板
目录结构:
/src目录 - 我把所有的客户端的东西一个src目录里面,所以我可以运行该目录内的优化器(这是您的媒体目录)。
/src/vendor - 这里我放置所有第三方文件和插件,包括require.js。
/src/lib - 在这里,我放置了由整个应用程序或某些页面共享的所有自己的代码。换句话说,不是页面特定的模块。
/src/page-module-xx - 然后,我为每个页面创建一个目录。这不是一个严格的规定。
/src/main.js:这是整个应用程序的唯一主文件。它将:
- 配置RequireJS,包括垫片
- 负载共享库/模块
- 负载特定页面的主模块
这是一个requirejs.config呼叫的例子:
requirejs.config({
baseUrl: ".",
paths: {
// libraries path
"json": "vendor/json2",
"jquery": "vendor/jquery",
"somejqueryplugion": "vendor/jquery.somejqueryplufin",
"hogan": "vendor/hogan",
// require plugins
"templ": "vendor/require.hogan",
"text": "vendor/require.text"
},
// The shim section allows you to specify
// dependencies between non AMD compliant files.
// For example, "somejqueryplugin" must be loaded after "jquery".
// The 'exports' attribute tells RequireJS what global variable
// it must assign as the module value for each shim.
// For example: By using the configutation below for jquery,
// when you request the "jquery" module, RequireJS will
// give the value of global "$" (this value will be cached, so it is
// ok to modify/delete the global '$' after all plugins are loaded.
shim: {
"jquery": { exports: "$" },
"util": { exports: "_" },
"json": { exports: "JSON" },
"somejqueryplugin": { exports: "$", deps: ["jquery"] }
}
});
然后,配置完成后,我们可以做出第一个require()请求 为所有这些库,然后做我们的“页面主”模块的请求。
//libs
require([
"templ", //require plugins
"text",
"json", //3rd libraries
"jquery",
"hogan",
"lib/util" // app lib modules
],
function() {
var $ = require("jquery"),
// the start module is defined on the same script tag of data-main.
// example: <script data-main="main.js" data-start="pagemodule/main" src="vendor/require.js"/>
startModuleName = $("script[data-main][data-start]").attr("data-start");
if (startModuleName) {
require([startModuleName], function (startModule) {
$(function(){
var fn = $.isFunction(startModule) ? startModule : startModule.init;
if (fn) { fn(); }
});
});
}
});
正如您在上面require()的主体中看到的那样,我们期待require.js脚本标记的另一个属性。 data-start属性将保存当前页面的模块名称。
因此,在HTML页面上,我们必须增加这些额外的属性:
<script data-main="main" data-start="pagemodule/main" src="vendor/require.js"></script>
通过这样做,我们将结束与优化main.js一个包含“/供应商”和“所有文件/ lib“目录(共享资源),但不包括页面特定的脚本/模块,因为它们在main.js中没有作为依赖关系进行硬编码。页面特定模块将在应用程序的每个页面上分别加载。
“页面主”模块应返回function()
,将由上面的“应用程序主”执行。
define(function(require, exports, module) {
var util = require("lib/util");
return function() {
console.log("initializing page xyz module");
};
});
编辑
下面是例子,你如何使用的建造轮廓,以优化有一个以上的文件中的特定页面模块。
例如,假设我们有以下页面模块:
/page1/main.js
/page1/dep1.js
/page1/dep2.js
如果我们不优化这个模块,那么浏览器会发出3个请求,每个脚本都有一个请求。 我们可以通过指示r.js创建一个包并包含这3个文件来避免这种情况。
在建造轮廓的“模块”属性:
...
"modules": [
{
name: "main" // this is our main file
},
{
// create a module for page1/main and include in it
// all its dependencies (dep1, dep2...)
name: "page1/main",
// excluding any dependency that is already included on main module
// i.e. all our shared stuff, like jquery and plugins should not
// be included in this module again.
exclude: ["main"]
}
]
通过这样做,我们创建了具有所有依赖另一个单页主文件。但是,由于我们已经有一个主文件可以加载我们所有的共享内容,因此我们不需要再将它们包含在page1/main模块中。 该配置有点冗长,因为您必须为每个页面模块执行此操作,而您有多个脚本文件。
我上传了GitHub中的样板代码:https://github.com/mdezem/MultiPageAppBoilerplate。 这是一个正在运行的样板,只需为节点安装node和r.js模块并执行build.cmd(位于/ build目录中,否则将失败,因为它使用相对路径)
我希望我已经清楚。让我知道是否听起来有点奇怪;)
问候!
我有和简短的答案,但我需要一些细节:多少页?每个页面特定的代码很少或很多代码(比如,每个页面代码为10kb)? – devundef 2012-07-29 09:58:11
你使用的是requirejs插件,插件是什么? – devundef 2012-07-29 10:00:32
通常每个mainjs文件<10kb。我只是将它用于初始化jquery插件之类的东西。将会有很多页面......我会说20并且在不断增长。所以可能大约有15个mainjs文件和增长。我使用的插件是jquery插件,并使用define调用包装以符合AMD标准 – AndyPerlitch 2012-07-29 16:27:44