美文网首页
【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