【问题标题】:Grunt watch/Bower link: What is the most appropriate way to use Grunt watch with Bower link when developing a bower component?Grunt watch/Bower 链接:在开发 bower 组件时,使用带有 Bower 链接的 Grunt watch 最合适的方式是什么?
【发布时间】:2015-01-30 19:06:48
【问题描述】:

问题

我目前正在开发一个项目,其中我们有一个父 Web 应用程序(恰好是一个 AngularJS 应用程序)和多个子 Bower 模块(包含 Javascript、SASS、图像等),这些子模块使用 Bower 包含在父级中.

例如,父 bower.json 如下所示:

{
    "name": "parent-app",
    "version": "1.0.0",
    "dependencies": {
        "child-1-module": "1.0.0",
        "child-2-module": "1.0.0"
    }
}

在父模块上执行“凉亭安装”时,子模块将安装到:

bower_components/child-1-module
bower_components/child-2-module



然后我们为每个子模块使用“bower link”。

然后在父节点上'bower link child-1-module'和'bower link child-2-module'创建本地软链接如:

bower_components/child-1-module -> /some/where/else/child-1-module
bower_components/child-2-module -> /some/where/else/child-2-module

这允许我们在本地对各个子模块进行更改,并在父应用中查看结果。


然后,我们还使用 Grunt 和父级中的 grunt-contrib-watch 来监视父级应用程序的更改,然后执行其他 Grunt 任务,或者执行“livereload”以刷新用于查看应用程序的浏览器。

下面是一个精简的 Gruntfile.js 示例,它监视 .js 文件,然后执行“jshint”任务和“livereload”:

grunt.initConfig({

    // Watches files for changes and runs tasks based on the changed files
    watch: {
        js: {
            files: [
                'scripts/{,*/}*.js', 
            ],
            tasks: ['newer:jshint:all'],
            options: {
                livereload: true
            }
        }
    }
}


这适用于查看父应用程序的更改,但我们也想知道子模块中的文件何时更改。目前我已经想到/研究了许多解决方案,但结果好坏参半。


潜在解决方案 1:将 bower_components 添加到父级中的 grunt watch

所以我可以只修改 Gruntfile 以另外查看 bower_components 文件夹中的 .js 文件,如下所示:

grunt.initConfig({

    // Watches files for changes and runs tasks based on the changed files
    watch: {
        js: {
            files: [
                'scripts/**/*.js', 
                'bower_components/**/*.js'
            ],
            tasks: ['newer:jshint:all'],
            options: {
                livereload: true
            }
        }
    }
}


然而,可能有许多子模块(包含许多 .js 文件),因此性能会受到很大影响,并且由于“EMFILE:打开的文件过多”问题(请参阅here)而常常甚至无法运行。

另外,子模块是动态添加的,所以我们不能在 Gruntfile 中只指定特定的,例如:

'bower_components/child-1-module/**/*.js'


潜在解决方案 2:在子模块和父模块中添加 grunt watch

我们可以改为在每个包含监视的子模块中添加 Gruntfile.js 来监视自己的文件。

当子模块中的文件发生更改时,我们可以更新特定的 'livereload' 文件,然后在父模块中我们可以只监视那些特定的文件。

child-module-1 中的示例“Gruntfile.js”

grunt.initConfig({
    watch: {
        js: {
            files: ['scripts/**/*.js'],
            tasks: ['livereloadEvent:js', 'newer:jshint:all']
        }
    }
}
grunt.registerTask('livereloadEvent', function() {
    // create a 'livereload/livereload.{arg}' file for the event specified
    grunt.file.mkdir('livereload');
    for(var i = 0; i < this.args.length; i++) {
        // contents of the file is the current timestamp
        grunt.file.write('livereload/livereload.'+ this.args[i], new Date());
    }
});


然后在父级中我们可以将以下文件夹添加到我们的手表中:

'bower_components/**/livereload/livereload.js'


这工作正常。父母现在不必观看太多文件,现在由孩子自己观看并基本上通知父母。

缺点是每个孩子都必须意识到这一点并以相同的方式实施。


其他可能的解决方案...

其他人是如何处理这个问题的?是否有一种公认且广泛使用的模式来处理这个问题?

【问题讨论】:

    标签: gruntjs bower livereload grunt-contrib-watch


    【解决方案1】:

    我们处理此问题的方式与您提出的解决方案 2 非常相似。

    1. 当开发人员在开发子组件时,他会设置从子组件到父 Angular 应用程序的 bower 链接。

    2. 他打开了两个终端窗口。一个在子节点上运行 grunt watch 任务,另一个在父节点上运行 grunt watch 任务。

    3. 当他对子组件进行更改时,它会触发 grunt 任务将文件的串联版本构建到组件的 /dist 文件夹中。

    4. 父级正在观察/dist文件夹的变化,当子组件中的构建任务完成时,它会触发其任务在父应用中构建。

    为了尽量减少父应用正在监视的文件数量,我们在所有 bower 组件中使用前缀,因此 watch 配置如下所示:

    watch: {
        bower_components: {
            files: ['./bower_components/orgname-*/dist/*.js'],
            tasks: ['newer:copy']
        }
    }
    

    我不知道这是否是公认的“最佳做法”,但它确实有效。

    【讨论】:

      猜你喜欢
      • 2014-02-04
      • 1970-01-01
      • 2016-05-11
      • 2014-11-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-15
      • 1970-01-01
      相关资源
      最近更新 更多