美文网首页
js模块化

js模块化

作者: koala949 | 来源:发表于2020-11-22 22:00 被阅读0次

早期将js代码放入不同的文件里面,通过多个srcipt标签来加载他们

<script src='./a.js'></script>

虽然每个代码块出在不同的文件中,但最终所有的js变量还是会处在全局作用域下,就需要额外注意由于作用域变量提升所带来的问题。如果代码之间有依赖关系,则需额外注意脚本加载的顺序。
为解决这样的问题,我们需要将这些脚本文件模块化:

  • 每个模块有自己的变量作用域
  • 不同模块之间保留相互导入和导出的方式方法。

commonJs规范初探

nodejs就是一个基于V8引擎,事件驱动I/O的服务端js运行环境,在09年刚推出时,就实现了一套CommomJs的模块化规范

每个js就是一个模块(module,每个模块内部使用require函数和module.exports对象对模块进行导入导出
在不同的模块加载moduleB两次,会得到相同的结果,这说明他保证了模块单例。
commonJs是一个同步加载模块的模块化规范,每当一个模块require一个子模块时,都会停止当前模块的解析直到子模块读取解析并加载

适合web开发的AMD模块化规范

asynchronous module definition 意为 异步模块定义,因为如果在浏览器中也使用同步加载,那么页面在解析脚本文件的过程中可能会使页面暂停响应。

AMD规范举例

// index.js
// require函数第一个参数是 入口模块的依赖列表, 第二个参数作为回调函数依次传入前面依赖的导出值,不同于CommonJS的是,这个回调函数的返回值即时模块导出结果

require(['moduleA','moduleB'], function (moduleA, moduleB){
  console.log(moduleB)
})

// moduleA.js
define(function(require){
  var  = require('moduleB')
  setTimeOut(() => console.log(m), 1000)
})

// moduleB.js
define(function(require){
   var m = new Data().getTime();
   return m
})

Nodejs里直接通过node index.js可查看输出结果,在web端我们需要一个html文件,同时在里面加载这个入口模块, 如果想使用AMD规范, 还需要在页面中添加符合AMD规范的加载器脚本

<script src="/require.js"></script>

直接起到服务器里命令

python -m SimpleHTTPServer 8080

从结果上来说 AMD和CommonJs一样,完美解决了变量作用域和依赖关系之类的问题,但是这种AMD默认异步, 在回调函数中定义模块内容, 相对来说使用就麻烦些。
同时, AMD的模块不能直接运行在node端,因为内部的define函数,require函数都必须配合在浏览器中加载require.js这类ADM库才能使用。

能同时被CommonJs规范和AMD规范加载的UMD模块

有时候我们希望写的模块能同时运行在浏览区端和NodeJs里,使用UMD(universal module definition)作为一种同构的模块化解决方案,在一个地方定义模块内容,同时兼容ADM和CommonJS规范

需要判断一下这些模块化规范的特征值,判断出当前究竟在哪种模块化规范的环境下,然后把模块内容用检测出的模块化规范的语法导出

// 写法不固定
(function(self, factory){
   if(typeof module === 'object' && typeof module.exports === 'object'){
   module.exports  = factory()
} else if ( typeof define === 'function' && define.amd){
  define(factory)
} else {
  // 什么环境也不是,直接挂在全局对象上
  self.umdModule = factory()
}
})( this, factory){
   return function(){
     retrun Math.randow()
  }
}

ESModule规范

es6之后,js有了语言层面的模块化导入导出关键词和语法以及匹配的esModule规范。
示例:

// index.js
import './moduleA';
import m from './moduleB'
console.log(m)


//moduleA.js
import m from './moduleB'
setTimeOut(()=> console.log(m), 1000)

// moduleB.js
  var m = new Data().getTime();
  export default m


// import { var1 as customVar } from './moduleA'

// 以下用法合理 因为commonJs导出的就是个对象
const { var1 = 1} = require('./moduleA')
const { [test]: var1: a} = require('./moduleA')

每个js运行环境都有一个解析器,他的作用就是用ECAMScript规范去解释js语法,也就是处理和执行语言本身的内容。在解析器上层,每个运行环境都会在解释器的基础上封装一些环境相关的API。

esModule是高版本工具,需要使用babel转义,对于模块化的importexport关键字,bebal最终会将他编译为包含require和export的commonJs规范,这就造成了另外一个问题, 这些关键字编译之后无法运行在浏览器中, 我们还需要一个步骤 打包,比如打包工具webpack/rollup,这样编译工具babel和他们的区别和作用就清楚了

  • 打包工具主要处理的是js不同版本间模块化的区别
  • 编译工具主要是处理JS版本间语义的问题

如果使用了ESModule:必须使用webpack和babel
如果是AMD或CommonJs:只用webpack

相关文章

  • 模块化开发

    js模块化开发vue模块化开发

  • Javascript 模块化

    Javascript 模块化发展的历史精读 js 模块化发展直接定义依赖 (1999): 由于当时 js 文件非常...

  • js模块化规范

    title: js模块化date: 2019-01-30 17:49:22tags: js 1.无模块化 缺点:1...

  • js 模块化

    尚硅谷_JS模块化 笔记

  • 06Vue的前端工程化

    Vue的前端工程化 一 模块化规范 1.1模块化规范举例 浏览器端JS模块化规范:AMD,CMD 服务器端JS模块...

  • 模块化开发

    什么是模块化? 模块化就是讲js文件按照功能分离,根据需求引入不同的文件中。源于服务器端。 js模块化方案有AMD...

  • 前端模块化

    在学node.js, 实际上就是基于common.js开发的,所以了解了一下模块化开发。 JS的模块化初衷和所有语...

  • 04-webpack核心基础-ES6模块化

    一、模块化概述 在ES6出现之前,JS不像其他语言拥有“模块化”这一概念,于是为了支持JS模块化我们使用类、立即执...

  • 前端javascript模块化

    JavaScript js 模块化 关于js模块化的理解写法一 写法二 写法三 写发四(不推荐) 写发五 (错误写...

  • 做了这么久的前端开发,听过Css模块化开发么?

    说起前端模块化开发,大部分人可能只会想到js模块化开发吧,网上也确实有各种各样的js模块化方法,但是鲜有谈论Css...

网友评论

      本文标题:js模块化

      本文链接:https://www.haomeiwen.com/subject/ytxpiktx.html