instructions

The version of this document is V11.12.0. This article mainly analyzes the result of Nodejs require import JSON and JS files, and briefly involves Nodejs module export module.exports and exports usage.

The introduction

In the process of reading the webpack source code, see the following line of code:

const version = require(".. /package.json").version
Copy the code

Therefore, the study of Nodejs require is extended.

Introduced the require

In node.js documentation, require’s documentation is in the Modules directory, which is part of the Nodejs modular system. Require is a function. Through the typeof or Object. The prototype. ToString. Call () can verify this conclusion:

The console. The log (require) / / output: the Function the console. The log (Object. The prototype. ToString. Call (require) / / output: [Object Function]Copy the code

By printing require directly, you can see that several static properties are mounted under the require function. These static properties can also be found directly in the Nodejs documentation:

{ [Function: require]
  resolve: { [Function: resolve] paths: [Function: paths] },
  main:
   Module {
     id: '. ',
     exports: {},
     parent: null,
     filename: '/Users/bjhl/Documents/webpackSource/index.js',
     loaded: false,
     children: [],
     paths:
      [ '/Users/bjhl/Documents/webpackSource/node_modules'.'/Users/bjhl/Documents/node_modules'.'/Users/bjhl/node_modules'.'/Users/node_modules'.'/node_modules' ] },
  extensions:
   [Object: null prototype] { '.js': [Function], '.json': [Function], '.node': [Function] },
  cache:
   [Object: null prototype] {
     '/Users/bjhl/Documents/webpackSource/index.js':
      Module {
        id: '. ',
        exports: {},
        parent: null,
        filename: '/Users/bjhl/Documents/webpackSource/index.js',
        loaded: false,
        children: [],
        paths: [Array] } } }
Copy the code

Static properties of the require function

More details on this later.

Require the use of

The following description of require can be found in the official documentation:

Require (id)# Added in: v0.1.13 ID module name or path Returns: exported module content Used to import modules, JSON, and local files. Modules can be imported from node_modules. Local modules and JSON files can be imported using a relative path (e.g. ./, ./foo, ./bar/baz, .. /foo) that will be resolved against the directory named by __dirname (if defined) or the current working directory.

At the same time, three use methods of require are given:

// Importing a local module:
const myLocalModule = require('./path/myLocalModule');

// Importing a JSON file:
const jsonData = require('./path/filename.json');

// Importing a module from node_modules or Node.js built-in module:
const crypto = require('crypto');
Copy the code

The following information can be obtained from the above documents:

  1. Require takes a parameter called ID of type String.
  2. The require function returns the contents of the module, of any type.
  3. The require function can import modules, JSON files, and local files. Modules can be exported from node_modules, local modules, JSON files via a relative path to the __dirname variable (if defined), or the current working directory.

The require practice

The practical conclusions of REQUIRE will be discussed here in categories.

The require import JSON

JSON is a syntax for serializing objects, arrays, values, strings, booleans, and NULL. The version property in package.json is read from the require(“./package.json”) file at the beginning of this article. Here you will try to import the info.json file and view the information. The file structure directory is as follows:

.├ ─ index.js ├─ info.jsonCopy the code

Change the contents of the info.json file to:

{
    "name": "myInfo"."hasFriend": true."salary": null,
    "version": "v1.0.0"."author": {
        "nickname": "Hello Kitty"."age": 20."friends": [{"nickname": "snowy"."age": 999}]}}Copy the code

Json contains strings, booleans, null, numbers, objects, and arrays. Modify the contents of index.js as follows and run the node index.js command in the current terminal to obtain the following results:

const info = require("./info.json") the console. The log (Object. The prototype. ToString. Call (info)) / / [Object Object] the console. The log (info. Version) / / v1.0.0 console.log(info.hasFriend) //true
console.log(info.salary) // null
console.log(info.author.nickname) // Hello Kitty
console.log(info.author.friends) // [ { nickname: 'snowy', age: 999 } ]
Copy the code

Nodejs can directly access all properties of this Object, including String, Boolean, Number, Null, Object, and Array. My guess is that something similar to json.parse () is being used. This conclusion also leads to the idea of passing in a JSON file to read some values via the require method, as in the beginning of this article, where WebPack gets the version value by reading package. JSON.

Require imports the local JS file

The file structure directory is as follows:

.├ ─ index.js ├─ ├─ ├.js ├─ ├.jsCopy the code

Module_a and module_B were imported and assigned to the index.js file, respectively, and then printed as follows:

console.log("*** index.js starts executing ***")
const module_a = require("./module_a")
const module_b = require("./module_b")
console.log(module_a, "*** Prints module_A ***")
console.log(module_b, "*** Prints module_B ***")
console.log("*** index.js end execute ***")
Copy the code

Module_a does not specify module.exports or exports, but adds an asynchronous execution statement setTimeout, which reads as follows:

console.log("** Module_A starts executing **")
let name = "I'm module_a"
setTimeout(() => {
    console.log(name, "** setTimeout Prints a's name **")
}, 0)
console.log("** module_A End execution **")
Copy the code

Exports can also be used as exports.name, but exports cannot be used as an object, because exports and module.exports refer to the same address, referencing the same object. Exports = module. Exports = module. Exports = module. Exports = module.

console.log("** Module_B starts executing **")
let name = "I'm module_b"
console.log(name, "** Print the name of B **")
module.exports = {
    name
}
console.log("** module_B end execution **")
Copy the code

Run node index.js under the current directory terminal and the output is as follows:

Js Start execute *** ** module_A Start execute ** ** module_A End execute ** ** module_B Start execute ** I am module_B ** Print the name of B ** ** module_B End execute * * {...})'*** prints module_A ***'
{ name: 'I am module_b' } '*** 打印module_b ***'Js End Run the *** I am module_A ** commandsetTimeout Prints the name of a **Copy the code

