[关闭]
@c-Ku 2017-11-05T07:41:34.000000Z 字数 2480 阅读 659

【JS基础】JS模块化杂记

Javascript


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

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

  1. var MYNAMESPACE = {
  2. PEOPLE: {
  3. person: function(name) {
  4. this.name = name;
  5. this.getName = function() {
  6. return this.name;
  7. }
  8. }
  9. },
  10. PET: {
  11. dog: function(petName) {
  12. this.petName = petName;
  13. this.getPetName = function() {
  14. return this.petName;
  15. }
  16. }
  17. }
  18. };
  19. var MYNAMESPACE = MYNAMESPACE || {};

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

  1. // 共生
  2. (function (root, factory) {
  3. if (typeof define === 'function' && define.amd) {
  4. // AMD
  5. define(['jquery', 'underscore'], factory);
  6. } else if (typeof exports === 'object') {
  7. // Node, CommonJS之类的
  8. module.exports = factory(require('jquery'), require('underscore'));
  9. } else {
  10. // 浏览器全局变量(root 即 window)
  11. root.returnExports = factory(root.jQuery, root._);
  12. }
  13. }(this, function ($, _) {
  14. // 方法
  15. function a(){}; // 私有方法,因为它没被返回 (见下面)
  16. function b(){}; // 公共方法,因为被返回了
  17. function c(){}; // 公共方法,因为被返回了
  18. // 暴露公共方法
  19. return {
  20. b: b,
  21. c: c
  22. }
  23. }));

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

var a = require('a');

  1. // AMD
  2. define(['./a', './b'], function(a, b) { // 依赖必须一开始就写好
  3. a.doSomething()
  4. // 此处略去 100 行
  5. b.doSomething()
  6. });
  7. // CMD
  8. define(function(require, exports, module) {
  9. var a = require('./a')
  10. a.doSomething()
  11. // 此处略去 100 行
  12. var b = require('./b')
  13. // 依赖可以就近书写
  14. b.doSomething()
  15. });

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

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


import

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

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

部分用法参见 解构赋值

export

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

  1. export default function() {}
  2. export function a () {}
  3. var b = 'xxx';
  4. export { b }; // {b: b}
  5. setTimeout(() => b = 'ooo', 1000);
  6. export var c = 100;

as关键字

  1. // a.js
  2. var a = function() {};
  3. export {a as fun};
  4. // b.js
  5. import {fun as a} from './a';
  6. a();
  7. // c.js
  8. export function fun() {};

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

define

在 import 时写这样

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

在 export 时写这样

  1. // d.js
  2. export default function() {}
  3. // 等效于:
  4. function a() {};
  5. export {a as default};

*

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

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

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

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

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注