搜尋

首頁  >  問答  >  主體

import - node.js中require一個npm install的module做了什麼事情?

刚刚发现require的module也会影响到后续的require,以moment和moment-timezone举例,也就是说:

/app.js

var moment = require('moment');
console.log(moment.tz()); 
// 这样会报错,因为moment.tz()是moment-timezone这个module才有的function
/*
TypeError: moment.tz is not a function
*/

但是如果我先require了moment-timezone,后续我再require了moment,npm install moment,我依然可以require('moment')而且这个moment就可以使用moment-timezone的功能,如下

/app.js

require('moment-timezone')
var moment = require('moment');
console.log(moment.tz()); //moment.utc("2017-06-27T06:59:14.475+00:00")

我不明白的点是,为什麽require('moment-timezone')之后,即使我没有npm install moment 我还是可以require('moment');而不会报错呢?
这样的node modules是经过什麽设计或有什麽特殊的名词可以造成这样的行为吗?

顺带一提,如果上面的moment-timezone可以这样设计,假设我今天发佈了一个叫做noname的module在npm上供人使用,只要程序上先执行了require('noname'); ,是否可以改了后续require('express')这个module的return内容,做到类似以下的作用:

require('noname');
var express = require('express');
express.thisIsMyExpress();//这是被我换过的express module
世界只因有你世界只因有你2694 天前1092

全部回覆(1)我來回復

  • 某草草

    某草草2017-06-29 10:11:33

    1. 為什麼require('moment-timezone')之後,即使我沒有npm install moment我還是可以require('moment')而不會報錯呢?

    查看moment-timezone依賴

    $> npm info moment-timezone dependencies 
    { moment: '>= 2.9.0' }

    可以看出moment-timezone是依賴了moment的,這表示在安裝moment-timezone時會自動安裝moment,所以不需要再單獨安裝也可以使用。

    2. 為什麼require('moment-timezone')會影響後續var moment = require('moment')中`moment`的賦值

    查看moment-timezone源碼

      1 //! moment-timezone.js
      2 //! version : 0.5.13
      3 //! Copyright (c) JS Foundation and other contributors
      4 //! license : MIT          
      5 //! github.com/moment/moment-timezone
      6 
      7 (function (root, factory) {
      8   "use strict";            
      9 
     10   /*global define*/        
     11   if (typeof define === 'function' && define.amd) {
     12     define(['moment'], factory);                 // AMD
     13   } else if (typeof module === 'object' && module.exports) {
     14     module.exports = factory(require('moment')); // Node
     15   } else {
     16     factory(root.moment);                        // Browser                  
     17   }
     18 }(this, function (moment) {
     19   "use strict";

    第14行可以看到moment-timezone修改了require('moment'),眾所周知npm模組是會緩存的,所以後續var moment = require('moment')被影響

    順便提一句,直接修改模組就和修改全域變數一樣,並不是很好的實踐。這裡moment-timezone模組基本上算是`moment`模組的補丁,是一個特例.

    回覆
    0
  • 取消回覆