Grunt手表/ Bower链接:在开发凉亭组件时,最适合使用Grunt手表与Bower链接的方法是什么?

时间:2015-01-30 19:06:48

标签: gruntjs bower livereload grunt-contrib-watch

问题

我目前正在开发一个项目,我们有一个父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 install'时,子模块将安装到:

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'


这很好用。父母现在不必观看太多文件,现在由孩子自己观看并基本上通知家长。

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


其他潜在解决方案......

别人怎么处理这个?是否有一个被接受和广泛使用的模式来处理这个?

1 个答案:

答案 0 :(得分:0)

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

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

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

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

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

  5. 为了最大限度地减少父应用程序正在观看的文件数量,我们在所有bower组件中都使用了前缀,因此watch配置如下所示:

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

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