Example analysis of js simple module loader

Keywords: Front-end Javascript Google

Front-end modularization

Families concerned about the development of front-end technology are certainly familiar with the term modular development. With more and more complex front-end projects and more code, modularization has become an inevitable trend.

Various standards

Because javascript itself does not set standards (of course, es6 already has import and export), various specifications have emerged in modularity. There are mainly AMD specifications (popularized with the birth of requirejs), CMD specifications (popularized with the emergence of seajs), and commonjs (mainly used for node s, not suitable for front-end). As for the similarities and differences of the above norms, shameless I do not spend much time here, please do not know the relatives themselves to find the father of google.

Simple module loader example

G point is coming!
Next, let's look at a sample code that suggests a module loader:

let Module = (() => {
    let module_list = {};
    function define(name,rely,callback){
        if (module_list[name]){
            console.log("The module have already existed!")
        }else{
            for(let i = 0;i < rely.length;i++){
                rely[i] = module_list[rely[i]];
            }
            module_list[name] = callback.apply(callback,rely);
        }
    }

    function require(name){
        if (module_list[name]){
            return module_list[name]
        }else{
            console.log("There is no such module!")
        }
    }

    let api = {
        "define":define,
        "require":require
    };
    return api;
})();

This is the implementation of the loader. Let's see how to use it again.

Module.define("test",[],()=>{
    function sayHello(name){
        return name+",How do you do";
    }
    return {
        "sayHello":sayHello
    }
})

Module.define("haha",[],()=>{
    function gotoHZ(name){
        return name+"I'm going to Hangzhou to play.";
    }
    return {
        "gotoHZ":gotoHZ
    }
})
Module.define("my_module",["test","haha"],(test,haha)=>{
    let name = "andrew";
    function sayHello2() {
        let str = test.sayHello(name);
        console.log(haha.gotoHZ("Zhang Wei"))
        str = str + ",It's a nice day today.";
        return str;
    }

    return {
        "sayHello2":sayHello2
    }
})

console.log(Module.require('my_module').sayHello2())
console.log(Module.require('test').sayHello("steve"))

In the above code, we define three modules named test, haha and my_module. See you here, if the foundation of js is not good, it may be a face of confusion, brain around dizziness.. First of all, let's take a look at the results of the operation:

The result is very simple. It prints out some information we want.

code analysis

Next, let's parse the code principle in detail.
Several key points in the loader,

  1. module_list

    Modul_list is an object that stores defined modules in the module name: callback
    Formal storage of key-value pairs;

  2. define function

    Then we define a definition function with three parameters: the module name, the module dependency list and the module callback function. When we call the definition function, we first check the module_list pair.
    If there is already a module with the same name in the image, if there is one, tell the user that the module name has been used directly. If not, we iterate through the dependent list. The operation in the loop is used to convert the dependent list from the name list to the real module list. Then we use the application function to pass it into the defined callback function one by one.

  3. require function
    Because our module_list exists in the internal scope, it guarantees the confidentiality of the module, and the external can't.
    Direct operation module list to read the module, so we define a require function, using closures to read and operate the corresponding module.

  4. Case analysis

    Module.define("my_module",["test","haha"],(test,haha)=>{
    let name = "andrew";
    function sayHello2() {
        let str = test.sayHello(name);
        console.log(haha.gotoHZ("Zhang Wei"))
        str = str + ",It's a nice day today.";
        return str;
    }
    
    return {
        "sayHello2":sayHello2
    }
    })

Here we define my_module, which depends on two modules: test and haha. In the callback function, we pass these two modules in. We can see that we can call the sayHello method of the test module and the gotoHZ method of the haha module. So far, a simple module loader has been implemented.

epilogue

This simple module loader simply introduces the basic principle of module loader implementation. Mature module loader is of course much more complex, but understanding the principle is the most important, isn't it

Posted by eazyGen on Sat, 06 Apr 2019 13:09:29 -0700