资讯专栏INFORMATION COLUMN

require 和 import 详解

wanghui / 2438人阅读

摘要:第二行,在第一行之后运行,因此必须等加载完成。类似于,但是是依赖就近,延迟执行,是依赖前置,提前执行。是一个文件名重命名导入成员名称标识符从已经存在的模块脚本文件等导入返回一个对象。

前言

JS模块化编程是前端小伙伴们必不可少的知识,下面妹子将于自认为比较清晰的方式列举出来。

1 require

特点:

1.运行时加载

2.拷贝到本页面

3.全部引入

1.1 CommonJS

Node.js就是用CommonJS思想。
在CommonJS中,有一个全局性方法require(),用于加载模块。

1.1.1 用法
var math = require("math");
math.add(2, 3);
var math = require("math");
const Math = new math(2, 3)
Math.add();
1.1.2 模块写法

模块写法分exports和module.exports。

exports.add = (x,y) => x+y;
module.exports = class math {
  constructor(x,y) {
    this.x = x;
    this.y = y;
  }

  add() {
    return  x+y;
  }
};
1.2 AMD

require.js和cujo.js就是用AMD思想。

AMD是”Asynchronous Module Definition”的缩写,意思就是”异步模块定义”。它采用异步方式加载模块,模块的加载不影响它后面语句的运行。所有依赖这个模块的语句,都定义在一个回调函数中,等到加载完成之后,这个回调函数才会运行。

第二行math.add(2, 3),在第一行require(‘math’)之后运行,因此必须等math.js加载完成。也就是说,如果加载时间很长,整个应用就会停在那里等。
这对服务器端不是一个问题,因为所有的模块都存放在本地硬盘,可以同步加载完成,等待时间就是硬盘的读取时间。但是,对于浏览器,这却是一个大问题,因为模块都放在服务器端,等待时间取决于网速的快慢,可能要等很长时间,浏览器处于”假死”状态。
因此,浏览器端的模块,不能采用”同步加载”(synchronous),只能采用”异步加载”(asynchronous)。这就是AMD规范诞生的背景。

1.2.1 用法
//require([module], callback);
require(["math"], function (math) {
 math.add(2, 3);
});
1.2.1 模块写法

define(id?, dependencies?, factory)

id:字符串,模块名称(可选)

dependencies: 是我们要载入的依赖模块(可选),使用相对路径。,注意是数组格式

factory: 工厂方法,返回一个模块函数

一个模块不依赖其他模块写法

// math.js
  define(function (){
    var add = function (x,y){
      return x+y;
    };
    return {
      add: add
    };
  });

模块还依赖其他模块

define(["a","b"], function(a,b){
    function foo(){
      a.doSomething();// 依赖前置,提前执行
      b.doSomething();
    }
    return {
      foo : foo
    };
  });
当require()函数加载上面这个模块的时候,就会先加载Lib.js文件。
1.3 CMD

sea.js就是用CMD思想。
CMD是"Common Module Definition"的缩写。类似于requirejs,但是seajs是依赖就近,延迟执行,requirejs是依赖前置,提前执行。

1.3.1 用法
seajs.config({
  alias: {
    "jquery": "http://modules.seajs.org/jquery/1.7.2/jquery.js"
  }
});

seajs.use(["./hello", "jquery"], function(hello, $) {
  $("#beautiful-sea").click(hello.sayHello);
});
1.3.1 模块写法
define(function(require, exports, module) {
  var $ = require("jquery");

  exports.sayHello = function() {
    $("#hello").toggle("slow");
  };
   var b = require("b");
   b.doSomething();    // 依赖就近,延迟执行
});
2 import

特点:

1.编译时加载

2.只引用定义

3.按需加载

可对比require的特点,发现import完胜require,推荐用import取代require
2.1.1 用法

import有两种模块导入方式:命名式导入(名称导入)和默认导入(定义式导入),以及 import()

import defaultMember from "module-name";
import * as name from "module-name";
import { member } from "module-name";
import { member as alias } from "module-name";
import { member1 , member2 } from "module-name";
import { member1 , member2 as alias2 , [...] } from "module-name";
import defaultMember, { member [ , [...] ] } from "module-name";
import defaultMember, * as name from "module-name";
import "module-name";

name-从将要导入模块中收到的导出值的名称

member, memberN-从导出模块,导入指定名称的多个成员

defaultMember-从导出模块,导入默认导出成员

alias, aliasN-别名,对指定导入成员进行的重命名

module-name-要导入的模块。是一个文件名

as-重命名导入成员名称(“标识符”)

from-从已经存在的模块、脚本文件等导入

import()

import()返回一个 Promise 对象。

// 报错
if (x === 2) {
  import MyModual from "./myModual";
}

引擎处理import语句是在编译时,这时不会去分析或执行if语句,所以import语句放在if代码块之中毫无意义,因此会报句法错误,而不是执行时错误。没办法像require样根据条件动态加载。
于是提案引入import()函数,编译时分析if语句,完成动态加载。

if(x === 2){
  import("myModual").then((MyModual)=>{
    new MyModual();
  })
}
2.2.1 模块写法

export有两种模块导出方式:命名式导出(名称导出)和默认导出(定义式导出),命名式导出每个模块可以多个,而默认导出每个模块仅一个。

export { name1, name2, …, nameN };
export { variable1 as name1, variable2 as name2, …, nameN };
export let name1, name2, …, nameN; // also var
export let name1 = …, name2 = …, …, nameN; // also var, const
 
export default expression;
export default function (…) { … } // also class, function*
export default function name1(…) { … } // also class, function*
export { name1 as default, … };
 
export * from …;
export { name1, name2, …, nameN } from …;
export { import1 as name1, import2 as name2, …, nameN } from …;

name1… nameN-导出的“标识符”。导出后,可以通过这个“标识符”在另一个模块中使用* import引用

default-设置模块的默认导出。设置后import不通过“标识符”而直接引用默认导入

-继承模块并导出继承模块所有的方法和属性

as-重命名导出“标识符”

from-从已经存在的模块、脚本文件…导出

参考资料

https://raoenhui.github.io/es6/2018/12/06/import

http://es6.ruanyifeng.com/#docs/module#import

https://www.cnblogs.com/liaojie970/p/7376682.html

Happy coding .. :)

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/99938.html

相关文章

  • 前端模块化详解

    摘要:提倡依赖前置,在定义模块的时候就要声明其依赖的模块。适用场景按需加载条件加载动态的模块路径注关于模块化,详细见阮一峰的入门模块与模块化区别模块化的规范和两种。 模块化开发方便代码的管理,提高代码复用性,降低代码耦合,每个模块都会有自己的作用域。当前流行的模块化规范有CommonJS,AMD,CMD,ES6的import/export CommonJS的主要实践者就是nodejs,一般...

    zhangfaliang 评论0 收藏0
  • 前端模块化详解(完整版)

    摘要:二模块化规范概述应用由模块组成,采用模块规范。模块化语法命令用于规定模块的对外接口,命令用于输入其他模块提供的功能。 前言 在JavaScript发展初期就是为了实现简单的页面交互逻辑,寥寥数语即可;如今CPU、浏览器性能得到了极大的提升,很多页面逻辑迁移到了客户端(表单验证等),随着web2.0时代的到来,Ajax技术得到广泛应用,jQuery等前端库层出不穷,前端代码日益膨胀,此时...

    Sanchi 评论0 收藏0
  • 前端模块化详解(完整版)

    摘要:二模块化规范概述应用由模块组成,采用模块规范。模块化语法命令用于规定模块的对外接口,命令用于输入其他模块提供的功能。 前言 在JavaScript发展初期就是为了实现简单的页面交互逻辑,寥寥数语即可;如今CPU、浏览器性能得到了极大的提升,很多页面逻辑迁移到了客户端(表单验证等),随着web2.0时代的到来,Ajax技术得到广泛应用,jQuery等前端库层出不穷,前端代码日益膨胀,此时...

    Pines_Cheng 评论0 收藏0
  • JavaScrip模块系统详解

    摘要:是一个字符串,它表示模块的标识。模块标准主要有两部分声明语法和可编程的加载配置模块如何以及有条件地加载模块模块的基础在的模块系统中,有两种命名的和默认的。 在这几天的工作中,我需要调用同事编写的兼容jQuery和React的通用组件。他为了兼容jQuery风格的调用和React的组件化,分别export了一个default和几个方法函数。在调用的过程中,出现了一些小插曲:React代码...

    testbird 评论0 收藏0
  • 【JS基础】一文看懂前端模块化规范

    摘要:参考资料前端模块化详解完整版入门近一万字的语法知识点补充彻底搞清楚中的和和详解 前言 前端的模块化之路经历了漫长的过程,想详细了解的小伙伴可以看浪里行舟大神写的前端模块化详解(完整版),这里根据几位大佬们写的文章,将模块化规范部分做了汇总和整理,希望读完的小伙伴能有些收获,也希望觉得有用的小伙伴可以点个赞,笔芯。 什么是模块 将一个复杂的程序依据一定的规则(规范)封装成几个块(文件)...

    HelKyle 评论0 收藏0

发表评论

0条评论

wanghui

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<