我有一个git项目,把handlebars.js作为一个子模块。我将在这里提供一个简单的例子 - 完整的项目更复杂,dojo任务和部署步骤在这里不相关。
$ mkdir handlebarstest ; cd handlebarstest ; git init
$ mkdir src ; git add src
$ git submodule add https://github.com/wycats/handlebars.js.git src/handlebars.js
我们的package.json
没有提到handlebars.js,只是咕噜声:
{
"name": "handlebarstest",
"version": "1.0.0",
"dependencies": {},
"devDependencies": {
"grunt": "~0.4.1",
"grunt-contrib-clean": "~0.4.1",
"grunt-run-grunt": "latest"
}
}
在这个项目的历史中,我们的安装和构建过程是:
$ npm install # install dependencies in package.json
$ grunt init # run the 'init' task which initialises git submodules
$ grunt build # run the 'build' task which compiles dojo etc.
对我们的项目进行了新的克隆,比如在我们的构建服务器上,git子模块需要初始化,我们从grunt控制它,所以我们必须先安装grunt,然后运行一个任务到init子模块,包括麻烦handlebars.js。
我们执行npm install
并安装grunt,并grunt init
获取包含其package.json
的handlebars.js。因此,我们问题的根源在于,当运行顶级package.json
时npm install
不可用。
我们的Gruntfile.js知道如何在handlebars.js中调用Gruntfile.js:
/*jshint node:true */
module.exports = function (grunt) {
/*jshint camelcase: false */
var path = require('path');
grunt.initConfig({
clean: [ 'dist' ],
run_grunt: {
options: {
},
handlebars_build: {
options: {
log: true
},
src: [ 'src/handlebars.js/Gruntfile.js' ],
task: 'build'
},
handlebars_amd: {
options: {
log: true
},
src: [ 'src/handlebars.js/Gruntfile.js' ],
task: 'amd'
}
}
});
// var handlebarsLink= grunt.registerTask('handlebarsLink', function () {
// var done = this.async(),
// child = grunt.util.spawn({
// cmd: 'npm',
// args: [ 'link', 'src/handlebars.js' ]
// }, function (error) {
// if (error) {
// grunt.warn(error);
// done(false);
// return;
// }
// done();
// });
// child.stdout.on('data', function (data) {
// grunt.log.write(data);
// });
// child.stderr.on('data', function (data) {
// grunt.log.error(data);
// });
// });
var submodules;
if (grunt.file.exists(__dirname, '.git')) {
submodules = grunt.registerTask('submodules', function () {
var done = this.async(),
child = grunt.util.spawn({
cmd: 'git',
args: [ 'submodule', 'update', '--init', '--recursive' ]
}, function (error) {
if (error) {
grunt.warn(error);
done(false);
return;
}
done();
});
child.stdout.on('data', function (data) {
grunt.log.write(data);
});
child.stderr.on('data', function (data) {
grunt.log.error(data);
});
});
}
var init = submodules ? [ 'submodules'/*, 'handlebarsLink'*/ ] : [];
grunt.registerTask('init', init);
grunt.registerTask('default', 'build');
grunt.registerTask('build', init.concat([ 'clean', 'run_grunt:handlebars_build', 'run_grunt:handlebars_amd' ]));
grunt.loadTasks(path.join(__dirname, 'grunt'));
grunt.loadTasks(path.join(__dirname, 'src', 'intern', 'tasks'));
grunt.loadNpmTasks('grunt-contrib-clean');
grunt.loadNpmTasks('grunt-run-grunt');
};
运行grunt失败,因为它会递归到handlebars.js,但其package.json中的模块依赖项尚未安装。
Running "run_grunt:handlebars_build" (run_grunt) task
--> starting "src/handlebars.js/Gruntfile.js"
--> reporting "src/handlebars.js/Gruntfile.js"
| >> Local Npm module "grunt-contrib-clean" not found. Is it installed?
| >> Local Npm module "grunt-contrib-concat" not found. Is it installed?
| >> Local Npm module "grunt-contrib-connect" not found. Is it installed?
| >> Local Npm module "grunt-contrib-copy" not found. Is it installed?
| >> Local Npm module "grunt-contrib-requirejs" not found. Is it installed?
| >> Local Npm module "grunt-contrib-jshint" not found. Is it installed?
| >> Local Npm module "grunt-contrib-uglify" not found. Is it installed?
| >> Local Npm module "grunt-contrib-watch" not found. Is it installed?
| >> Local Npm module "grunt-saucelabs" not found. Is it installed?
| >> Local Npm module "es6-module-packager" not found. Is it installed?
| Loading "metrics.js" tasks...ERROR
| >> Error: Cannot find module 'underscore'
| Loading "publish.js" tasks...ERROR
| >> Error: Cannot find module 'underscore'
| Loading "version.js" tasks...ERROR
| >> Error: Cannot find module 'async'
| Warning: Task "clean" not found. Use --force to continue.
|
| Aborted due to warnings.
|
--> failed "src/handlebars.js/Gruntfile.js" (304ms)
--> failed handlebars_build @ "src/handlebars.js/Gruntfile.js"
Warning: 1 gruntfile failed and completed 0 (308ms)
Use --force to continue.
解决方案可能是:
npm link
中以某种方式使用package.json
来做
在npm install
之后使用脚本钩子聪明的东西
完了。这似乎是不可能的,因为
handlebars.js/package.json
直到很好才会出现
npm install
完成后。run_grunt:handlebars_build
递归到src/handlebars.js
并运行
该目录中的npm install
。这似乎比我更手动
期待。run_grunt:handlebars_build
之前迈出一步
将src/handlebars.js/package.json
中的依赖项安装到
项目的顶级node_modules目录,可能是
在src/handlebars.js
内运行Gruntfile.js时拾取(这个
可能要求没有node_modules目录
src/handlebars.js
- 我对npm和node_modules的了解不是
大)。src/handlebars.js
子模块
项目,只需将构建的文件作为普通文件添加到其位置。这个
将是一个耻辱,因为你失去了追踪a的好处
项目的版本通过git子模块方法智能化。对于前进的最佳方式,我们将对一些建议表示赞赏。
答案 0 :(得分:4)
我的解决方案使用grunt
插件grunt-run
在子模块目录中运行npm install
(将其依赖项安装到自己的node_modules
目录中:这将是{{1}在你的情况下)。
在我的情况下,我需要在子模块中使用src/handlebars.js/node_modules/
任务编译TypeScript文件。我使用插件grunt
解决了这个问题。
grunt-submodule
如果在错误的工作目录中执行>> Local Npm module "grunt-contrib-clean" not found. Is it installed?`
,则似乎出现错误 - 如果您以前设法安装了依赖项。
示例:强>
只有子模块使用grunt
来清除其构建工件。您已经安装了子模块要求(在其目录中),但您在父目录中运行grunt-contrib-clean
。此处不知道节点模块。
希望有所帮助,
马库斯
这些任务当然是从grunt clean
内部运行,并集成到我的构建/开发生命周期中。
<强>参考文献:强>
答案 1 :(得分:1)
您可以将主模块上的依赖项添加到子模块中,然后npm install
也将安装子模块依赖项。
例如,如果您的子模块位于src/submodule
下
您应该运行npm install --save file:src/common
并将其添加到您的package.json
中(或者您可以自己添加,只需将{:1的key:value附加到您的dependencies
键上即可) }}
此后运行"common": "file:src/common",
,将在主模块和子模块中安装所有依赖项。