【发布时间】: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