Conclusions can be drawn from the above results:

  1. Exports/module. Exports/module. Exports require a js file that does not export through exports or module. Instead, you can export the specified content via module.export or by assigning a value to the exports property.
  2. When require a JS file, the file will be sync executed immediately.

Require import module

Let’s start with an NPM package — CORS. Go to the folder and run the command:

NPM init -y // Initializationecho -e "let cors = require(\"cors\")\nconsole.log(cors)"NPM install cors --save // Install cors packageCopy the code

The file structure is as follows (… Omit other modules):

. ├ ─ ─ index. Js ├ ─ ─ node_modules │ ├ ─ ─ cors │ │ ├ ─ ─ CONTRIBUTING. Md │ │ ├ ─ ─ the HISTORY. The md │ │ ├ ─ ─ LICENSE │ │ ├ ─ ─ the README, md │ │ ├ ─ ─ lib │ │ │ └ ─ ─ index. The js │ │ └ ─ ─ package. The json │ │... ├ ─ ─ package - lock. Json └ ─ ─ package. The jsonCopy the code

The contents of index.js are as follows:

let cors = require("cors")
console.log(cors)
Copy the code

Run Node index.js and get the following result:

[Function: middlewareWrapper]
Copy the code

Go to the cORS module folder under node_modules, look at the package.json file in cros, and find the main field: “main”: “./lib/index.js”, find the file pointing to the main field, find that it is an IIFE, add console.log(“hello cors”) to the IIFE code, and emulate the code structure as follows:

(function () {
    'use strict';
    console.log("hello cors"); // This is manually added code...functionmiddlewareWrapper(o) { ... } module.exports = middlewareWrapper; }) ()Copy the code

Run Node index.js again and get the following result:

hello cors
[Function: middlewareWrapper]
Copy the code

Why is Hello Cors printed? Json file that the main field in the package.json file points to. The js file is automatically executed, as is the require reference to the local JS file.

Packjson document

The main field definition in package.json can be found on NPM’s official website.

main The main field is a module ID that is the primary entry point to your program. That is, if your package is named foo, and a user installs it, and then does require(“foo”), Then your main module’s exports object will be returned. This should be a module ID relative to the root of your package folder For most modules, it makes the most sense to have a main script and often not much else.

The following conclusions can be drawn from the above explanation:

  1. The main field is a module ID and is the main entry to the program.
  2. Module. Exports from the js file corresponding to the main field when require(” XXX “) is used.

So require imports the file specified in the main field of the corresponding module package.json.

— end —