Gruntjs Grunt watch/Bower link:在开发Bower组件时,使用Grunt watch和Bower link的最合适方式是什么? 问题

Gruntjs Grunt watch/Bower link:在开发Bower组件时,使用Grunt watch和Bower link的最合适方式是什么? 问题,gruntjs,bower,livereload,grunt-contrib-watch,Gruntjs,Bower,Livereload,Grunt Contrib Watch,我目前正在从事一个项目,在这个项目中,我们有一个父web应用程序(碰巧是AngularJS应用程序)和多个子Bower模块(包含Javascript、SASS、图像等),它们包含在使用Bower的父web应用程序中 例如,父级bower.json如下所示: { "name": "parent-app", "version": "1.0.0", "dependencies": { "child-1-module": "1.0.0", "chi

我目前正在从事一个项目,在这个项目中,我们有一个父web应用程序(碰巧是AngularJS应用程序)和多个子Bower模块(包含Javascript、SASS、图像等),它们包含在使用Bower的父web应用程序中

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

{
    "name": "parent-app",
    "version": "1.0.0",
    "dependencies": {
        "child-1-module": "1.0.0",
        "child-2-module": "1.0.0"
    }
}
watch: {
    bower_components: {
        files: ['./bower_components/orgname-*/dist/*.js'],
        tasks: ['newer:copy']
    }
}
在父模块上执行“bower安装”时,子模块将安装到:

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


然后,我们对每个子模块使用“bower链接”

然后在父节点上“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_组件添加到父级中的grunt watch 因此,我可以修改Grunfile,以便另外查看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:打开的文件太多”问题而无法运行(请参阅)

此外,子模块是动态添加的,因此我们不能在GrunFile中预先指定特定的子模块,例如:

'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());
    }
});

这样行。父级现在不必监视太多文件,现在由子级自己执行监视并基本上通知父级

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


其他可能的解决方案。。。
其他人是如何处理这件事的?是否有一种被广泛接受的模式来处理此问题?

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

  • 开发人员在处理子组件时,会设置从子组件到父应用程序的bower链接

  • 他打开两个终端窗口。一个在子系统上运行
    grunt-watch
    任务,另一个在父系统上运行
    grunt-watch
    任务

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

  • 父组件正在监视
    /dist
    文件夹中的更改,当子组件中的构建任务完成时,它将触发其任务以在父应用程序中构建

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

    {
        "name": "parent-app",
        "version": "1.0.0",
        "dependencies": {
            "child-1-module": "1.0.0",
            "child-2-module": "1.0.0"
        }
    }
    
    watch: {
        bower_components: {
            files: ['./bower_components/orgname-*/dist/*.js'],
            tasks: ['newer:copy']
        }
    }
    
    我不知道这是否是公认的“最佳实践”,但它确实有效