Javascript 与RequireJS模块/包的相对路径

Javascript 与RequireJS模块/包的相对路径,javascript,requirejs,Javascript,Requirejs,我对RequireJS相当陌生,我遇到了一些问题。我已经使用RequireJS编写了一个基于主干网的小框架,我希望它在不同的项目中可以重用。因此,通过一些搜索,我了解到require允许包。这似乎是我要找的。我有一个main.js文件来启动我的应用程序,基本上如下所示: require.config({ packages: ['framework'] }); require(['framework'], function(framework) { framework.createDas

我对RequireJS相当陌生,我遇到了一些问题。我已经使用RequireJS编写了一个基于主干网的小框架,我希望它在不同的项目中可以重用。因此,通过一些搜索,我了解到require允许包。这似乎是我要找的。我有一个main.js文件来启动我的应用程序,基本上如下所示:

require.config({
  packages: ['framework']
});

require(['framework'], function(framework) {
  framework.createDash();
});
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
      });
    });
  };
});
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;
});
然后在与main.js相同的目录中,我有另一个名为“framework”的目录,其中包含另一个main.js,如下所示:

require.config({
  packages: ['framework']
});

require(['framework'], function(framework) {
  framework.createDash();
});
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
      });
    });
  };
});
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;
});

在搜索中,我找到了一个参数,它指示'require'参数的作用域应该是子模块。然而,当我试图要求一些东西时,它们仍然是相对于我原来的main.js的。我尝试了很多东西,搜索了几个小时都没有结果。有没有办法让我的包中的require/define调用相对于其根目录中的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
            });
        });
    };
});

我找到了问题的答案和解决方案(显然它们不一样)。我想我会把它贴在这里,以防将来它能帮助别人

本质上,我想要的是在自己的上下文中加载我的框架。我在on require的网站和一个。最初,我是这样做的:

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() {});
这有两个问题。首先,我的'req'变量是在框架之外定义的,但我希望框架定义它自己的路径。第二,当框架外的文件需要框架内的文件时,例如,框架内的文件需要“jQuery”,那么框架实例require的上下文中就不需要jQuery(或其他任何东西),因此它找不到该文件

我最后做的是定义框架的main.js,使其看起来像这样:

require.config({
  packages: ['framework']
});

require(['framework'], function(framework) {
  framework.createDash();
});
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
      });
    });
  };
});
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;
});
然后在我的项目的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);
});

这会将传递给框架的initialize()方法的任何内容作为“baseURL”的前缀,并将其添加到框架定义的任何不以正斜杠或“anything://”开头的路径,除非它们是重写路径。这允许使用框架的包覆盖诸如“jQuery”之类的内容。

您需要在require配置中将子模块定义为包:

require.config({
  packages: [
    { name: 'packagename',
      location: 'path/to/your/package/root',  // default 'packagename'
      main: 'scriptfileToLoad'                // default 'main' 
    }]
  ... some other stuff ...
});
要加载模块,您只需按照以下要求使用“packagename”:

define(['jquery', 'packagename'], function($, MyPackage) {
  MyPackage.useIt()
});
在软件包中,必须使用
/
前缀加载与子模块相关的文件:

define(['globalDependency', './myLocalFile'], function(Asdf, LocalFile) {
  LocalFile.finallyLoaded();
});

有一个有用的快捷方式:如果包名等于位置,并且主文件名为“main.js”,则可以替换此文件

  packages: [
    { name: 'packagename',
      location: 'packagename',
      main: 'main'
    }]
为此:

  packages: ['packagename']
据我所知,您已经尝试定义一个包,但是否也使用了./prefix?如果没有此前缀,require将尝试在其全局根路径中查找文件。如果没有包,
/
将毫无用处,因为相对路径与全局根路径相同



Cheers

对于我来说,允许直接从data main或外部框架使用包含子模块的包(假设main.js(或其他包main)由特定名称调用)的过程非常有效,它使用
var baseUrl=require.tour('packageName')+'/../'
作为
require.config的前缀({路径:{…}})
配置文件。例如:

var music21Base = require.toUrl('music21') + '/../';

require.config({ paths: {
                          'jquery': music21Base + 'ext/jquery/jquery.2.1.10.min';
                          'subModuleLoader': music21Base + 'src/subModuleLoader';
                         }  });

context:“xxx”
的设置对于调用带有
/modName
的普通模块非常有效,但对于我来说,
路径
参数不起作用。

感谢您的回答。“/”确实可以加载这两个组件,但我想我在解释问题时做得不好(主要是因为我认为我在发布时没有完全理解这个问题)。实际上,我的问题归结为,如何使用require.config()定义路径它可以在框架上下文中使用,也可以不在框架上下文中使用,但仍然包含同一个文件?对于我正在尝试做的事情,可能有更好的解决方案,但至少我现在有了一些工作。再次感谢!这是否仍然允许包单独调用require.config()并定义它自己的路径别名列表,只要别名引用的文件以“./”开头?我不想每次使用define()引用它们时都使用所有文件的完整相对路径.我已经重组了整个项目,但我仍然很好奇。我知道这个答案有点过时,但最近,即使没有包,你也可以安全地使用相对路径来要求模块。这不是很整洁,但它解决了我加载本地小程序的问题。谢谢!