search

Home  >  Q&A  >  body text

import - What does the require npm install module in node.js do?

I just discovered that the require module will also affect subsequent require, taking moment and moment-timezone as examples, that is to say:

/app.js

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

But if I require moment-timezone first, and then require moment, npm install moment, I can still require('moment') and this moment can use the function of moment-timezone, as follows

/app.js

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

What I don't understand is why after require('moment-timezone'), even if I don't have npm install moment, I can still require('moment'); without reporting an error?
What is the design of such node modules or is there any special term that can cause such behavior?

By the way, if the above moment-timezone can be designed like this, suppose I released a module called noname for people to use on npm today. As long as the program executes require('noname'); first, is it possible? Changed the return content of the subsequent require('express') module to achieve a similar effect to the following:

require('noname');
var express = require('express');
express.thisIsMyExpress();//这是被我换过的express module
世界只因有你世界只因有你2695 days ago1093

reply all(1)I'll reply

  • 某草草

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

    1. Why after require('moment-timezone'), even if I don't npm install moment I can still require('moment') without getting an error?

    View moment-timezoneDependencies

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

    It can be seen that moment-timezone is dependent on moment, which means that moment will be automatically installed when installing moment-timezone, so it can be used without installing it separately.

    2. Why does require('moment-timezone') affect the subsequent assignment of `moment` in var moment = require('moment')

    View moment-timezonesource code

      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";

    On line 14, you can see that moment-timezone has modified require('moment'). As we all know, the npm module will be cached, so the subsequent var moment = require('moment') will be affected

    By the way, directly modifying modules is the same as modifying global variables, which is not a good practice. The moment-timezone module here is basically a patch of the `moment` module and is a special case.

    reply
    0
  • Cancelreply