Front End Modular Outline

Front-end modular specifications are as follows:

1.1 Module Overview

In the early days of JavaScript design, there was no concept of modules, packages, or classes. Developers needed to simulate similar capabilities to isolate and organize complex JavaScript code, which we call modularity. A module is a file that implements a specific function. With a module, we can more conveniently use other people’s code and load any module with any function.

Four benefits of modular development:

1. Avoid variable pollution and naming conflicts; 2. Improve code reuse rate; 3. Improved maintainability; 4. Facilitate dependency management.

To avoid the problem of missing modules, let’s look at how programmers solve the problem:

1.2 Function Encapsulation

When we talked about functions, we mentioned that a function is a package of statements that implement specific logic, and JavaScript’s scope is based on functions, so it’s a natural first step to modularize functions. Writing several related functions in a file is the beginning of a module

1 / / function
function fn1(){
  //statement
}
/ / function 2
function fn2(){
  //statement
} 
Copy the code

In this way, when the function function is needed, you can import the file and call the function.

Disadvantages:

Contaminate global variables, can not guarantee that other modules have variable name conflicts, and there is no relationship between module members, just put in a JS file.

1.3 Object Encapsulation

In order to solve the above problem, the object writing method came into being, you can encapsulate all module members in one object

var myModule = {
  var1: 1.var2: 2.fn1: function () {},
  fn2: function () {}};Copy the code

So we reference the corresponding file when we want to call the module:

myModule.fn2();
Copy the code

This avoids variable contamination, as long as the module name is unique and members of the same module are related. But outsiders can modify internal members at will, which can cause unexpected security problems.

myModel.var1 = 100;
Copy the code

1.4 Execute function Expressions now (IIFE)

You can hide details by executing functional expressions (IIFE) immediately.

var myModule = (function () {
  var var1 = 1;
  var var2 = 2;
  function fn1() {}
  function fn2() {}

  return {
    fn1: fn1,
    fn2: fn2, }; }) ();Copy the code

This makes it impossible to modify variables or functions outside the module that are not exposed. But they are relatively weak, encapsulation adds work, still leads to namespace contamination, and closures have costs.

JavaScript initially just validates forms and later adds animations, but much of this JS code can be done in a single file, so we just need to add a script tag to the HTML file.

Later, with the increase of front-end complexity, in order to improve the readability and scalability of the project code, our JS files gradually increased, no longer a JS file can be solved, but each JS file as a module. So, what is the js introduction mode at this time? Something like this:

  <script src="jquery.js"></script>
  <script src="jquery.artDialog.js"></script>
  <script src="main.js"></script>
  <script src="app1.js"></script>
  <script src="app2.js"></script>
  <script src="app3.js"></script>
Copy the code

Simply put all the JS files together. However, the order of these files should not be wrong. For example, jquery needs to be imported before jquery plug-ins can be imported before jquery can be used in other files. The idea of using multiple JS files to achieve the simplest modularity is an improvement over using a single JS file.

Disadvantages:

Contamination global scope. Because each module is globally exposed, simple use can lead to global variable naming conflicts, of course, we can also use the namespace approach to resolve.

For large projects, there are many kinds of JS, and developers have to solve the dependency between modules and code base manually, resulting in high maintenance costs.

Dependencies are not obvious and are not conducive to maintenance. For example, main.js needs to use jquery, but you can’t tell from the above file. If jquery forgets, it will report an error.

1.5 Modular Specifications

Common JavaScript module specifications are: CommonJS, AMD, CMD, UMD, native modularity

1.5.1 CommonJS

CommonJs is the specification for server-side modules, which Is adopted by Node.js.

According to the CommonJS specification, a single file is a module. The load module uses the require method, which reads a file and executes, finally returning the exports object inside the file.

// foobar.js

// Private variables
var test = 123;

// Public method
exports.foobar = {
  foo:function () {
    // do something ...
  };
  bar:function () {
    //do something ...
  };
}
Copy the code
The //require method reads js files by default, so you can omit the js suffix
var test = require('./foobar').foobar;
test.bar();
Copy the code

CommonJS loads modules synchronously, so you can’t perform any operations until the load is complete. For example, Node.js is mainly used for server programming, and the loaded module files are generally stored in the local hard disk, so the loading is relatively fast, without considering the asynchronous loading mode, so the CommonJS specification is more suitable. However, in a browser environment, to load modules from the server, this must be done in asynchronous mode. Hence the AMD CMD solution.

1.5.2 AMD(Asynchromous Module Definition) Asynchronous Module Definition

AMD is the canonical output of RequireJS’s module definition in its promotion process. AMD asynchronously loads modules. Its modules support various types of modules such as object function constructor string JSON. Applicable to AMD specification applies to define method for module definition.

// The dependency is passed in through an array, and the callback is passed in through a parameter
define(['someModule1'.'someModule2'].function (someModule1, someModule2) {

function foo () {
/// someing
someModule1.test();
}

return {foo: foo}
});
Copy the code

The AMD specification allows the output module to be compatible with the CommonJS specification.

define(function (require.exports.module) {
  var reqModule = require("./someModule");
  reqModule.test();

  exports.doSome = function () {
    //something
  };
});
Copy the code

1.5.3 Common Module Definition (CMD) Common Module Definition

CMD is the normalized output of SeaJS module definition in the promotion process. The differences between CMD and AMD are as follows:

  1. For dependent modules AMD is executed early, CMD is executed late. However, since 2.0, RequireJS can also be delayed execution (depending on the writing method, the processing method is not passed).

  2. CMD advocates dependency nearby, AMD advocates dependency front.

    //AMD
    define(["./a"."./b"].function (a, b) {
      // Dependencies are written from the start
      a.test();
      b.test();
    });
    
    //CMD
    define(function (requie, exports.module) {
      // Dependencies can be written nearby
      var a = require("./a");
      a.test();
    
      / / soft dependency
      if (status) {
        var b = requie("./b"); b.test(); }});Copy the code

    Although AMD also supports CMD, dependency prefixes are the default module definition for official documentation.

  3. The DEFAULT AMD API is one when multiple use, CMD strict distinction advocates a single responsibility. For example, in AMD require is divided into global and local. There is no global require in CMD. Seajs.use () is provided to enable the module system to load and start. Every API in CMD is simple and pure.

1.5.4 UMD

UMD is a combination of AMD and CommonJS. AMD browser first principle develops asynchronous loading modules. The CommonJS module follows the server first principle of synchronous loading and does not require unwrapped modules.

This forced people to come up with another, more generic pattern, UMD (Universal Module Definition). Looking for a cross-platform solution. UMD determines whether any module (exports) that supports Node.js exists and uses node.js module mode if it does. Then check whether AMD is supported (define exists). If yes, load the module in AMD mode.

(function (obj, factory) {
  if (typeof exports= = ="object") {
    module.exports = factory();
  } else if (typeof define === "function" && define.amd) {
    define(factory);
  } else {
    obj.eventUtil = factory();
  }
})(this.function () {
  //module ...
});
Copy the code

1.5.5 Modularization of Native JS

None of the above modules are native JavaScript modules. They are simply modular systems that we emulate with Module pattern, CommonJS, or AMD.

JavaScript standard-setters in TC39 (which defines the syntax and semantics of ECMAScript) have introduced a built-in module system for ECMAScript 6 (ES6).

ES6 opens up a lot of possibilities for importing exporting modules.

CommonJS

CommonJS is a JavaScript modularity specification that was originally used in server-side NodeJS, and the front-end Webpack supports CommonJS natively.

According to the specification, each file is a module, and the variables defined inside it belong to that module and are not exposed, that is, they do not pollute global variables.

CommonJS defines modules as:

  1. Module reference (require) : require() is used to introduce external modules;
  2. Module definition (exports) : An exports object is a method or variable that exports the current module, the only export;
  3. Module identifier (Module) : The Module object represents the module itself.

2.1 NodeJS uses CommonJS module for management

2.1.1 Module Definition

According to the commonJS specification, a single file is a module, and each module is a separate scope. That is, variables defined inside the module cannot be read by other modules unless they are properties of the Global object.

The module has only one export, the Module.exports object, into which we need to put what the module wants to export.

Mathlib.js module definition

var message="Hello CommonJS!";

module.exports.message=message;
module.exports.add=(m,n) = >console.log(m+n);
Copy the code

2.1.2 Module Dependency

Modules are loaded using the require method, which reads a file and executes, returning the module.exports object inside the file.

Myapp.js module dependency

var math=require('./mathLib');
console.log(math.message);
math.add(333.888);
Copy the code

2.2 Use CommonJS module for browser management

The browser does not support CommonJS. In order for the browser to use these modules, the format must be converted. The root cause of browser incompatibility with CommonJS is the lack of four node.js environment variables (Module, exports, require, global). As long as these four variables are available, the browser can load the CommonJS module. A tool like Browserify solves the above problem by compiling NodeJS modules into browser-usable modules. Browserify is currently the most commonly used tool for converting CommonJS formats. Install Browserify using the following command:

npm install -g browserify
yarn global add browserify
Copy the code

To convert the CommonJS format to a browser-usable format, use the following command:

$ browserify myApp.js > myApp_01.js
Copy the code

While Browserify is powerful, it doesn’t work in a browser, which can be inconvenient at times.

Browser-only CommonJS module loader Require1k (github.com/Stuk/requir…

Advantages:

CommonJS specification takes the lead in completing the modularization of JavaScript on the server side, and solves the problems of dependency and global variable pollution, which is also a necessary condition for JS to run on the server side.

Disadvantages:

This article is mainly about the modularization of browser-side JS, because CommonJS is a synchronous loading module, on the server side, the files are saved on the hard disk, so there is no problem with synchronous loading, but for the browser side, the file needs to be requested from the server side, so synchronous loading is not applicable, so, CommonJS is not very suitable for the browser side.

AMD

3.1 the profile

The CommonJS specification loads modules synchronously, meaning that subsequent operations cannot be performed until the load is complete. The AMD specification loads modules asynchronously and allows you to specify callback functions. Node.js is mainly used for server programming, and module files usually already exist on the local hard disk, so it can be loaded quickly without considering the asynchronous loading mode, so the CommonJS specification is suitable. However, in the browser environment, to load modules from the server side, then must be in asynchronous mode, so the browser side generally uses the AMD specification. And the implementation of AMD specifications, is the famous require.js.

Asynchronous Module Definition Asynchronous Module Definition It is a specification for modular development on the browser side. Because it is not supported by JS native, page development using AMD specification needs corresponding function library, namely the famous RequireJS. In fact, AMD is the standardized output of RequireJS module definition in the promotion process.

RequireJS addresses two main issues:

  1. Multiple JS files may have dependencies, and the dependent file needs to be loaded into the browser before the dependent file.
  2. The browser stops rendering when js is loaded. The more files loaded, the longer the page is unresponsive.

3.2 Usage

The FOLLOWING two apis are defined in the AMD standard:

1.require([module], callback)
2. define(id, [depends], callback)
Copy the code

Define a module and use require to load a module. Require also supports CommonJS module export.

RequireJS defines a function define, which is the global variable used to define the module.

define(id,dependencies,factory)

— id Specifies the identity of the module. If this parameter is not provided, the script name is used (without the extension). Dependencies are an array of module names that the current module uses. The module initializes the function or object to be executed. If it is a function, it should be executed only once. If it is an object, this object should be the output value of the module.

Load the module on the page using the require function:

require([dependencies], function(){});

The require() function takes two arguments: the first argument is an array representing the dependent module; The second argument is a callback function that will be called after all modules specified in the previous page have been successfully loaded. Loaded modules are passed to the function as arguments, so they can be used inside the callback function.

// moduleA
define(function () {
  return {
    show: (m) = > {
      console.log(m);
      document.body.innerHTML = `<h2>${m}</h2>`; }}; });// moduleB
define(["m/moduleA"].function (a) {
  return {
    add: (m, n) = > a.show(m + n),
  };
});

// The module references app.js
require(["m/moduleB",].function (b) {
  let m = 500,
    n = 100;
  b.add(m, n);
});
Copy the code
<script
  type="text/javascript"
  defer
  src=".. /node_modules/requirejs/require.js"
  data-main="js/app.js"
></script>
Copy the code

However, with require.js, all dependencies must be loaded in advance before they can be used, not when they need to be used.

Advantages:

Suitable for asynchronously loading modules in a browser environment. Multiple modules can be loaded in parallel.

Disadvantages:

Increased development costs, and instead of loading on demand, all dependencies must be loaded in advance.

3.3 Tips

3.3.1 data – the main attributes

Remember the requirejs mantra: two functions for one property. Requirejs requires a root to start the search dependency, and data-main specifies this root.

<script src="scripts/require.js" data-main="scripts/app.js"></script>
Copy the code

The root is app.js, and only modules that are directly or indirectly dependent on app.js will be inserted into the HTML.

3.3.2 rainfall distribution on 10-12 require. Config () configuration

Requirejs can be configured flexibly through this function. Its parameter is a configuration object. The configuration items and their meanings are as follows:

  1. BaseUrl — the root path to load the module;
  2. Paths — For mapping module paths that do not have root paths;
  3. Shims – Configures functions outside of scripts/modules that do not use RequireJS and initializes functions. If underscore does not use the RequireJS definition, but you still want to use it with RequireJS, then you need to define it as a shim in the configuration.
  4. Deps — Loads the dependency array.
require.config({
  // The base path of a module dependency
  baseUrl: "js/".// Simplify the configuration path.
  paths: {
    m: "module/".jquery: "Common/jquery/jquery - 1.11.3".moduleG: "module/moduleG",},shim: {
    moduleG: {
      exports: "moduleG",}}});Copy the code

3.4 Loading a JavaScript File

RequireJS aims to encourage modularity of code by using script loading steps that are different from traditional Script tags. It can be used to speed up and optimize code, but its main purpose is to modularize the code. It encourages the use of module IDS instead of URLS when using scripts.

RequireJS loads all code at an address relative to baseUrl. The script tag at the top of the page contains a special attribute, data-main, which require.js uses to start the script loading process, and baseUrl is generally set to a directory consistent with this attribute. BaseUrl Settings are shown in the following example:

<! --This sets the baseUrl to the "scripts" directory, and loads a script that will have a module ID of 'main'-->
<script data-main="scripts/main.js" src="scripts/require.js"></script>
Copy the code

BaseUrl can also be set manually using RequireJS Config. If config and data-main are not explicitly specified, the default baseUrl is the directory of the HTML page containing RequireJS.

Ideally, each loaded script is a module defined by define(); However, some traditional/legacy “browser global variable injection” libraries do not use define() to define their dependencies, so you must use shim Config to specify their dependencies. Loading may fail if you do not specify dependencies. This is because RequireJS loads these libraries asynchronously and unordered for speed reasons.

3.5 Path Processing

/ / moduleA:
define(function () {
    return {
        show: m= > console.info(m)
    }
});

// moduleB:
define(['moduleA'].function (a) {
    return {
        add: (m, n) = > a.show(m + n)
    }
});

// app.js
require(['module/moduleB'].function (b) {
    b.add(100.500);
});

// index.html:
<script src="Js/require2.1.11. Js" data-main="js/app.js"></script>
Copy the code

Solution 1: BaseUrl =’js/’, so all modules start with js/ by default, so moduleB depends on ModuleA and starts with JS /. You can fix this problem by specifying the current directory. Modify moduleB as follows:

define(['./module/moduleA'].function (a) {
    return {
        add: (m, n) = > a.show(m + n)
    }
});
Copy the code

Solution 2: Manually configure baseUrl and modify it as follows:

requirejs.config({
    // Base path of module dependencies, default module loading location
    baseUrl:'js/module/'
});

// The module references app.js
require(['moduleB'].function (b) {
    b.add(100.500);
});

// moduleB
define(['moduleA'].function (a) {
    return {
        add: (m, n) = > a.show(m + n)
    }
});
Copy the code

3.5.1 Relying on Third-party Libraries (AMD Relying on jQuery)

JQuery 1.7 starts to support registering jQuery as an AMD asynchronous module. There are many compatible script loaders (including RequireJS and curl) that can load modules in an asynchronous module format:

if ( typeof define === "function" && define.amd ) {
    define( "jquery"[],function() {
        return jQuery;
    });
}
Copy the code

Since jquery defines a global variable “jquery” in the define way, you introduce the jquery module by defining the path alias in the Paths option.

requirejs.config({
    // Base path of module dependencies, default module loading location
    baseUrl:'js/'./ / path
    paths: {jquery:'common/jquery/jquery - 1.12.4'}});// Module reference
require(['jquery'].function ($) {$("body").css({"background":"yellow"});
});
Copy the code

3.5.2 Rely on non-AMD modules

The shim parameter configures dependencies and exports for “browser global variable injection” scripts that do not use define() to declare dependencies and set modules.

Add a non-AMD module modulee.js:

var moduleE = {
    hello: () = > {
        console.info("Hello ModuleE!"); }};Copy the code

Reference ModuleE:

/ / configuration
requirejs.config({
    // Base path of module dependencies, default module loading location
    baseUrl:'js/'./ / path
    paths: {moduleE:'module/moduleE'
    },
    // Handle non-standard AMD modules
    shim: {// This key name is the file name of the target file to be loaded
        'moduleE': {exports:'moduleE'}}});// Module reference
require(['moduleE'].function (e) {
    e.hello();
});
Copy the code

3.6 Precautions

Module per file: Each Javascript file should define only one module, which is a natural requirement of the module-filename lookup mechanism. Multiple modules will be organized and optimized by the optimization tool, but you should place multiple modules in one file when using the optimization tool.

Relative module names in define() : In order to properly resolve relative names using calls such as require(“./relative/name”) inside define(), remember to inject “require” itself as a dependency into the module:

define(["require"."./relative/name"].function(require) {
    var mod = require("./relative/name");
});

// Better yet, use the following shorter syntax for converting CommonJS modules:
define(function(require) {
    var mod = require("./relative/name");
});
Copy the code

CMD

CMD specification is ali yubo put forward, implement JS library for sea-.js. It is very similar to Requirejs in that a JS file is a module, but CMD loads better by loading on demand rather than having to load all dependencies at the start of the module. As follows:

define(function(require.exports.module) {
    var$=require('jquery');
    var Spinning = require('./spinning');
    exports.doSomething = ...
    module.exports = ...
})
Copy the code

Advantages:

Also realized the browser side modular loading.

Can be loaded on demand, depending on the nearest.

Disadvantages:

Depending on SPM packaging, the loading logic of modules is too heavy.

Module definition syntax:

define(id, deps, factory)
Copy the code

Because CMD advocates a per-file module, it often uses the filename as the module ID; CMD advocates nearby dependencies, so instead of writing dependencies in define parameters, you write them in Factory.

Factory takes three arguments:

function(require.exports.module){}
Copy the code
  1. The first argument to the require: factory function, require is a method that takes the module identity as a unique argument and is used to get interfaces provided by other modules;
  2. Exports: an object that provides module interfaces;
  3. Module: An object that stores properties and methods associated with the current module.
// Define the module mymodule.js
define(function(require.exports.module) {var$=require('jquery.js'The $()'div').addClass('active');
});

// Load the module
seajs.use(['myModule.js'].function(my){});Copy the code

4.1 Seajs

Seajs is a loader that follows the CMD specification modularized development, relies on autoloading, simple and clear configuration. SeaJS is a cmD-compliant JavaScript module loading framework, which can implement the modular development and loading mechanism of JavaScript.

Unlike JavaScript frameworks such as jQuery, SeaJS does not extend encapsulation language features, but simply implements modularization and module-loading of JavaScript. The main purpose of SeaJS is to make JavaScript development modular and easy to load, freeing the front-end engineer from heavy JavaScript file and object dependency processing and allowing him to focus on the logic of the code itself. SeaJS integrates perfectly with frameworks like jQuery. Using SeaJS can improve the readability and clarity of JavaScript code, solve the common problems of dependency disorder and code entanglement in JavaScript programming, and facilitate the writing and maintenance of code.

Basic application:

Import Seajs library

yarn add sea.js
Copy the code

Introduce seaJS at the end of the page:

<script src="/site/script/sea.js"></script>
Copy the code

Then write the module’s configuration and entry below it.

Seajs.use (".. /static/hello/src/main");Copy the code

Here’s what configuration and entry means:

configuration

Seajs paths and aliases are usually modified on configuration. The seaJS path is relative to the seaJS file introduced earlier. Suppose the directory structure looks like this:

examples/
|-- index.html
|
`--about
| |-- news.html
|
`-- script
|-- seajs.js
|-- jquery.js
`-- main.js
Copy the code

If we refer to main.js in index.html, the path would be script/main.js. If we refer to main.js from news.html, the path would be script/main.js. / script/main. Js.

In seaJS, the seaJS file is relative to the seaJS file, so use main.js directly.

Since it is so convenient, when do you need to configure it? You don’t need it in general. But it comes in handy if you have really deep paths or if you want to do path mapping. The following describes common configurations.

seajs.config({
// Sea.js base path (change this path to not be relative to seajs file)
    base: 'http://example.com/path/to/base/'.// Alias configuration (use variables to represent files, solve the path hierarchy is too deep and implement path mapping)
    alias: {
        'es5-safe': 'gallery/es5 - safe / 0.9.3 / es5 - safe'.'json': 'gallery/json / 1.0.2 / json'.'jquery': 'the jquery/jquery / 1.10.1 / jquery'
    },
// Path configuration (use variable to represent path, solve the problem of path hierarchy too deep)
    paths: {
        'gallery': 'https://a.alipayobjects.com/gallery'}});Copy the code

The entrance

The entry is the load, and what files need to be loaded (the module loader) is introduced here. Sea-.js automatically loads the entry module after downloading.

seajs.use("abc/main"); Seajs.js > seajs.js > seajs.js > seajs.js > seajs.jsCopy the code

Seajs.use () has another use.

Loading a single dependency

// Load the module main and execute the specified callback when the load is complete
seajs.use('./main'.function(main) {the main. The init (); });Copy the code

Loading multiple dependencies

Copy the code// Load modules A and B concurrently, and execute the specified callback when both are complete
seajs.use(['./a'.'./b'].function(a, b) {
    a.init();
    b.init();
});
Copy the code

Take two arguments: the first is a file dependency (a single string array is ok, multiple arrays are required), and the second is a callback function.

Seajs.use () can only be used to introduce modules in the first argument, and cannot be used to load modules in callback functions using require().

Module development

// All modules are defined with define
define(function (require.exports.module) {
  // introduce dependencies via require
  var$=require("jquery");
  var Spinning = require("./spinning");

  // Provides interfaces through exports
  exports.doSomething = 10;

  // The entire interface is available through module.exports
  module.exports = function a() {};
});
Copy the code

Modules are wrapped by the define() method, and then internally introduce the required dependency files (modules) through the require() method.

Native modularity (ECMAScript modularity)

ES6 has previously implemented modularity using RequireJS, a modularity library based on the AMD specification, and seaJS, a modularity library based on the CMD specification, both of which are intended to promote front-end modularity.

Now ES6 has its own modularity, it is the first time that JS supports Module, in a long time, we can directly import and export each module in the browser, a JS file represents a JS module;

Modern browsers support modules to varying degrees, and currently use babelJS or Traceur to convert ES6 code into ES5-compatible JS code.

Although there is not much difference between import and require at the moment, ES6 is still recommended, because es6 is going to be the mainstream in the future and it will be very easy to migrate code.

5.1 Modular Features of ES6

  1. Each module is loaded only once, and each JS is executed only once. If you load the same file under the same directory again next time, it will be read directly from the memory. A module is a singleton, or an object;
  2. Variables declared in each module are local variables and do not pollute the global scope.
  3. Variables or functions inside the module can be exported through export.
  4. A module can import other modules

Example: lib. Js

/ / export
export let msg = "Sum for:";
export function sum(n) {
  let total = 0;
  for (var i = 1; i <= n; i++) {
    total += i;
  }
  return total;
}
Copy the code
<body>
    <script type="module">
        / / import
        import {sum,msg} from './lib.js';
        let result=sum(100);
        console.log(msg+""+result);
    </script>
</body>
Copy the code
// Import all
import people from './example'  
  
There is a special case that allows you to import the entire module as a single object
// All exports of the module will exist as properties of the object
import * as example from "./example.js"  
console.log(example.name)  
console.log(example.age)  
console.log(example.getName())  
  
// Import section
import {name, age} from './example'  
  
// Export defaults with one and only one default
export default App  
  
// Partial export
export class App extend Component {};  

// Change the name when importing
import add as add1 from "./example.js" 
Copy the code

Do not use curly braces when importing:

  1. When exporting with export default people, import with import people (without curly braces);
  2. There can be only one Export default in a file. But there can be more than one export;
  3. When using export name, import {name} with curly braces;
  4. Import people, {name, age} when a file contains both an export default people and multiple export names or export ages.
  5. When there are more than n modules in a file, export exports many modules. In addition to importing modules one by one, you can also use import * as example.
  6. When exporting the interface, we can use XX as YY to change the name of the exported interface, for example, closureFn as sayingFn, and change the name of the interface to “you can know what to do without reading the document”.

UMD (Generic module definition)

UMD is called the Universal Module Definition. It also follows the trend towards a big front end, which allows the same code module to run at run time or compile time in projects using CommonJs, CMD or even AMD. In the future, the same JavaScript package running on the browser side, the server side, and even the APP side will only need to follow the same script.

It does not have its own specification, is a combination of CommonJs, CMD, AMD specifications in one, let’s look at the concrete implementation of it:

(function (root, factory) {
  if (typeof define === "function" && define.amd) {
    // AMD. Register as an anonymous module.
    define(["b"], factory);
  } else if (typeof module= = ="object" && module.exports) {
    // Node. Does not work with strict CommonJS, but
    // only CommonJS-like environments that support module.exports,
    // like Node.
    module.exports = factory(require("b"));
  } else {
    // Browser globals (root is window)
    root.returnExports = factory(root.b);
  }
})(this.function (b) {
  return {};
});
Copy the code

Notation 2 (Vue)

(function (global, factory) {
  typeof exports= = ="object" && typeof module! = ="undefined"
    ? (module.exports = factory())
    : typeof define === "function" && define.amd
    ? define(factory)
    : (global.Vue = factory()); }) (this.function () {
  return {};
});
Copy the code

6.1 UMD sample

6.1.1 Define the module utils.js

(function (global, factory) {
  if (typeof define === "function" && (define.amd || define.cmd)) {
    // AMD spec. Register an anonymous module compatible with AMD and CMD
    define([], factory);
  } else if (typeof module= = ="object" && module.exports) {
    //CommonJS, NodeJS runtime environment
    module.exports = factory();
  } else {
    // Browser global object registration
    global.UMD = factory();
  }
})(this.function () {
  var msg = "UMD!";
  // Returns the object to export
  return {
    show: function () {
      console.log("Hello "+ msg); }}; });Copy the code

6.1.2 Run under CommonJS specification

var utils=require('./Utils.js');
utils.show();
Copy the code

6.1.3 Run under AMD specifications

/ / configuration
requirejs.config({
  // Base path of module dependencies, default module loading location
  baseUrl:'js/'./ / path
  paths: {// If m/ is written before the path, it indicates js/module/
      m:"module/",}});// Module reference
require(['m/Tools'.'m/Utils'].function (mu) {
  mu.show();
});
Copy the code
<body>
    <script src="Js/require2.1.11. Js" data-main="js/app.js"></script>
</body>
Copy the code

Running results:

6.1.4 Run under CMD specification

seajs.config({
  // Base path of sea.js
  base: './javascript/module/'});// Reference module, dependency module
seajs.use(['Utils'].function (mu) {
  mu.show();
});
Copy the code
<body>
  <script src="js/sea.js"></script>
  <script src="js/main.js"></script>
</body>;
Copy the code

Running results:

6.1.5 Running in a native browser

<body>
    <script src="javascript/module/Utils.js"></script>
    <script>
        UMD.show();
    </script>
</body>
Copy the code

Running results:It can be seen from the above example that the module defined by UMD is compatible with CommonJS, AMD, CMD and browser native environment, as well as the front and back. The writing is not fixed and can be changed as needed.

NodeJS package manager

NPM opens the door for you and your team to connect to the entire world of JavaScript geniuses. It is the largest software registry in the world. Open-source software developers from all continents use NPM to share and learn from each other. The package structure makes it easy to track dependencies and versions.

Warehouse: www.npmjs.com/

7.1 summary of NPM

NPM, fully known as Node Package Manager, is a Node.js-based Package Manager, which is the most popular and supports the most third-party modules in the entire Node.js community.

NPM was originally intended to make it easier for JavaScript developers to share and reuse code.

Usage scenarios of NPM: Allows users to obtain third-party packages and use them. Allows users to publish and share their own packages or command-line programs. NPM -v NPM installation:

  1. Install nodeJS. Since the new nodeJS has integrated with NPM, you can directly test the installation by typing NPM -v.
  2. Use the NPM command to upgrade NPM: NPM install NPM -g.

7.2 Package

A package describes a file or a directory. A package configuration typically consists of: a folder containing a package.json configuration file; Contains a Gzip zip file (folder containing package.json files); Parse the URL of gzip; Add url information for @ to the registry.

7.3 Modules

A template contains one or more packages through a DOM node in a configuration file. It usually consists of packages and configuration files and related module programs to perform one or more business function operations.

A module can fill a Node.js program with any require().

Here is an example of all things loading modules:

  1. The package.json file contains a main field;
  2. A folder named index.js file;
  3. A JavaScript file.

7.4 ECOSYSTEM of NPM

The package.json file defines packages. The node_modules folder is where the modules are stored. Easy for JS to find modules.

If you create a node_modules/foo.js file, use var f=require(‘foo.js’) to load the module. Foo.js is not a package because it does not have a package.json file. If you don’t create the index.js or package.json file “main” field, even if you install node_modules, it’s not a module because it doesn’t require(). Common commands:

NPM install [-g] Local or global install modules NPM uninstall [-g] Local or global uninstall modules NPM update Update modules NPM ls View installed modules NPM list Lists installed modules NPM show Displays module details NPM info Displays module details NPM search Searches module NPM publish published module NPM unpublish Deletes published modules NPM -v or NPM version Displays version information NPM view NPM NPM install -g [email protected] / NPM update -g [email protected] Install the specified NPM version NPM init boot create a package.json file This includes name, version, author, etcCopy the code