npm安装git子模块的依赖项

Nee*_*eek 5 git npm handlebars.js gruntjs

我有一个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
Run Code Online (Sandbox Code Playgroud)

我们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"
  }
}
Run Code Online (Sandbox Code Playgroud)

在这个项目的历史中,我们的安装和构建过程是:

$ 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.
Run Code Online (Sandbox Code Playgroud)

完成了我们项目的新克隆,比如在我们的构建服务器上,git子模块需要初始化,我们从grunt控制它,所以我们必须先安装grunt,然后运行一个任务到init子模块,包括麻烦的把手.js .

我们做npm install并安装grunt,并grunt init获取包括它的handlebars.js 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');
};
Run Code Online (Sandbox Code Playgroud)

运行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.
Run Code Online (Sandbox Code Playgroud)

解决方案可能是:

  1. npm link在我们的顶层使用以某种方式在完成package.json后使用脚本钩子做一些聪明的事情npm install.这似乎是不可能的,因为 handlebars.js/package.json直到npm install完成后才能使用.
  2. run_grunt:handlebars_build进入该目录src/handlebars.jsnpm 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子模块方法智能地跟踪项目版本的好处.

一些建议将在最佳前进方向上受到赞赏.

Yar*_*arh 10

为确保在安装主存储库的依赖项时安装子模块的依赖项,您需要修改主 package.json。

假设你的子模块被称为“common”并且位于src/common它的 package.json 中src/common,那么,

您应该运行npm install --save file:src/common,它会将依赖项添加到您的package.json(或者您可以自己添加,只需将dependencieskey:value of"common": "file:src/common",

npm install之后运行,将安装主模块和子模块中的所有依赖项。

这些步骤也将有助于解决持续部署环境中的问题。

  • 这个答案是更有用的答案,应该是公认的答案 (8认同)

bvf*_*nbk 5

这可能对像我在研究类似问题时那样绊倒这个问题的人有所帮助:

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

在我的情况下,我需要使用grunt子模块内的任务编译 TypeScript 文件。我使用插件解决了这个问题grunt-submodule

>> Local Npm module "grunt-contrib-clean" not found. Is it installed?`
Run Code Online (Sandbox Code Playgroud)

如果grunt在错误的工作目录中执行,似乎会出现错误 - 如果您之前设法安装了依赖项。

例子:

只有子模块用于grunt-contrib-clean清理其构建工件。您已经安装了子模块要求(在其目录中),但您grunt clean在父目录中运行。这个地方不知道节点模块。

希望有所帮助,

马库斯


这些任务当然是从内部运行的grunt,并集成到我的构建/开发生命周期中。

参考: