如何更改Meteor加载Javascript文件的顺序?

如何更改Meteor加载Javascript文件的顺序?,javascript,dependencies,meteor,require,Javascript,Dependencies,Meteor,Require,当您使用Meteor框架创建一个项目时,它会将所有文件打包在一起,但似乎没有一种方式明确地说“我希望在加载该文件之前加载该文件” 比如说,我有两个javascript文件:foo.js和bar.js 文件bar.js实际上包含的代码取决于foo.js中的代码,但是Meteor在foo.js之前加载了bar.js,破坏了项目 在node.js中,我只需在foo.js中使用require('./bar') 在浏览器中,我会放置一个指向foo.js的标记,然后再放置一个指向bar.js,以便按正确顺

当您使用Meteor框架创建一个项目时,它会将所有文件打包在一起,但似乎没有一种方式明确地说“我希望在加载该文件之前加载该文件”

比如说,我有两个javascript文件:
foo.js
bar.js

文件
bar.js
实际上包含的代码取决于
foo.js
中的代码,但是Meteor在
foo.js
之前加载了
bar.js
,破坏了项目

  • node.js中,我只需在
    foo.js中使用
    require('./bar')
  • 浏览器中,我会放置一个指向
    foo.js
    标记,然后再放置一个指向
    bar.js
    ,以便按正确顺序加载文件

我们如何在Meteor中做到这一点?

并不是所有场景的解决方案,但我认为理想情况下,依赖于其他代码的任何东西都将放在Meteor.startup函数中,以确保所有东西都已加载。

根据Meteor文档,文件当前按以下顺序加载:

  • 首先加载[project\u root]/lib中的文件
  • 文件按目录深度排序。首先加载更深层次的文件
  • 文件按字母顺序排序
  • main.*文件最后加载
  • 资料来源:

    您可以使用类似的JS加载程序,并将其添加到client.JS文件中。这对我来说很有用。

    我有一组在公共名称空间(js global)下构造的实用函数

    然后在子文件夹中:

    // utils/validation/validation.js
    Utils.Validation = {};
    
    // utils/validation/creditCard.js
    Utils.Validation.creditCard = ... // validation logic etc
    
    我还有一堆使用UTIL及其子对象的代码

    显然,此结构首先不能用作Meteor加载子文件夹

    为了使其按预期工作,我必须创建具有无意义名称的/subfolder/subfolder/subfolder,然后将根对象推到最深的子文件夹中,并将子文件夹中的对象分支到不太深的子文件夹中

    对于我的口味和错误倾向来说,这是非常违反直觉的(假设您有一个在文件夹结构中更深的组件)

    为了解决这个问题,我使用了带有延迟和承诺的Q库。解决方案仍然不干净,因为它会让您重复执行常规代码并进行检查,但它可以让您完全控制加载顺序,而不会影响目录结构(您好,有人说您可以根据需要组织meteor代码)

    例如:

    //utils.js
    UtilsDefer = UtilsDefer || Q.defer();
    UtilsDefer.resolve({
        // here some root utils stuff
    });
    
    //cards.js
    // here we'll depend on Utils but don't want to care about directory structure
    UtilsDefer = UtilsDefer || Q.defer(); // it will be a) already 
    // resolved defer from utils.js, or b) new defer that will
    // be resolved later in utils.js
    UtilsDefer.then(function(Utils) {
        // do something with utils usage, or for instance add some fields here
        Utils.CreditCardDefer = Utils.CreditCardDefer || Q.defer();
        Utils.CreditCardDefer.resolve({
            // Credit card utils here
        })
    });
    
    //someOtherFile.js
    // it will be pain to use sub-objects with this method though:
    UtilsDefer = UtilsDefer || Q.defer();
    UtilsDefer.then(function(Utils) {
        Utils.CreditCardDefer = Utils.CreditCardDefer || Q.defer();
        Utils.CreditCardDefer.then(function(CreditCard) {
            // do stuff with CreditCard _if_ you need to do it on startup stage   
        })
    });
    

    这是一个非常狭隘的用例示例,因为在一些用户交互回调或Meteor.startup中处理这些全局调用时,大多数情况下您都会感到高兴,因为所有这些调用都已经初始化。否则,如果您希望在很早的阶段就对初始化顺序进行细粒度控制,这可能是一个解决方案。

    Meteor现在按字母顺序加载内容,作为一个简单的黑客,您可以重命名一个文件,将其按字母顺序放在另一个文件之前/之后。我知道它缺乏优雅,但这是我所知道的影响加载顺序的唯一方法。我希望有另一种方法可以做到这一点。也许公开类似browserify的包将是一个解决方案:。它允许人们在项目中使用node的样式require()。谢谢,这种逻辑实际上比我预期的按字母顺序排序文件要好。应该足以管理依赖关系。@JérémyFaivre是的,如果您使用Meteor.startup(…),您可以保证在开始使用它之前已经加载了所有内容,并且DOM已经准备就绪。玩得高兴如果我使用一个外部脚本(比如谷歌),而我的脚本依赖于它,那该怎么办?@jordymow你应该能够将它放在lib/中-排序逻辑现在被记录下来了@meteorite安装的代码呢?他们什么时候上船?
    //utils.js
    UtilsDefer = UtilsDefer || Q.defer();
    UtilsDefer.resolve({
        // here some root utils stuff
    });
    
    //cards.js
    // here we'll depend on Utils but don't want to care about directory structure
    UtilsDefer = UtilsDefer || Q.defer(); // it will be a) already 
    // resolved defer from utils.js, or b) new defer that will
    // be resolved later in utils.js
    UtilsDefer.then(function(Utils) {
        // do something with utils usage, or for instance add some fields here
        Utils.CreditCardDefer = Utils.CreditCardDefer || Q.defer();
        Utils.CreditCardDefer.resolve({
            // Credit card utils here
        })
    });
    
    //someOtherFile.js
    // it will be pain to use sub-objects with this method though:
    UtilsDefer = UtilsDefer || Q.defer();
    UtilsDefer.then(function(Utils) {
        Utils.CreditCardDefer = Utils.CreditCardDefer || Q.defer();
        Utils.CreditCardDefer.then(function(CreditCard) {
            // do stuff with CreditCard _if_ you need to do it on startup stage   
        })
    });