ember.js - 在构建时写入公共(public)文件的 repo 插件会导致服务上的无限构建循环

标签 ember.js broccolijs

我在将我的 in-repo 插件写入 appDir/public 时遇到困难。我想做的是在每个构建中写出一个 JSON 文件,以包含在应用程序/dist 中。我遇到的问题是在运行“ember serve”时,文件观察器检测到新文件并再次重建,导致无限循环。

我已经尝试使用 preBuild() 和 postBuild() 钩子(Hook)编写 JSON 文件,保存到/public,但在构建之后,观察者检测到它并一遍又一遍地重建,每次都再次写入一个新文件。我也尝试使用 my-addon/public 文件夹并写入它,同样的事情。

唯一部分起作用的是在 init() 上编写,这很好,除了我没有看到使用 ember serve 的更改。

我确实尝试过使用 treeForPublic() 方法,但没有取得任何进展。我可以编写文件并使用 treeForPublic()。不过,这只在初始构建时运行一次。它部分解决了我的问题,因为我将文件放入 app dist 文件夹中。但我认为 ember serve 不会在应用程序中的后续文件更改时重新运行 treeForPublic。

有没有办法从文件监视中忽略特定文件?然而仍然允许文件包含到构建中?也许在 ember-cli-build 中有一个 exclude watch 属性?

这是我的 treeForPublic() ,但我猜我的问题不在这里:

treeForPublic: function() {
    const publicTree = this._super.treeForPublic.apply(this, arguments);
    const trees = [];
    if (publicTree) {
        trees.push(publicTree);
    }
    // this writes out the json
    this.saveSettingsFile(this.pubSettingsFile, this.settings);
    trees.push(new Funnel(this.addonPubDataPath, {
        include: [this.pubSettingsFileName],
        destDir: '/data'
    }));

    return mergeTrees(trees);
},

2019 年 5 月 20 日更新

此时我可能应该提出一个新问题......

我的目标是创建一个自动递增的内部版本号,在 ember build 和 ember serve 上更新。我在下面@real_ates 的回答下的评论有助于解释原因。最后,如果我只能在构建时使用它,那完全没问题。

@real_ate 的回答非常有帮助,解决了无限循环问题,但它不能在 ember serve 上运行。也许这只是无法完成,但我真的很想知道任何一种方式。我目前正在尝试更改环境变量而不是使用 treeforPublic()。我已经问过这个关于插件 config() 更新到 Ember 环境的单独问题: Updating Ember.js environment variables do not take effect using in-repo addon config() method on ember serve

我不知道是否可以将@real_ate 的答案标记为已接受的解决方案,因为它不适用于 ember serve。这是非常有帮助和教育!

最佳答案

这是一个很好的问题,人们在处理西兰花时常常会对这个问题感到困惑(我确信我过去曾被这个问题困扰过)

您遇到的问题是您的 treeForPublic() 实际上正在将文件写入源目录,然后您正在使用 broccoli-funnel 选择新的文件自定义文件并将其包含在构建中。执行此操作的正确方法是使用 broccoli-file-creator创建包含新文件的输出树。我将通过下面的示例进行更详细的介绍:

treeForPublic: function() {
  const publicTree = this._super.treeForPublic.apply(this, arguments);
  const trees = [];
  if (publicTree) {
    trees.push(publicTree);
  }

  let data = getSettingsData(this.settings);
  trees.push(writeFile('/data/the-settings-file.json', JSON.stringify(data)));

  return mergeTrees(trees);
}

正如您将看到的,大部分代码与您的示例完全相同。两个主要区别是,我们现在有一个函数 this.getSettingsData(),而不是将设置文件写到磁盘上的函数 this.saveSettingsFile()我们希望在新创建的文件中看到的内容。这是我们在测试时想出的简单示例:

function getSettingsData() {
  return {
    setting1: 'face',
    setting2: 'my',
  }
}

您可以编辑此函数以获取您需要的任何参数并具有您想要的任何功能。

下一个主要区别是我们使用的是 writeFile() 函数,它实际上只是 broccoli-file-creator 插件。这是您将放在文件顶部的导入:

let writeFile = require('broccoli-file-creator');

现在,当您运行您的应用程序时,它不会再写入源目录,这意味着它会停止不断重新加载 🎉


这个问题作为“我可以问一个问题”第 2 季第 2 集的一部分得到了回答。如果您想看到我们完整讨论这个答案,您可以在此处观看视频:https://youtu.be/9kMGMK9Ur4E

关于ember.js - 在构建时写入公共(public)文件的 repo 插件会导致服务上的无限构建循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55996762/

相关文章:

javascript - 随意命名 Ember.js 文件

ruby-on-rails-4 - Ember-cli 实现自定义序列化器

javascript - 测试 Ember 计算属性时创建相关对象的更好方法?

node.js - 错误 - 找不到模块 'broccoli'

javascript - 将 livereload 添加到西兰花

ember.js - 如何将 stripe.js 添加到 ember-cli 应用程序?

ember.js - 在 JavaScript 代码中应用 Handlebars 模板

javascript - 模型的更改不影响 View ember

javascript - ember 中的 helper 'andThen' 与传统的 'then' 有何不同