听课笔记-模块化开发

认识模块化开发

1、模块化最终的目的是将程序划分成为一个个小的结构

2、这个结构中编写属于自己的逻辑代码,有自己的作用域,定义变量名词时不会用影响到其他结构

3、这个结构希望暴露自己的变量、函数、对象等导出给其他结构使用

4、也可以通过某种方式,导入另外结构中的变量、函数、对象

上面提到的结构,就是模块,按照这种结构划分开发程序的过程,就是模块化开发的过程

       commonJS

一、commonJS规范和node关系

1、CommonJS是一个规范,最初提出来是在浏览器以外的地方使用,并且当时被命名为ServerJS,后来为了体现其广泛性,修改为CommonJS,  简称为CJS

        (1) node是CommonJS在服务器端一个具有代表性的实现;

        (2)Browserify是CommonJS在浏览器中的一种实现;

        (3)webpack打包工具具备对CommonJS的支持和转换
2、所以,Node中对CommonJS进行了支持和实现,让我们在开发node的过程中可以方便的进行模块化开发:
        (1) 在Node中每一个js文件都是一个单独的模块

        (2) 这个模块中包括CommonJS规范的核心变量:exports、module.exports、 require;

        我们可以使用这些变量来方便的进行模块化开发
3、前面我们提到过模块化的核心是导出和导入,Node中对其进行了实现:

        (1) exports和module.exports可以负责对模块中的内容进行导出
        (2)  require函数可以帮助我们导入其他模块(自定义模块、系统模块、第三方库模块)中的内容

二、expoerts导出

exports是一个对象,可以在这个对象中添加多个属性,添加的属性会导出:bar.js文件

exports.name = name;
exports.age = age;
exports.num = num;

另一个文件可以导入;main.js文件(.js可以省略)

const bar = require('./bar');

        main中的bar变量等于exports对象,也就是require通过各种查找方式,最终找到了exports对象;,并且将这个export对象赋值给了bar变量bar变量就是exports对象了

三、module.exports导出

1、Node中我们经常导出东西的时候,又是通过module.exports导出的:module.exports和exports有什么关系或者区别呢?

2、我们追根湖源,通过维基百科中对CommonJS规范的解析:

        (1)CommonJS中是没有module.exports的概念的;

        (2)但是为了实现模块的导出,Node中使用的是Module的类,每一个模块都是Module的一个实例,也就是module;

        (3)所以在Node中真正用于导出的其实根本不是exports,而是module.exports;

        (4)因为module才是导出的真正实现者;

3、为什么exports也可以导出呢?

        (1) 这是因为module对象的exports属性是exports对象的一个引用

        (2) 也就是说 module.exports = exports =main中的bar;

四、require细节

1、require是一个函数,可以帮助我们引入一个文件(模块)中导出的对象

2、require的查找规则:导入格式require(X)

(1)情况一:X是一个Node核心模块,比如path、 http

           直接返回核心模块,并停止查找

(2)情况二:X是以./或../或根目录开头的

        第一步:将X当作文件在对应的目录下查找

                1、如果有后缀名,按照后缀名的格式1查找对应的文件

                2、如果没有后缀名,会按照如下顺序:

                        1>直接查找X文件

                        2>查找X.js文件

                        3>查找X.json文件

                        4>查找X.node文件

        第二步:没有找到对应的文件,将X作为一个目录

                查找目录下面的index.js文件

                        1>查找X/index.js文件

                        2>查找X/index.json文件

                        3>查找X/index.node文件

       如果没有找到,那么报错:not found

(3)情况三:直接是一个X(没有路径)并且不是一个核心模块

ES Module

一、认识ES Module

1、JavaScript没有模块化一直是它的缺陷,所以才会产生我们前面学习的社区规范:CommonJS、AMD、CMD等。

2、ES Module和CommonJS的模块化有一些不同之处:
        (1)一方面它使用了importexport关键字;
        (2)另一方面它采用编译期的静态分析,并且也加入了动态引用的方式

3、 ES Module模块采用export和import关键字来实现模块化:

        (1) export负责将模块内的内容导出
        (2) import负责从其他模块导入内容;

4、了解:采用ES Module将自动采用严格模式:use strict

二、export关键字

1、 export关键字将一个模块中的变量、函数、类等导出;

2、我们希望将其他中内容全部导出,它可以有如下的方式:
        (1)方式一:在语句声明的前面直接加上export关键字

export const name = "fh"
export const age = 18
export function sayHello() {
    console.log("sayhello")
}


        (2)方式二:将所有需要导出的标识符,放到export后面的{ }中

export {
    name,
    age,
    sayHello
}


         注意:这里的(里面不是ES6的对象字面量的增强写法,{ } 也不是表示一个对象的;

         所以:export (name: name),是错误的写法;

 
(3) 方式三:导出时给标识符起一个别名
                通过as关键字起别名

 export {
     name as fname,
     age as fage
     sayHello as fsayhello
 }

三、import关键字

1、import关键字负责从另外一个模块中导入内容(.js不可以省略)

2、导入内容的方式也有多种:
(1)方式一:import (标识符列表)from '模块';

import { name, age, sayHello } from "./foo.js"

               注意:这里的{}也不是一个对象,里面只是存放导入的标识符列表内容;

(2)方式二:导入时给标识符起别名

import { name as fname, age, sayHello } from "./foo.js"

  通过as关键字起别名

(3)方式三:通过*将模块功能放到一个模块功能对象 (a module object)上

import * as foo from "./foo.js"

四、export和import结合使用 

补充:export和import可以结合使用

export {sum as bar} from './bar.js';

(1)在开发和封装一个功能库时,通常我们希望将暴露的所有接口放到一个文件中;
(2)这样方便指定统一的接口规范,也方便阅读;
(3)这个时候,我们就可以使用export和import结合使用;

 五、default用法

1、前面我们学习的导出功能都是有名字的导出(named exports)

        (1)在导出export时指定了名字;
        (2)在导入import时需要知道具体的名字;

2、还有一种导出叫做默认导出 (default export)

        (1)默认导出export时可以不需要指定名字
        (2)在导入时不需要使用{},并且可以自己来指定名字
        (3)它也方便我们和现有的CommonJS等规范相互操作;

3、注意:在一个模块中,只能有一个默认导出(default export);

六、import函数

1、通过import加载一个模块,是不可以在其放到逻辑代码中的,比如:

if(true) {
    import sub from './bar.js'
}

为什么会出现这个情况呢?
(1)这是因为ES Module在被JS引擎解析时,就必须知道它的依赖关系;
(2)由于这个时候jS代码没有任何的运行,所以无法在进行类似于if判断中根据代码的执行情况;(3)甚至拼接路径的写法也是错误的:因为我们必须到运行时能确定path的值;


2、但是某些情况下,我们确确实实希望动态的来加载某一个模块:

(1)如果根据不同的条件,动态来选择加载模块的路径;
(2)这个时候我们需要使用 import() 函数来动态加载;
        注意: import函数返回一个Promise,可以通过then获取结果;

let flag = true;
if(flag) {
    import('./foo.js').then(foo => {
        foo.foo();
    })
} else {
    import('./bar.js').then(bar => {
        bar.bar();
    })
}

七、import meta

1、 import.meta是一个给JavaScript模块暴露特定上下文的元数据属性的对象。

(1)它包含了这个模块的信息,比如说这个模块的URL;
(2)在ES11 (ES2020)中新增的特性;


        



 

    




 

                      

                    


       

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值