npm安装一个git子模块的依赖关系

问题描述 投票:6回答:2

我有一个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,只提到了grunt。

{
  "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,然后运行一个任务来初始化子模块,包括麻烦的handlebars.js。

我们的做法是 npm install 和安装grunt,和 grunt init 获取了包括它的 package.json. 所以我们问题的根源在于 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.

解决方案可能是

  1. 使用 npm link 傍大款 package.json 用脚本钩子做一些聪明的事情,在之后的 npm install 已经完成了。 这似乎是不可能的,因为handlebars.js/package.json 要到很久以后才会有。npm install 已完成。
  2. 把一个手动步骤放在run_grunt:handlebars_build 递进 src/handlebars.js 并运行npm install 在该目录中。 这似乎比我想象的要手动一些。
  3. 把一个步骤放在 run_grunt:handlebars_build 的依赖性,从 src/handlebars.js/package.json 到项目的顶层node_modules目录中,当在项目内部运行Gruntfile.js时,它可能会被拾取。src/handlebars.js (这可能需要在目录中没有node_modules目录。src/handlebars.js - 我对npm和node_modules的了解不是很好)。)
  4. 放弃将handlebars.js作为我们的项目构建的一部分,删除了 src/handlebars.js 子模块,而只是将构建的文件作为普通文件添加到它的位置。 这将是一个耻辱,因为你失去了通过git子模块方法智能地跟踪一个项目的版本的好处。

如果能得到一些关于最佳前进方式的建议,将不胜感激。

git gruntjs handlebars.js npm
2个回答
4
投票

这可能对像我在研究类似问题时偶然发现这个问题的人有一些帮助。

我的解决方案使用的是 grunt 插件 grunt-run 运转 npm install 的子模块目录下(将其依赖项安装到自己的 node_modules 目录:那将是 src/handlebars.js/node_modules/ 在你的情况下)。)

在我的例子中,我需要使用一个叫做 grunt 之后在子模块内的任务。我使用插件解决了这个问题 grunt-submodule.

>> Local Npm module "grunt-contrib-clean" not found. Is it installed?`

错误似乎会出现,如果 grunt 是在错误的工作目录下执行的--如果你之前已经成功安装了依赖关系。

例子:

只有子模块使用了 grunt-contrib-clean 来清理它的构建工件。你已经安装了子模块的需求(在其目录内),但你运行了 grunt clean 的父母目录中。node模块在这个地方是不知道的。

希望能帮到你。

马库斯


当然,这些任务是在 grunt融入到我的构建开发生命周期中。

参考文献。


0
投票

你可以在你的子模块中添加一个对主模块的依赖,然后在子模块中添加 npm install 也会安装子模块的依赖关系。

例如,如果你的子模块位于下面的 src/submodule

你应该跑 npm install --save file:src/common 它将把依赖关系添加到你的 package.json (也可以自己添加,只需将其追加到你的 dependencies 键的键值 "common": "file:src/common",

跑步 npm install 之后,将安装主模块和子模块中的所有依赖关系。

© www.soinside.com 2019 - 2024. All rights reserved.