我想使用一个单独的域作为JavaScript框架,它将创建一个基本需求配置,我可以从应用程序中增加。
foo.example.com
main.js
lib/foo-specific.js
framework.example.com
framework.js <-- entry point
lib/jquery.js
lib/etc...
最理想的是,我希望能够要求'lib / foo-specific'和/或'lib / jquery'并且让路径很好地解决,但是从我发现的,没有办法做这个,除非我为框架中的每个js文件使用特定的路径键/值。目前,我有一个自定义插件,可以使用不同的基本URL(例如fw!lib/jquery
)加载给定路径,但如果我想使用text!
插件,它将无法正常工作插件链不受支持。
请参阅https://github.com/jpillora/js-framework了解我目前的情况,并https://github.com/jpillora/prettyprinter了解用例。
有没有一个干净的方法来解决这个问题?或者实现多个基本URL?
注意:我也查看了多个require实例,但我认为这不会起作用,因为我希望应用程序能够访问框架的配置。
答案 0 :(得分:35)
James Burke在RequireJS Github问题的页面上回答:Issue #447: Multiple Base URLs · jrburke/requirejs。
如果 data-main是脚本的唯一入口点(更多信息的评论),结果很简单,我用以下方法解决了我的特殊问题:
我的应用index.html
:
<script src="http://framework.jpillora.com/js/lib/require.js"
data-main="http://framework.jpillora.com/js/framework" > </script>
将requirejs入口点设置为framework.js
:
var framework = ... //set using script elements src attribute
require.config({
baseUrl: 'js/',
//Framework paths
paths: {
'framework': framework,
'lib' : framework + 'js/lib',
'ext' : framework + 'js/ext',
'util' : framework + 'js/util'
},
//Shortcuts
map: {
'*': {
...
}
},
//Non-modularised libraries with deps
shim: {
...
}
});
require(['main']);
因此,我们不是通常执行index.html->main.js
,而是添加一个额外的步骤index.html->framework.js->main.js
,它为应用程序代码提供了框架代码路径的知识。
例如,在应用http://prettyprint.jpillora.com/中,一旦需要加载framework.js
,它就会设置lib/...
到http://framework.jpillora.com/的路径并设置baseUrl
作为./js/
,因此只需要main
,就会将基本网址设置为自己的域名,并将lib
指向另一个域名。
哪个会产生require(['lib/foo', 'view/bar']);
解决:
http://framework.jpillora.com/js/lib/foo.js
和
http://prettyprint.jpillora.com/js/view/bar.js
如此处所示,该应用仅为main.js
其他所有内容均来自framework
:
最后,每当我使用上面的main.js
加载应用程序的framework.js
时,我就可以访问所有常用的库和实用程序类。请参阅应用来源。
另请注意,使用r.js
优化器和一个不错的本地文件结构,还可以将应用程序优化为单个js文件,仅提取framework
所需的内容。
答案 1 :(得分:9)
我在尝试设置测试环境时遇到了类似的问题。我有一个像这样的文件结构:
myApp/
src/
js/
app.js
data.js
lib/underscore.js
test/
karma.conf.js
test-main.js
matchers.js
spec/
data.js
这里有些棘手:我的应用脚本(app.js
和data.js
)假设一个RequireJS配置将data
解析为src/js/data.js
,{{1到lib/underscore
等,所以我也需要在我的测试环境中进行配置:
src/js/lib/underscore.js
现在我可以写我的测试了:
test/test-main.js
-----------------
require.config({
// Karma serves files under /base, which is the basePath from your config file
baseUrl: '/base/src/js',
// ...
});
使用一些自定义匹配器:
test/spec/data.js
-----------------
define(['data', '../../test/matchers'], function(dataModule) {
describe('The data module', function() {
it('should satisfy my custom matcher', function() {
expect(dataModule).toSatisfyMyCustomMatcher();
});
});
});
然而,test/matchers.js
----------------
define([], function() {
beforeEach(function() {
this.addMatchers({
toSatisfyMyCustomMatcher: function() {
return this.actual.isGood;
},
});
});
});
部分非常丑陋。通过了解其他模块的文件路径 - 这就是RequireJS的工作,不应该打扰测试规范。相反,我们想要使用符号名称。
RequireJS paths config也可以映射目录。
用于模块名称的路径不应包含扩展名,因为路径映射可以用于目录。
所以,解决方案是一个简单的路径配置:
'../../test/matchers'
现在我可以将test/test-main.js
-----------------
require.config({
baseUrl: '/base/src/js',
paths: {
test: '../../test',
},
// ...
});
目录称为test
的孩子:
baseUrl
在我的案例中,有效的方式与我可以有多个test/spec/data.js
-----------------
define(['data', 'test/matchers'], function(dataModule) {
// ...
});
几乎相同。
答案 2 :(得分:0)
了解我们如何处理BoilerplateJS中的路由和上下文,这是大规模产品开发的参考架构。我们使用库crossroads.js来路由模块和UI组件。所有要做的就是将路径/哈希添加到路由集中,它将通过框架进行路由。
作为example,UI组件的所有路径都会添加到URL控制器对象中。
对于在整个应用程序中访问框架配置信息,可以将配置/设置附加到可在应用程序内访问的全局上下文对象。
答案 3 :(得分:0)
尝试一下
context:赋予加载上下文的名称。只要每个顶级require调用都指定一个唯一的上下文字符串,这便允许require.js在页面中加载模块的多个版本。要正确使用它,请参阅“ Multiversion支持”部分。