美文网首页
【JS基础】JS模块化杂记

【JS基础】JS模块化杂记

作者: 六毫笙 | 来源:发表于2017-11-05 15:41 被阅读0次

    参 照:
    http://www.jianshu.com/p/554454d951d9
    http://blog.csdn.net/xcymorningsun/article/details/52709608
    http://imweb.io/topic/582293894067ce9726778be9
    https://juejin.im/entry/58aa60182f301e006c32bb97

    最 新:
    https://www.zybuluo.com/c-Ku/note/938733

    最初的JS用来实现简单的页面逻辑,因而放在页面中的 <script> 标签内,或是通过该标签来进行调用。每一个通过 <script> 标签调用的文件此时可被看成单个模块,不同模块的接口都暴露在全局作用域(window)下,污染了全局作用域,文件只能按照script标签书写顺序进行加载,且在大型项目中冗杂堆积,可维护性差

    为了在一定程度上避免问题,通常会采用 命名空间 的形式,比如:

    var MYNAMESPACE = {
        PEOPLE: {
            person: function(name) {
                this.name = name;
                this.getName = function() {
                    return this.name;
                }
            }
        },
        PET: {
            dog: function(petName) {
                this.petName = petName;
                this.getPetName = function() {
                    return this.petName;
                }
            }
        }
    };
    
    var MYNAMESPACE = MYNAMESPACE || {};
    

    后来有了AMD(国外),CMD(国内),CommonJS(服务器端)等规范,这些(野生)规范的核心是允许模块通过 require方法 来同步加载所要依赖的其他模块,然后通过 exportsmodule.export 来导出需要暴露的接口。

    // 共生
    (function (root, factory) {
    
        if (typeof define === 'function' && define.amd) {
    
            // AMD
            define(['jquery', 'underscore'], factory);
    
        } else if (typeof exports === 'object') {
    
            // Node, CommonJS之类的
            module.exports = factory(require('jquery'), require('underscore'));
    
        } else {
    
            // 浏览器全局变量(root 即 window)
            root.returnExports = factory(root.jQuery, root._);
    
        }
    
    }(this, function ($, _) {
    
        // 方法
        function a(){}; // 私有方法,因为它没被返回 (见下面)
    
        function b(){}; // 公共方法,因为被返回了
    
        function c(){}; // 公共方法,因为被返回了
    
        // 暴露公共方法
        return {
            b: b,
            c: c
        }
     
    }));   
    

    AMD要求在头里引入依赖(依赖前置,提前执行)
    CMD可在编写过程中引入依赖(依赖就近,延迟执行)

    var a = require('a');

    // AMD
    define(['./a', './b'], function(a, b) {  // 依赖必须一开始就写好  
       a.doSomething()    
       // 此处略去 100 行    
       b.doSomething()
    });
    
    // CMD
    define(function(require, exports, module) {
       var a = require('./a')   
       a.doSomething()   
       // 此处略去 100 行   
       var b = require('./b') 
       // 依赖可以就近书写   
       b.doSomething()
    });
    

    ES6发布后,module成为标准
    标准的使用以import引入模块
    以export导出接口

    在Node.js中,使用CommonJS规范,
    因而使用require引入模块,
    使用module.exports导出接口


    import

    ES6中,import需放在文件头部,且前面不允许有其他逻辑代码。

    import $ from 'jquery';
    import * as _ from '_';
    import {a,b,c} from './a';
    import {default as alias, a as a_a, b, c} from './a';
    

    部分用法参见 解构赋值

    export

    如下的语句中,b 在 export 仍可被修改。

    export default function() {}
    export function a () {}
    
    var b = 'xxx';
    export { b }; // {b: b}
    setTimeout(() => b = 'ooo', 1000);
    export var c = 100;
    

    as关键字

    // a.js
    var a = function() {};
    export {a as fun};
    
    // b.js
    import {fun as a} from './a';
    a();
    
    // c.js
    export function fun() {};
    

    通过「取别名」的方式来解决不同接口重名的问题
    在 import 和 export 中皆可使用。

    define

    在 import 时写这样

    import a from './d';
    
    // 等效于,或者说就是下面这种写法的简写,是同一个意思
    import {default as a} from './d';
    

    在 export 时写这样

    // d.js
    export default function() {}
    
    // 等效于:
    function a() {};
    export {a as default};
    

    *

    这个符号用于继承某一个模块全部的接口
    比如:

    import * as _ from '_';
    
    _.func()    // 调用
    

    「require是赋值过程,import是解构过程」
    至于「该用require还是import?」这个问题
    目前而言,所有的引擎都还没有实现import
    node中是使用了babel将ES6转码为ES5再执行
    import语法会被转码为require。

    因而在模块导出时使用module.exports
    在引入时使用import仍然起效
    本质上,import会被转码为require去执行。

    相关文章

      网友评论

          本文标题:【JS基础】JS模块化杂记

          本文链接:https://www.haomeiwen.com/subject/ytthmxtx.html