四.JS模块化开发


JS模块化开发

1.认识模块化开发

事实上模块化开发最终的目的是将程序划分成一个个小的结构

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

这个结构可以将自己希望暴露的变量、函数、对象等导出给其结构使用;[导出]

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

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

无论你多么喜欢JavaScript,以及它现在发展的有多好,它都有很多的缺陷:

  比如var定义的变量作用域问题;

  比如JavaScript的面向对象并不能像常规面向对象语言一样使用class;

  比如JavaScript没有模块化的问题;

对于早期的JavaScript没有模块化来说,确确实实带来了很多的问题;

模块化的历史 : 

  在网页开发的早期,Brendan Eich开发JavaScript仅仅作为一种脚本语言,做一些简单的表单验证或动画实现等,那个时候代码还是很少的:

    这个时候我们只需要讲JavaScript代码写到<script>标签中即可;

    并没有必要放到多个文件中来编写;甚至流行:通常来说 JavaScript 程序的长度只有一行

  但是随着前端和JavaScript的快速发展,JavaScript代码变得越来越复杂了:

    ajax的出现,前后端开发分离,意味着后端返回数据后,我们需要通过JavaScript进行前端页面的渲染

    SPA的出现,前端页面变得更加复杂:包括前端路由、状态管理等等一系列复杂的需求需要通过JavaScript来实现;

    包括Node的实现,JavaScript编写复杂的后端程序,没有模块化是致命的硬伤;

  所以,模块化已经是JavaScript一个非常迫切的需求:

    但是JavaScript本身,直到ES6(2015)才推出了自己的模块化方案

    在此之前,为了让JavaScript支持模块化,涌现出了很多不同的模块化规范:AMD、CMD、CommonJS

 

2.CommonJS(模块化方案[社区推出,还有人用])和node

CommonJS 是一个规范

导出 : exports

导入 : require

例子 : 

导出 : a.js

  let  name = 'yjx'

  funciton foo(){ }

  exports.name = name

  exports.foo = foo 

导出 : const  aa = require('./a.js')

  console.log(aa.name)

  console.log(aa.foo)
优化 :
  const {name,foo} = require('./a.js')
  console.log(name)

  console.log(foo)

Node,Browserify,webpack 都有实现过CommonJS的规范.  浏览器没有实现过(所以不能用)

 

进阶 : 

  其实我们通常用的是 module.exports , 而不是exports  .  在CommonJS中是没有module.exports的,但是node加了module类

  所以 :  require(”)  ==>  指向的是module.export  而不是export

  默认情况下 : module.exports = exports 

  正式中,我们采用的代码是这样的 :  [都是采用module.export的用法]

导出 : a.js

  let  name = 'yjx'

  funciton foo(){ }

  module.exports =  {
            name,
            foo
     }


导出: 
  const {name,foo} = require('./a.js')
  console.log(name)
  console.log(foo)        

 

require的查找过程 :   导入格式如下:require(X)

  1:X是一个Node核心模块,比如path、http 直接返回核心模块,并且停止查找

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

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

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

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

        1> 直接查找文件X

        2> 查找X.js文件

        3> 查找X.json文件

        4> 查找X.node文件

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

      查找目录下面的index文件

        1> 查找X/index.js文件

        2> 查找X/index.json文件

        3> 查找X/index.node文件

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

  3:直接是一个X(没有路径),并且X不是一个核心模块 [axios]

    那么就会通过 node_modules  文件夹查找了

    [ npm i  下载的都存在这个文件夹,会找当前目录的node_modules,没有,再找上层..上上层..直到根目录,如果没有找到,那么报错:not found]

 

模块的加载过程 : 四.JS模块化开发

 

 CommonJS的缺点

  CommonJS加载模块是同步的

    同步的意味着只有等到对应的模块加载完毕,当前模块中的内容才能被运行;

    这个在服务器不会有什么问题,因为服务器加载的js文件都是本地文件,加载速度非常快;

  如果将它应用于浏览器呢?

    浏览器加载js文件需要先从服务器将文件下载下来,之后再加载运行;

    那么采用同步的就意味着后续的js代码都无法正常运行,即使是一些简单的DOM操作;

  所以在浏览器中,我们通常不使用CommonJS规范

    当然在webpack中使用CommonJS是另外一回事; 因为它会将我们的代码转成浏览器可以直接执行的代码;

  在早期为了可以在浏览器中使用模块化,通常会采用AMD或CMD(使用很少),现在基本用ES Modules

    但是目前一方面现代的浏览器已经支持ES Modules,另一方面借助于webpack等工具可以实现对CommonJS或者ES Module代码的转换;

    AMD和CMD已经使用非常少了;

 

3.AMD和CMD(了解,模块化规范[社区推出,已经不用了])

AMD主要是应用于浏览器的一种模块化规范:

   AMD是Asynchronous Module Definition(异步模块定义)的缩写;

  它采用的是异步加载模块;

  事实上AMD的规范还要早于CommonJS,但是CommonJS目前依然在被使用,而AMD使用的较少了;

我们提到过,规范只是定义代码的应该如何去编写,只有有了具体的实现才能被应用: AMD实现的比较常用的库是require.js和curl.js

 

CMD规范也是应用于浏览器的一种模块化规范:

  CMD 是Common Module Definition(通用模块定义)的缩写;

  它也采用的也是异步加载模块,但是它将CommonJS的优点吸收了过来;

  但是目前CMD使用也非常少了;

CMD也有自己比较优秀的实现方案:SeaJS

 

4.ESModule用法详解(ES6标准推出来的模块化方案 重点)

 

5.ESModule运行原理

 

原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/279415.html

(0)
上一篇 2022年8月7日
下一篇 2022年8月8日

相关推荐

发表回复

登录后才能评论