實現 node_modules 共享

Gruntjs 做爲前端工程化工具,可以很好的對前端資源進行管理(校驗,合併,壓縮)。前端

久之,發現一個問題node

npm install

每次不一樣的項目都必須使用以上命令初始化,獲取相對應的依賴模塊,而這些模塊每每都是類似。linux

那麼,可否多個項目共用同個 node_modules ,作到一處管理,多處複用呢?npm

咱們嘗試一下:json

咱們事先初始化一個 node_modules 目錄,包含 grunt 等衆多精彩使用到的模塊segmentfault

node_modules

接着,咱們分析一下 grunt 模塊下的 task.js 文件,能夠找到兩處任務加載的執行函數:windows

// Load tasks and handlers from a given directory.
task.loadTasks = function(taskdir) {}

// Load tasks and handlers from a given locally-installed Npm module (installed relative to the base dir).
task.loadNpmTasks = function(name) {}

從代碼的註釋能夠獲知前端工程化

task.loadTasks 方法能夠從指定的目錄加載任務模塊
task.loadNpmTasks 方法則根據當前項目下 Npm module 所在的安裝目錄來加載任務模塊函數

至此,咱們很快能夠得到共享 node_modulse 的靈感,只要稍微改造一下 Gruntfile.js 文件,咱們就能夠實現以前的想法了。grunt

// 引入 path 模塊
var path = require('path');

module.exports = function(grunt) {

    // 從新設置 grunt 的項目路徑,獲取當前的 package.json 文件信息
    grunt.file.setBase(__dirname);

    // 獲取當前目錄相對於共享 node_modules 目錄的路徑(以windows下面爲例)
    var nodepath = path.relative(__dirname,'D:/node_modules/') 

    grunt.initConfig({
        pkg: grunt.file.readJSON('package.json'),
        concat: "",
        uglify: "",
        clean : ""
    })

    // 加載任務
    grunt.task.loadTasks(path.join(nodepath,"grunt-contrib-clean",'tasks'));
    grunt.task.loadTasks(path.join(nodepath,"grunt-contrib-uglify",'tasks'));
    grunt.task.loadTasks(path.join(nodepath,"grunt-contrib-concat",'tasks'));

    // 註冊任務
    grunt.registerTask('build', ['concat','uglify','clean']);
}

Made it!! 如獲至寶,立刻命令行執行 grunt build。 吶呢,出錯啦:

Fatal error: Unable to find local grunt.

出錯的緣由也比較簡單,咱們把 grunt 的目錄給忽略了,所以在必須在執行命令的時候告訴 grunt 目錄的位置,加上 --base 參數,就能成功運行了。

grunt build --base = d:\node_modules\

由於咱們這裏人爲的加上 --base 參數,改變了當前項目下 grunt 目錄地址,在運行任務的時候,須要從新設置回去,這也解釋了爲何須要在 Gruntfile.js 加上如下代碼:

grunt.file.setBase(__dirname);

PS: 以上爲 windows 下的實現方法,最好把共享的 node_modules 和項目放置在同一分區,否則會出現文件路徑不兼容的問題,Unix 和 linux 沒有分區的概念,因此沒有問題,其餘的設置都同樣。

The End, Enjoy it!

相關文章
相關標籤/搜索