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

Posted

技术标签:

【中文标题】如何更改 Meteor 加载 Javascript 文件的顺序?【英文标题】:How do I change the order in which Meteor loads Javascript files? 【发布时间】:2012-05-28 10:01:24 【问题描述】:

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

假设,例如,我有 2 个 javascript 文件:foo.jsbar.js

文件bar.js 实际上包含依赖于foo.js 内部的代码,但Meteor 在foo.js 之前加载bar.js,从而破坏了项目。

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

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

【问题讨论】:

Meteor 现在按字母顺序加载内容,作为一个简单的 hack,您可以重命名文件以按字母顺序将其放在另一个文件之前/之后。我知道它缺乏优雅,但这是我知道影响加载顺序的唯一方法。 确实如此。我希望有另一种方法可以做到这一点。也许暴露一个类似browserify的包是一个解决方案:github.com/substack/node-browserify。如果他们想在他们的项目中使用,它将允许人们使用 node 的样式 require()。 【参考方案1】:

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

    首先加载 [project_root]/lib 中的文件 文件按目录深度排序。首先加载较深的文件。 文件按字母顺序排序。 main.* 文件最后加载。

来源: http://docs.meteor.com/#structuringyourapp

【讨论】:

谢谢,这个逻辑实际上比我预期的按字母顺序排序文件要好。应该足以管理依赖项。 @JérémyFaivre 是的,如果您使用 Meteor.startup(...) 您可以保证在开始使用之前所有内容都已加载并且 DOM 已准备就绪。玩得开心! 如果我使用外部脚本(如 Google)并且我的脚本依赖于它怎么办? @JordyMeow 你应该可以把它放在 lib/ 中 - 现在记录了排序逻辑 @docs.meteor.com/#structuringyourapp 用陨石安装的代码怎么样?它们什么时候加载?【参考方案2】:

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

【讨论】:

【参考方案3】:

您始终可以使用像 yepnope.js 这样的 JS 加载器并将其添加到 client.js 文件中。这对我有用。

【讨论】:

【参考方案4】:

我有一组实用函数,它们是在公共命名空间(js 全局)下构建的。

// utils/utils.js
Utils = ;

然后在子文件夹中:

// utils/validation/validation.js
Utils.Validation = ;

// utils/validation/creditCard.js
Utils.Validation.creditCard = ... // validation logic etc

我还有一堆使用 Utils 及其子对象的代码。

显然,这种结构不能像 Meteor 一样首先加载子文件夹。

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

这对我的口味来说非常违反直觉并且容易出错(假设您有文件夹结构更深的组件)。

为了解决这个问题,我使用了带有 defers 和 Promise 的 Q 库。解决方案仍然不干净,因为它使您例行代码重复和检查,但它使您可以完全控制加载顺序而不会弄乱目录结构(向那些说您可以根据需要组织流星代码的人打招呼)。

例子:

//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 加载 Javascript 文件的顺序?的主要内容,如果未能解决你的问题,请参考以下文章

在 Meteor (JavaScript) 中指定内容类型

如何在没有 Meteor 的情况下获得 Meteor 的路由/即时换页效果?

使用 Meteor 和 blaze 在掌上电脑上正确加载数据

加快 Meteor.js 中的自动重新加载

流星如何更新浏览器?

使用 appcache 在服务器上重新部署后 Meteor 不断重新加载