Jus*_*tin 28 javascript requirejs
我是RequireJS的新手,我遇到了一些问题.我使用RequireJS编写了一个基于Backbone构建的小框架,我希望它可以在不同的项目中重用.所以,通过一些搜索,我了解到需要允许包.这看起来像我在寻找.我有一个main.js文件来启动我的应用程序,基本上是这样的:
require.config({
packages: ['framework']
});
require(['framework'], function(framework) {
framework.createDash();
});
Run Code Online (Sandbox Code Playgroud)
然后在与我的main.js相同的目录中,我有另一个名为"framework"的目录,其中包含另一个main.js,如下所示:
define(function(require, exports, module) {
exports.createDash = function(dash, element) {
require(['dash/dash.model', 'dash/dash.view'], function(DashModel, DashView) {
return new DashView({
model: new DashModel(dash),
el: element ? element : window
});
});
};
});
Run Code Online (Sandbox Code Playgroud)
在搜索中我发现这个页面表明'require'参数应该作用于子模块.但是,当我尝试要求它们仍然相对于我原来的main.js. 我已经尝试了很多东西,并且搜索了几个小时无济于事.有没有什么方法可以让我的包中的require/define调用相对于它的root中的main.js包含?
小智 51
您需要在require配置中将子模块定义为包:
require.config({
packages: [
{ name: 'packagename',
location: 'path/to/your/package/root', // default 'packagename'
main: 'scriptfileToLoad' // default 'main'
}]
... some other stuff ...
});
Run Code Online (Sandbox Code Playgroud)
要加载模块,您只需要在要求中使用'packagename':
define(['jquery', 'packagename'], function($, MyPackage) {
MyPackage.useIt()
});
Run Code Online (Sandbox Code Playgroud)
在您的包中,您必须使用./前缀来加载相对于子模块的文件:
define(['globalDependency', './myLocalFile'], function(Asdf, LocalFile) {
LocalFile.finallyLoaded();
});
Run Code Online (Sandbox Code Playgroud)
有一个有用的快捷方式:如果您的包名称等于您的位置,而您的主文件名为'main.js',那么您可以替换它
packages: [
{ name: 'packagename',
location: 'packagename',
main: 'main'
}]
Run Code Online (Sandbox Code Playgroud)
对此:
packages: ['packagename']
Run Code Online (Sandbox Code Playgroud)
据我所知,你已经尝试定义一个包,但你是否也使用./前缀?如果没有此前缀,require将尝试在其全局根路径中查找文件.没有包,./将无用,因为相对路径与全局根路径相同.
干杯
我想出了我的问题的答案和解决方案(显然它们不一样).我想我会在这里发布,以防将来可以帮助其他人.
基本上我想要的是在自己的上下文中加载我的框架.我在require的网站上的配置部分下找到了context选项,以及如何使用它的示例.最初我通过做类似的事情来尝试这个:
var req = require.config({
baseUrl: 'framework',
context: 'framework',
paths: {
jQuery: 'lib/jquery/jquery-1.7.min.js',
Underscore: 'lib/underscore/underscore.min.js',
Backbone: 'lib/backbone/backbone.min.js',
etc...
}
});
req(['main'], function() {});
Run Code Online (Sandbox Code Playgroud)
这有两个问题.首先,我的'req'变量是在框架之外定义的,但我希望框架定义它自己的路径.其次,每当框架之外的文件需要在框架内的文件,这将反过来要求"jQuery的",例如,然后jQuery的(或任何其他)将不会从框架实例的范围内所需的需要,所以它找不到文件.
我最终做的是定义我的框架的main.js看起来像这样:
var paths = {
jQuery: 'lib/jquery/jquery-1.7.min.js',
Underscore: 'lib/underscore/underscore.min.js',
Backbone: 'lib/backbone/backbone.min.js',
etc...
};
define(function() {
var exports = {};
exports.initialize = function(baseUrl, overridePaths, callback) {
if(!overridePaths) {
overridePaths = {};
}
if(baseUrl && baseUrl[baseUrl.length - 1] != '/') {
baseUrl = baseUrl + '/';
}
var fullpaths = {};
for(var path in paths) {
// Don't add baseUrl to anything that looks like a full URL like 'http://...' or anything that begins with a forward slash
if(paths[path].match(/^(?:.*:\/\/|\/)/)) {
fullpaths[path] = paths[path];
}
else {
fullpaths[path] = baseUrl + paths[path];
}
}
var config = {paths: fullpaths};
for(var pathName in overridePaths) {
config.paths[pathName] = overridePaths[pathName];
}
require.config(config);
// Do anything else you need to do such as defining more functions for exports
if(callback) {
callback();
}
}
return exports;
});
Run Code Online (Sandbox Code Playgroud)
然后在我的项目的main.js文件中,我只是这样做:
require(['framework/main'], function(framework) {
// NOTE: This setTimeout() call is used because, for whatever reason, if you make
// a 'require' call in here or in the framework without it, it will just hang
// and never actually go fetch the files in the browser. There's probably a
// better way to handle this, but I don't know what it is.
setTimeout(function() {
framework.initialize('framework', null, function() {
// Do stuff here
}
}, 0);
});
Run Code Online (Sandbox Code Playgroud)
这需要无论是在传递给该框架的initialize()方法"基本URL",并预置,为这个框架定义了一个不以正斜杠或"什么://"开头的任何路径,除非他们是超越路径.这允许使用框架的包覆盖诸如'jQuery'之类的东西.