javascript RequireJS:有没有办法实现多个基本 URL?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12302440/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
RequireJS: Is there a way to achieve multiple base URLs?
提问by jpillora
I want to use a separate domain as a JavaScript framework and it will create a base require config which I can augment from the app.
我想使用一个单独的域作为 JavaScript 框架,它将创建一个基本的 require 配置,我可以从应用程序中扩充它。
foo.example.com
main.js
lib/foo-specific.js
framework.example.com
framework.js <-- entry point
lib/jquery.js
lib/etc...
Optimally, I'd like to be able to require 'lib/foo-specific' and/or 'lib/jquery' and have the paths just resolve nicely, but from what I've found, there's no way to do this, unless I use a specific path key/value for every js file in the framework. At the moment, I've got a custom plugin to load the given path with a different base url (e.g. fw!lib/jquery
), though if I wanted to use the text!
plugin, it won't work as plugin chaining is unsupported.
最佳情况下,我希望能够要求 'lib/foo-specific' 和/或 'lib/jquery' 并且路径可以很好地解析,但从我发现的情况来看,没有办法做到这一点,除非我为框架中的每个 js 文件使用特定的路径键/值。目前,我有一个自定义插件可以使用不同的基本 url(例如fw!lib/jquery
)加载给定的路径,但是如果我想使用该text!
插件,它将无法工作,因为不支持插件链。
See https://github.com/jpillora/js-frameworkfor what I've currently got, and also https://github.com/jpillora/prettyprinterfor a use case.
请参阅https://github.com/jpillora/js-framework了解我目前拥有的内容,以及https://github.com/jpillora/prettyprinter的用例。
Is there a clean way to solve this ? or to achieve multiple base URLs ?
有没有干净的方法来解决这个问题?或实现多个基本网址?
Note: I have also looked into multiple require instances, though I don't think that would work as I'd like the the app to be able to access the framework's config.
注意:我还研究了多个 require 实例,但我认为这不会起作用,因为我希望应用程序能够访问框架的配置。
采纳答案by jpillora
Answered by James Burke on RequireJS Github Issue's page: Issue #447: Multiple Base URLs · jrburke/requirejs.
James Burke 在 RequireJS Github 问题页面上回答:问题 #447:多个基本 URL · jrburke/requirejs。
Turns out to be quite simple if data-main is the only entry point to your scripts(comments for more info), I solved my particular problem with the following:
如果data-main 是脚本的唯一入口点(更多信息的评论),结果会非常简单,我用以下方法解决了我的特定问题:
My app's index.html
:
我的应用程序index.html
:
<script src="http://framework.jpillora.com/js/lib/require.js"
data-main="http://framework.jpillora.com/js/framework" > </script>
has the requirejs entry point set to framework.js
:
将 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']);
So instead of normally doing index.html->main.js
, we're adding an extra step index.html->framework.js->main.js
, which gives the app code knowledge of paths to the framework code.
因此index.html->main.js
,我们不是通常这样做,而是添加了一个额外的步骤index.html->framework.js->main.js
,它为应用程序代码提供了框架代码路径的知识。
For example, in the app http://prettyprint.jpillora.com/, once require has loaded framework.js
, it will setup paths to lib/...
which to http://framework.jpillora.com/and set the baseUrl
as ./js/
so once main
is required, it will have the base url set to it's own domain and lib
pointing to another domain.
例如,在应用程序http://prettyprint.jpillora.com/ 中,一旦 require 已加载framework.js
,它将设置lib/...
到http://framework.jpillora.com/ 的路径并将其设置baseUrl
为./js/
一旦main
需要,它将将基本 url 设置为它自己的域并lib
指向另一个域。
Which results in require(['lib/foo', 'view/bar']);
resolving to:
这导致require(['lib/foo', 'view/bar']);
解决:
http://framework.jpillora.com/js/lib/foo.js
and
http://prettyprint.jpillora.com/js/view/bar.js
http://framework.jpillora.com/js/lib/foo.js
和
http://prettyprint.jpillora.com/js/view/bar.js
As displayed here, the app is only a main.js
everything else comes from the framework
:
如此处所示,该应用程序只是main.js
其他所有内容均来自framework
:
So finally, whenever I load an app's main.js
via with the above framework.js
, I then have access to all of my commonly used libraries and utility classes. See app source.
所以最后,每当我main.js
用上面的方法加载应用程序的via 时framework.js
,我就可以访问我所有常用的库和实用程序类。查看应用程序源。
Also note, with the r.js
optimiser and a nice local file structure, one can also optimise the app into a single js file pulling only what's required from framework
.
另请注意,借助r.js
优化器和良好的本地文件结构,您还可以将应用程序优化为单个 js 文件,仅从 .js 文件中提取所需的内容framework
。
回答by Emil Lundberg
The problem
问题
I had a similar problem while trying to set up a testing environment. I had a file structure like this:
我在尝试设置测试环境时遇到了类似的问题。我有一个这样的文件结构:
myApp/
src/
js/
app.js
data.js
lib/underscore.js
test/
karma.conf.js
test-main.js
matchers.js
spec/
data.js
Here's where it gets tricky: my app scripts (app.js
and data.js
) assume a RequireJS configuration that resolves data
to src/js/data.js
, lib/underscore
to src/js/lib/underscore.js
etc, so I need that configuration in my test environment as well:
这里的地方变得棘手:我的应用程序的脚本(app.js
和data.js
)承担RequireJS配置解析data
到src/js/data.js
,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',
// ...
});
Now I can write my tests:
现在我可以编写我的测试:
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();
});
});
});
With some custom matchers:
使用一些自定义匹配器:
test/matchers.js
----------------
define([], function() {
beforeEach(function() {
this.addMatchers({
toSatisfyMyCustomMatcher: function() {
return this.actual.isGood;
},
});
});
});
However, that '../../test/matchers'
part is horrendously ugly. The test specifications shouldn't be bothered with knowing file paths to other modules - that's RequireJS's job. Instead we want to use symbolic names.
然而,那'../../test/matchers'
部分非常丑陋。测试规范不应该为知道其他模块的文件路径而烦恼——这是 RequireJS 的工作。相反,我们想使用符号名称。
The solution
解决方案
The RequireJS paths configcan also map directories.
RequireJS路径配置也可以映射目录。
The path that is used for a module name should not include an extension, since the path mapping could be for a directory.
用于模块名称的路径不应包含扩展名,因为路径映射可能用于目录。
So, the solution is a simple path config:
因此,解决方案是一个简单的路径配置:
test/test-main.js
-----------------
require.config({
baseUrl: '/base/src/js',
paths: {
test: '../../test',
},
// ...
});
Now I can refer to the test
directory as if it were a child of the baseUrl
:
现在我可以参考该test
目录,就好像它是以下目录的子项一样baseUrl
:
test/spec/data.js
-----------------
define(['data', 'test/matchers'], function(dataModule) {
// ...
});
Which in my case effectively comes out pretty much the same as if I could have multiple baseUrl
s.
在我的情况下,这实际上与我可以有多个baseUrl
s几乎相同。
回答by ???? ????? ???? ??????
TRY this
试试这个
context: A name to give to a loading context. This allows require.js to load multiple versions of modules in a page, as long as each top-level require call specifies a unique context string. To use it correctly, see the Multiversion Support section.
上下文:赋予加载上下文的名称。这允许 require.js 在页面中加载多个版本的模块,只要每个顶级 require 调用指定一个唯一的上下文字符串。要正确使用它,请参阅多版本支持部分。
回答by Himeshi
Have a look at how we have handled routing and the context in BoilerplateJSwhich is a reference architecture for large-scale product development. We have used the library crossroads.jsto route modules and UI components. All there is to do is add the path/hash to the set of routes and it will be routed through the framework.
看看我们是如何处理路由和BoilerplateJS中的上下文的,BoilerplateJS是用于大规模产品开发的参考架构。我们使用了crossroads.js库来路由模块和 UI 组件。所要做的就是将路径/哈希添加到路由集中,它将通过框架进行路由。
As an exampleall the paths of the UI components are added to the URL controller object.
作为一个示例UI组件的所有路径被添加到URL控制器对象。
As for accessing the framework configuration information throughout the application, configurations/settings can be attached to the global-context object which can be accessed inside the application.
至于在整个应用程序中访问框架配置信息,可以将配置/设置附加到可以在应用程序内部访问的全局上下文对象。