프런트엔드 모듈의 역사 프로세스

모듈 메커니즘의 발생 원인


처음에 저희가 코드를 이렇게 썼어요.
function foo(){
    //...
}
function bar(){
    //...
}

Global이 오염되어 충돌이라고 명명하기 쉽다

단순 패키지: Namespace 모드

var MYAPP = {
    foo: function(){},
    bar: function(){}
}

MYAPP.foo();

이렇게 하면 Global의 변수 수를 줄이지만 본질은 대상이다

IIFE 모드

var Module = (function(){
    var _private = "safe now";
    var foo = function(){
        console.log(_private)
    }

    return {
        foo: foo
    }
})()

Module.foo();
Module._private; // undefined

다음에 우리는 모듈에 jquery의 인용을 전송하는 등 다른 의존을 도입할 수 있다
var Module = (function($){
    var _$body = $("body");     // we can use jQuery now!
    var foo = function(){
        console.log(_$body);    //  
    }

    // Revelation Pattern
    return {
        foo: foo
    }
})(jQuery)

Module.foo();

이것이 바로 모듈 모델이자 현대 모듈 실현의 초석이다.

script 로드

script(src="jquery.js")
script(src="app.js") 

처음에 우리가 script 탭으로 js를 불러오는 것은 이렇다. 이렇게 쓰는 단점은 순서가 매우 중요하고 가장 기본적인 의존은 맨 앞에 놓을 수 밖에 없다. 왜냐하면 브라우저는 가 웹 페이지에 나타난 순서에 따라 자바스크립트 파일을 읽고 바로 실행하기 때문이다.또한 브라우저는'동기화 모드'로 탭을 불러옵니다. 즉, 페이지가 막혀서 (blocking) 자바스크립트 파일이 불러올 때까지 기다립니다.만약 우리가 비동기적인 방식으로 js를 불러온다면, 또한onload의 리셋에서 js로 조정할 수 없는 방법을 초래할 것이다.이것은 몇 가지 문제를 가져왔다.
  • 유지하기 어렵다
  • 의존이 모호하다
  • 요청이 너무 많습니다

  • LABjs


    LABjs는 Javascript 로드를 보다 효과적으로 관리할 수 있도록 도와줍니다.LAB(Loading and Blocking), Loading은 비동기식 병렬 로드, Blocking은 동기식 실행 대기입니다.LAB는 우아한 문법(script와wait)을 통해 이 두 가지 특성을 실현했고 핵심 가치는 성능 최적화이다.LABjs는 파일 로더입니다.

    YUI


    모듈 기반 의존 관리를 위한 YUI
    // YUI - 编写模块
    YUI.add('dom', function(Y) {
      Y.DOM = { ... }
    })
    
    // YUI - 使用模块
    YUI().use('dom', function(Y) {
      Y.DOM.doSomeThing();
      // use some methods DOM attach to Y
    })

    YUI의 원리는 다음과 같다.
    // Sandbox Implementation
    function Sandbox() {
        // initialize the required modules
        for (i = 0; i < modules.length; i += 1) {
            Sandbox.modules[modules[i]](this);
        }
    }

    모든 의존 모듈은 attach를 통해 샌드박스에 주입됩니다. (attach: 현재 YUI 실례에서 모듈의 초기화 코드를 실행하여 모듈을 현재 실례에서 사용할 수 있도록 합니다.)즉,add 방법을 사용한 후에 YUI가 모듈을 초기화했다는 것이다.

    Combo

    script(src="http://yui.yahooapis.com/3.0.0/build/yui/yui-min.js")
    script(src="http://yui.yahooapis.com/3.0.0/build/dom/dom-min.js")

    우리가 해결해야 할 문제 중 하나는 스크립트 탭의 요청이 너무 많다는 것이다. 그러면 이런 방식을 통해
    script(src="http://yui.yahooapis.com/combo?
        3.0.0/build/yui/yui-min.js&
        3.0.0/build/dom/dom-min.js")

    이런 방식은 웹 서버의 지원이 필요하다.

    commonJs


    commonJs 표준은 브라우저뿐만 아니라 node에서도 해결됩니다.js에서 지원을 받았습니다.
    // math.js
    exports.add = function(a, b){
        return a + b;
    }

    사용할 때
    // main.js
    var math = require('math')      // ./math in node
    console.log(math.add(1, 2));    // 3

    특히 동기화 로드는 서버/로컬 환경에 전혀 문제가 되지 않습니다.

    AMD和CMD


    CMD(Common Module Definition)는 SeaJS가 모듈 정의에 대한 규범화 산출이고, AMD(Async Module Definition)는 RequireJS가 모듈 정의에 대한 규범화 산출이다.만약 require가 비동기적이라면 다음 코드는 오류를 보고할 것입니다.
    //CommonJS Syntax
    var Employee = require("types/Employee");
    
    function Programmer (){
        //do something
    }
    
    Programmer.prototype = new Employee();
    
    //如果 require call 是异步的,那么肯定 error
    //因为在执行这句前 Employee 模块根本来不及加载进来

    그래서 AMD에서 wrapper를 통해서.
    //AMD Wrapper
    define(
        ["types/Employee"],  //依赖
        function(Employee){  //这个回调会在所有依赖都被加载后才执行
            function Programmer(){
                //do something
            };
    
            Programmer.prototype = new Employee();
            return Programmer;  //return Constructor
        }
    )

    require.js

    // 在helper.js中
    define('helper', ['jquery'], function($){
        return {
            trim: function(str) {
                return $.trim(str);
            }
        }
    })

    첫 번째 매개 변수는 모듈 이름입니다. 쓰지 않으면 파일 경로를 모듈 이름으로 합니다. (상응하는require 호출에 의존하는 것은 경로 문자열입니다.)두 번째 파라미터는 모듈 의존이고 하나의 수조로 여러 개의 의존을 설정할 수 있다.마지막으로 모듈 의존 불러오기 후 세 번째 파라미터의 리셋을 터치합니다. 파라미터의 순서는 의존하는 모듈 순서입니다.리셋에서 모듈 결과를 되돌려줍니다.이제 로딩 모듈 한번 볼게요.
    // 在所需js文件中
    require(['helper'], function(helper){
        var str = helper.trim(' sysuzhyupeng ');
        console.log(str);
    });

    로드 모듈의 첫 번째 매개 변수는 의존하는 수조로 사용 방식과 정의 모듈은 기본적으로 일치한다.require.js는 baseUrl에 대한 주소로 모든 코드를 불러옵니다. 예를 들어 위에서 우리가 require를 할 때,helper 앞에 baseUrl 경로를 추가합니다.baseUrl에서 요구할 수 있습니다.js가 불러온 script 탭은 데이터-main 속성으로 설정할 수도 있고, 스스로 설정할 수도 있습니다.
    requirejs.config({
        baseUrl: '',
        paths: {
            'jquery': 'lib/jquery'
        }
    })

    그러면 비baseUrl 아래의 모듈은 paths 필드를 설정하여 경로를 지정할 수 있습니다.require.js는 탭으로 파일을 불러옵니다. cdn의 파일을 크로스 필드에서 얻을 수 있습니다.Require를 호출할 때, 불러오면 바로 실행합니다.AMD를 지원하지 않는 모듈은 설정 파일의shim 속성에서만 설정하면 됩니다.

    좋은 웹페이지 즐겨찾기