Es6Module and CommonJS specifications


Static and dynamic ES6Modules are static modules that analyze dependencies at compile time and support tree-shaking. CommonJS is a dynamic module, dependencies are known at code execution time, tree-shaking is not supported. 2) esModule inputs references to values. CommonJS outputs are worth copying. 3) The top layer of this in the esModule refers to undefined. The top-level this in the CommonJS module refers to the current module.

Module in Node

1. Built-in modules

1) the fs module
let r = fs.readFileSync('./1.js');
let exists = fs.existsSync('./2.js');
Copy the code
2) path module
path.resolve(__dirname, 'a.js'); Path.resolve (__filename,'b.js'); Path.resolve (__dirname,'a'.'b'.'/'); # c:\ If any` / `, returns the root directory.Copy the code
path.join(__dirname, 'a'.'b'.'/'); #/Users/Desktop/demo/a/b/ path splices, encountered` / `It's going to be put togetherCopy the code
// Take the extension
path.extname('a.min.js'); // .js
// Take the file name according to the suffix
path.basename('a.js'.'.js') // a
// Get the relative path
path.relative('a/b/c/1.js'.'a'); / /.. /.. /..
// Get the directory name
path.dirname('a/b/c'); // a/b
Copy the code
3) the vm module
// new Function() executes the code
global.a = 100;
new Function('b'.'console.log(a, b)') ('b'); // 100 b
Copy the code
// Execute in the current context
const vm = require('vm');
global.a = 100;
vm.runInThisContext('console.log(a)'); / / 100
Copy the code

2. File module

File module lookup specification:

  • The default is to look for files with the same name and try adding.js and.json files.
  • If you can’t find a file with the same name, look for a folder with the same name (think of folders as packages). If package.json is in the folder, look it up according to the file specified by main in package.json.
  • If you don’t have package.json, look for index.js in the folder with the same name.

3. Third-party modules

Third-party module references are divided into global module installation references and code references.

Third party module lookup specification:

  • The default is to look up the current directory and find the folder of the same name under node_modules. Look for main in package.json, or index.js if you can’t find it.
  • If you don’t find it, go straight to node_modules. If the root path is not found, the package does not exist, indicating an error.

Implementation principle of require in node


The core idea of CommonJS require is that the introduced module wraps a layer of self-executing functions to achieve module isolation.

Take a look at the following example to help you understand how it works:

// a.js
var a = 100;
module.exports = '1';
Copy the code
// b.js

/ / introduction of a. s
let a = require('./a');

/ / equivalent to
let a = (function(exports.module.require, __dirname, __filename) {
    var a = 100;
    module.exports = '1';
    
    return module.exports; }) (exports.module.require, __dirname, __filename);
Copy the code

Implementation process:

  1. Module.resolveFilenameGenerates an absolute path based on the relative reference path entered by the user.
  2. new ModuleCreate a module based on the file path.
  3. module.loadCall the module’s load event, load the module, execute the script tomodule.exportsThe assignment.
  4. return module.exportsreturnexportsObject, the user gets itmodule.exportsReturns the result of.
  5. cacheModule = Module._cache[filename]Cache modules by filename.
// 1.js

var a = 100;
console.log(this= = =module.exports) // true
module.exports = a;
Copy the code
// require.js

const fs = require('fs');
const path = require('path');
const vm = require('vm');

function Module(id) {
    this.id = id;
    this.exports = {};
}
Module._cache = [];
Module.prototype.load = function() {
    // Get the file name extension and go to policy mode
    let ext = path.extname(this.id);
    Module._extensions[ext](this);
}
// Policy mode, different suffixes
Module._extensions = {
    '.js'(module) {
        // Read the script
        let script = fs.readFileSync(module.id, 'utf8');
        // Wrapped as a Function, runInThisContext is similar to new Function(), which converts the templateFn string into a Function
        let templateFn = `(function(exports, module, require, __dirname, __filename){${script}}) `;
        let fn = vm.runInThisContext(templateFn);
        // console.log(fn.toString());

        // this = module.exports = exports
        let exports = module.exports;
        let thisValue = exports;
        let filename = module.id;
        let dirname = path.dirname(filename);
        
        Module.exports = 100
        fn.call(thisValue, exports.module, req, dirname, filename);
    },
    '.json'(module) {
        let script = fs.readFileSync(module.id, 'utf8');
        module.exports = JSON.parse(script); }}// Change the path to an absolute path and add the suffix
Module._resolveFilename = function(id) {
    let filePath = path.resolve(__dirname, id);
    let isExists = fs.existsSync(filePath);
    if (isExists) return filePath;

    // Try adding the suffix
    let keys = Reflect.ownKeys(Module._extensions); // ['.js', '.json']
    for (let i = 0; i < keys.length; i++) {
        let newPath = filePath + keys[i];
        if (fs.existsSync(newPath)) return newPath;
    }
    throw new Error('module not found');
}

function req(filename) {
    // 1. Create an absolute reference path for subsequent reading
    filename = Module._resolveFilename(filename);
    // There is a cache
    let cacheModule = Module._cache[filename];
    if (cacheModule) return cacheModule.exports;
    // 2. Create a module based on the path
    const module = new Module(filename);
    // Cache modules by filename
    Module._cache[filename] = module;
    // exports. Let users assign values to module.exports
    module.load();

    return module.exports;
}

// let a = req('a.json');
let a = req('./1.js');
console.log(a);
Copy the code

Iv. Installation and release of third-party modules

1) Global installation

Global installation, which can be used only on the command line. Modules in global installation are installed in the NPM directory.

To implement the global installation package yourself, you need:

  1. package.jsonIn the configurationbinCommand.
  2. Add execution mode#! /usr/bin/env node.
  3. Place this package under NPM and install it globally or temporarilysudo npm link.
2) Code installation

NPM install module --save --save-dev

3) Dependency
  1. Development dependency: –save-dev
  2. Production dependency: –save
  3. PeerDependencies: a third-party module that depends on another module.
  4. OptionalDependencies: optionalDependencies.
  5. Package dependencies: bundledDependencies.npm packWhen you play a compressed package, you want to put a package in here. (the defaultnpm packHit the compression pack will not hitnode_modules).
4) Why can NPM run XXX be executed?

By default, the. Bin environment variable is added to the global environment variable before the command is executed. Then the command can be executed. After the command is executed, the corresponding path is deleted.

NPX is similar to NPM run. If the NPX module does not exist, it will be installed first and then used.

5) Version management

Version management mode: Semver (Major, Minor, and Patch).

^2.24.=> The first digit can only be2. ~2.24.=> The second value cannot be lower than that2, the larger version cannot exceed2Version, that is,2.2X.` > = `=> The version must be greater than or equal to a certain version` < = `=> Less than or equal to a specified version: NPM install jquery@2.24.NPM install jquery@2No less than2The version of theCopy the code
6) Package release
  1. Switch the source
nrm use npm
Copy the code
  1. Login NPM
npm addUser
Copy the code
  1. release
npm publish
Copy the code

An updated version

NPM version Major #1, other version numbers belong to0NPM version Minor #1, the revision number belongs to0NPM Version Patch #1
Copy the code
npm publish
Copy the code