Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Centralise node_modules in project with subproject

is it possible to configure grunt in a way that you have the required modules on a central point?

I have following project structure

-Project
-- subproject
-- subproject
-- subproject

I build the project via grunt with all subprojects, and I can build each subproject for itself too. Currently I have a Gruntfile.js, package.json & folder node_modules (~50mb) with all required modules in each subproject and on the root level.

So is it possible to have the node_modules folder only on one level, for e.g. on the root level and the subprojects refer to the node_modules on root level?

-Project
--subproject
--subproject
--subproject
--node_modules

Is there a way to reference the node_module folder via package.json or anything else?

Edit:

Gruntfile.js (subproject level)

/*global module:false */
/*jshint node:true */

module.exports = function(grunt) {

    "use strict";

    // ================================================================================
    // project configuration
    // ================================================================================
    grunt.initConfig({
        pkg : grunt.file.readJSON('package.json'),
        jshint: {
            globals : {
                d3:true,
                Modernizr:true,
                tempo:true
            },
            options: grunt.file.readJSON('.jshintrc')
        },
        csslint: {
            subproject: {
                src: 'css/**/*.css'
            }
        },
        htmllint : {
            subproject: {
                src: 'html/**/*.html'
            }
        },
        clean : [ 'output' ],
        less : {
            options: {
                paths: ['./']
            },
            src: {
                expand: true,
                cwd:    'css/',
                src:    ['**/*.less'],
                dest:   'css/',
                ext:    '.css'
            }
        },
        copy: {
            subproject: {
                files: [
                    {src: ['img/**', 'js/**', 'folderX/**','!**/*.less'], dest: 'output/subproject/'}
                ]
            }
        }
    });

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

    // ================================================================================
    // default task
    // ================================================================================
    grunt.registerTask('default', ['clean', 'less', 'csslint', 'htmllint', 'copy']);
};

package.json (subproejct level)

{
    "description": "subproject", 
    "title": "Lorem Ipsum", 
    "devDependencies": {
        "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"
    }
}

BR, mybecks

like image 258
mybecks Avatar asked Mar 05 '13 14:03

mybecks


People also ask

Can I copy node_modules folder to another project?

Yes you can copy whole node_modules (have done it multiple times) from one project to another and use same package.

Can I delete node_modules and reinstall?

You could remove your node_modules/ folder and then reinstall the dependencies from package. json. This would erase all installed packages in the current folder and only install the dependencies from package.

What happens if I delete node_modules?

Anybody can suggest if I delete node_modules folder and after re-creating it, will I get all the already installed packages back in the same way they were just before deleting? YES, you will get back all the packages listed in your package. json file.


2 Answers

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.

like image 168
Pascal Belloncle Avatar answered Oct 01 '22 02:10

Pascal Belloncle


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

like image 40
psyrendust Avatar answered Oct 01 '22 00:10

psyrendust