Centralise node_modules in project with subproject

泄露秘密 提交于 2019-12-02 17:38:56

This works out of the box. npm looks for node_modules in the current directory, and all its parent directories, then looks in the global location.

So you could even do this:

-Project
--subproject1
---node_modules
--subproject2
--subproject3
--node_modules

subproject1 will have access to all npms inside Project/subproject1/node_modules and Project/node_modules, while subproject2 and subproject3 will only find those inside Project/node_modules

Update

There is a very little documented feature called grunt collections. It requires a bit of a setup, but you won't need a copy of all your grunt plugins in each subproject.

Here's the file layout

-Project
--subproject1
---node_modules
----grunt-collection
-----package.json
--subproject2
...
--subproject3
...
--node_modules
---grunt
---grunt-contrib-concat
---grunt-contrib-jshint
---grunt-contrib-qunit
---grunt-contrib-watch
---grunt-html
---grunt-contrib-clean
---grunt-contrib-copy
---grunt-contrib-less
---grunt-contrib-uglify
---grunt-css
--package.json

Project/package.json

{
    "description": "subproject", 
    "version": "0.0.0",
    "name": "Lorem",
    "title": "Lorem Ipsum", 
    "devDependencies": {
        "grunt": "*",
        "grunt-contrib-watch": "~0.2.0", 
        "grunt-contrib-jshint": "~0.1.1", 
        "grunt-contrib-less": "~0.5.0", 
        "grunt-contrib-uglify": "~0.1.1", 
        "grunt-contrib-copy": "~0.4.0", 
        "grunt-contrib-qunit": "~0.1.1", 
        "grunt-css": "~0.5.4", 
        "grunt-contrib-clean": "~0.4.0", 
        "grunt-html": "~0.3.3", 
        "grunt-contrib-concat": "~0.1.3"
    }
}

Project/subproject1/package.json

{
    "description": "subproject", 
    "version": "0.0.0",
    "name": "Lorem",
    "title": "Lorem Ipsum", 
    "devDependencies": {
    }
}

Project/subproject1/Gruntfile.js excerpt (you only need the grunt-collection task).

grunt.loadNpmTasks('grunt-collection');
// grunt.loadNpmTasks('grunt-contrib-jshint');
// grunt.loadNpmTasks('grunt-html');
// grunt.loadNpmTasks('grunt-css');
// grunt.loadNpmTasks('grunt-contrib-less');
// grunt.loadNpmTasks('grunt-contrib-copy');

Project/subproject1/node_modules/grunt-collection/package.json

{
    "description": "subproject", 
    "version": "0.0.0",
    "name": "Lorem",
    "title": "Lorem Ipsum", 
    "dependencies": {
      "grunt-contrib-watch": "~0.2.0", 
      "grunt-contrib-jshint": "~0.1.1", 
      "grunt-contrib-less": "~0.5.0", 
      "grunt-contrib-uglify": "~0.1.1", 
      "grunt-contrib-copy": "~0.4.0", 
      "grunt-contrib-qunit": "~0.1.1", 
      "grunt-css": "~0.5.4", 
      "grunt-contrib-clean": "~0.4.0", 
      "grunt-html": "~0.3.3", 
      "grunt-contrib-concat": "~0.1.3"
    },
    "keywords": ["gruntcollection"]
}

The key is to create in each of your subproject, a small module with just a package.json which includes the keyword gruntcollection and includes the dependencies your Grunfile uses.

Grunt will then load these using the same strategy require uses, which means they can be found in the node_modules of your parent project.

Caveat: the way grunt collection works by using the dependency tag of package.json, this means you can not install it with npm install, but you should be able to store it source control.

psyrendust

I created a npm module load-grunt-parent-tasks to fix the issue. It was inspired by the answer that Pascal Belloncle gave and uses a gruntcollection hack.

All you need to do is require the module, pass it grunt and a config object and it will do the rest.

module.exports = function(grunt) {

  require('load-grunt-parent-tasks')(grunt, {
    config: 'package.json',
    pattern: 'grunt-*',
    scope: 'dependencies',
    module: 'grunt-collection'
  });

};

You can filter which grunt tasks you would like to load based on the globbing pattern you pass to pattern.

You can check out the module on Npm: https://www.npmjs.org/package/load-grunt-parent-tasks

Another solution, found in https://github.com/gruntjs/grunt/issues/696 module.exports = function (grunt) { grunt.file.expand('../node_modules/grunt-*/tasks').forEach(grunt.loadTasks); }

Following is a simple workaround. Change Gruntfile.js. module.exports = function (grunt) { var cwd = process.cwd(); process.chdir(cwd+'/../'); require('matchdep').filterDev('grunt-*').forEach(grunt.loadNpmTasks); process.chdir(cwd); }

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!