简体   繁体   English

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

[英]How do I change the order in which Meteor loads Javascript files?

When you make a project with the Meteor framework, it packages all the files together, but there doesn't seem to be a way to explicitly say "I want this file to be loaded before that one". 当您使用Meteor框架创建项目时,它将所有文件打包在一起,但是似乎没有一种方法可以明确地说“我希望在该文件之前加载该文件”。

Let's say, for example, I have 2 javascript files: foo.js and bar.js . 例如,假设我有2个javascript文件: foo.jsbar.js

The file bar.js is actually containing code depending one the one inside foo.js but Meteor is loading bar.js before foo.js , breaking the project. bar.js文件实际上包含的代码与foo.js内部的代码foo.js但是Meteor正在bar.js之前加载foo.js ,这破坏了项目。

  • In node.js I would simply use require('./bar') inside foo.js node.js中,我只是在foo.js使用require('./bar')
  • In the browser , I would put a <script> tag pointing to foo.js and another, after, pointing to bar.js , in order to load the files in the correct order. 浏览器中,我会把一个<script>标签指向foo.js和另一个后,指着bar.js ,以加载正确的顺序文件。

How can we do that in Meteor ? 我们如何在流星中做到这一点?

According to the Meteor documentation, files are currently loaded in this order: 根据Meteor文档,当前按以下顺序加载文件:

  1. Files in [project_root]/lib are loaded first 首先加载[project_root] / lib中的文件
  2. Files are sorted by directory depth. 文件按目录深度排序。 Deeper files are loaded first. 首先加载更深的文件。
  3. Files are sorted in alphabetical order. 文件按字母顺序排序。
  4. main.* files are loaded last. main。*文件最后加载。

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

并非所有情况的解决方案,但我认为理想情况下,任何依赖于其他代码的内容都应放置在Meteor.startup函数中,以确保所有内容均已加载。

You can always us a JS loader like yepnope.js and add it to the client.js file. 您可以始终使用yepnope.js之类的JS加载器,并将其添加到client.js文件中。 This works for me. 这对我有用。

I have a set of utility functions that I structured under common namespace (js global). 我在通用名称空间(全局js)下构造了一组实用程序函数。

Ie

// utils/utils.js
Utils = {};

and then in subfolders: 然后在子文件夹中:

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

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

also I have bunch of code that uses Utils and it's subobjects. 我也有一堆使用Utils及其子对象的代码。

Obviously, this structure doesn't work as Meteor load subfolders first. 显然,此结构首先不能用作“流星”加载子文件夹。

To make it work as expected, I had to create /subfolder/subfolder/subfolder with meaningless names, and then shove root object in most deep subfolder, and branch objects in subfolders not so deep. 为了使其按预期工作,我必须使用无意义的名称创建/ subfolder / subfolder / subfolder,然后将根对象推入最深的子文件夹中,并将分支对象推入不那么深的子文件夹中。

It is extremely counterintuitive for my taste and error-prone (suppose you have component that is even deeper in folder structure). 这对于我的品味和容易出错的情况来说是非常违反直觉的(假设您的文件夹结构中的组件甚至更深)。

To address this issue, I used Q library with defers and promises. 为了解决这个问题,我使用了带有延迟和承诺的Q库。 Solution still isn't clean as it makes you routine code repeating and checks but it gives you full control over the load order without messing with directory structure (hello to people who says you can organise meteor code as you want). 解决方案仍然不是很干净,因为它使您可以重复执行例程代码并进行检查,但是它可以让您完全控制加载顺序,而不会弄乱目录结构(对那些说您可以根据需要组织流星代码的人问好)。

Example: 例:

//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   
    })
});

This is the example of rather narrow use case, as mostly you will be happy with handling these globals inside some user interaction callbacks or Meteor.startup where everything already initialised. 这是一个用例非常狭窄的示例,因为大多数情况下,您会满意于在某些已经初始化的用户交互回调或Meteor.startup中处理这些全局变量。 Otherwise, if you want fine-grained control over initialisation order on very early stage, that could be a solution. 否则,如果您想在早期阶段对初始化顺序进行细粒度的控制,那可能是一个解决方案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM