Recently, my mental state is not very good, and I can’t sleep well at night, but I still can’t drop my study! After all, he who does not advance loses ground. No problem! Arrangement!!

1. Development of module writing method

  • The way I wrote it at the beginning
function m1() {... }function m2() {... }Copy the code

These two functions form a module, which is called directly when used, but it obviously pollens the global environment, so it is impossible to guarantee that variable name conflicts with other modules, and it is also impossible to see the dependency between each module.

  • Write it as an object
var module = new Object({
    _count: 0.m1: function() {
        / /...
    },
    m2: function() {
        / /...}});Copy the code

So module.m1(); But this exposes all module members, and internal code can be overwritten externally. For example, external code can directly change the value of the internal count :module1._count =5;

  • It is possible to do this without exposing private member variables using immediate functions
var module1 = (function() {var _count = 0;var m1 = function() {/ /...};var m2 = function() {/ /...};return{m1: m1,m2: m2}; }) ();Copy the code
  • Later, there was a wide amplification mode
var module = (function(mod) {/ /...
    returnmod; }) (window.module || {});
Copy the code

2. The emergence of modular specifications, currently: CommonJS module, AMD module and CMD module specifications.

  • CommonJs shortcomings and AMD background

This is not a problem on the server side because all modules are stored on the local disk and can be loaded synchronously. The wait time is the disk read time. For browsers, however, this is a big problem because modules are on the server side and the wait time can be long depending on the speed of the network, leaving the browser in a state of “suspended animation”. Therefore, browser-side modules cannot be synchronous, they can only be asynchronous. This is the background from which the AMD specification was born

var math = require('math');
math.add(2.3)
Copy the code
  • AMD writing (AMD advocates the dependency front, in the definition of the module should declare its dependency module)

AMD async module loading adopts async mode to load the module, and the module loading does not affect the running of the following statements. All statements that depend on this module are defined in a callback function that will not run until the load is complete. Require ([module], callback); The first argument, [module], is an array whose members are the modules to be loaded. The second argument, callback, is the callback function after the successful loading

require(['math'].function(math) {math. Add (2.3);
});
Copy the code

Math.add () is not synchronized with the Loading of the Math module, and the browser does not fake death. So clearly, AMD is a good fit for the browser environment. ==requireJS This JavaScript library implements the AMD specification ==

  • CMD (CMD advocates proximity, requiring only when a module is needed)

CMD has a browser implementation SeaJS that addresses the same problems as requireJS, but differs in how modules are defined and when they are loaded (run, parse, so to speak). A module is a file in CMD

define(function(require.exports.module) {

    // Module code

});
Copy the code

Require is a parameter that can be imported into other modules; Exports can export some properties and methods in modules. A module is an object that stores properties and methods associated with the current module.

// CMD defines the module
define(function(require.exports.module) {
    var a = require('./a')
    a.doSomething()
    // Omit 100 lines here
    var b = require('./b') // Dependencies can be written nearby
    b.doSomething()
    // ... 
})

// AMD defines modules
define(['./a'.'./b'].function(a, b) { Dependencies must be written in the beginning
    a.doSomething()
    // Omit 100 lines here
    b.doSomething()
        ...
})
Copy the code
// Define the module mymodule.js
define(function(require.exports.module) {
  var$=require('jquery.js'The $()'div').addClass('active');
  exports.data = 1;
});

// Load the module
seajs.use(['myModule.js'].function(my){
    var star= my.data;
    console.log(star);  / / 1
});
Copy the code

3. For AMD aboverequireJSinstructions

  • Why userequireJS
<script src="1.js"></script>
<script src="2.js"></script>
<script src="3.js"></script>
<script src="4.js"></script>
Copy the code

There are two disadvantages to loading this way: the browser will stop rendering the page at load time, and the more files you load, the longer the page will be unresponsive (the solution is below); Second, due to the dependencies between JS files, the loading order must be strictly guaranteed

  • RequireJS addresses dependencies

Require.js solves this problem with the async property stating that the file needs to be loaded asynchronously to prevent the page from becoming unresponsive. IE doesn’t support this property and only supports defer, so write defer as well. After loading require.js, we need to load our own code and write main.js, which is equivalent to the main () entry in C;

//main.js 
require(['moduleA'.'moduleB'.'moduleC'].function(moduleA, moduleB, moduleC) {// Omit 1000 lines of code here
});
Copy the code

The require() function takes two arguments. The first argument is an array of dependent modules, such as [‘moduleA’, ‘moduleB’, ‘moduleC’], where the main module depends on these three modules. The second argument is a callback function that will be called after all the 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. Require () asynchronously loads moduleA, moduleB, and moduleC without the browser losing its response; It addresses the dependency problem by specifying a callback function that will run only after all previous modules have been successfully loaded.

  • RequireJS customizes the loading behavior of modules using the require.config() method; Write it in the header of main.js.
require.config({paths: {
        // or write baseUrl: "js/lib" instead of lib
        "jquery": "lib/jquery.min"."underscore": "lib/underscore.min"."backbone": "lib/backbone.min"}});Copy the code
  • Many library modules do not conform to THE AMD specification so how to load?

Before loading them, you must define their features, such as underscore and backbone. Require.config () accepts a configuration object that, in addition to the paths property described earlier, has a shim property for configuring incompatible modules. Specifically, each module defines an (1) exports value (the name of the exported variable) that indicates the name of the external call to the module; (2) DEPS array, indicating the dependency of the module.

require.config({shim: {'underscore': {exports: '_'},'backbone': {deps: ['underscore'.'jquery'].exports: 'Backbone'}}});Copy the code

4. How to write module (using AMD specification), write module must be defined by the specific define() function

/ / math. Js moduledefine(function() {var add = function(x, y) {returnx + y; };return{add: add}; });Copy the code