模块化的学习和理解

最近在看vue源码,然后看到了rollup,然后又看到了模块化的概念,所以对模块化的概念进行一个学习和总结。以下就是我的学习成果,如果有什么不对的欢迎指教。

模块化概念

模块化存在的意义:开发者希望在开发过程中只需要关注自己的核心业务逻辑,其他的可以直接加载别人写好的模块。但是Javascript不是一种模块化编程语言,在es6以前,它是不支持”类”(class),所以也就没有”模块”(module)了(借鉴而来)

nodejs一个应用于服务器端编程被提出时,Javascript模块化也因此诞生,CommonJS模块规范被提出。在es6模块之前,CommonJS统一了模块化编程。

下面我要简述一下CommonJS、AMDCMD和ES6 Module

同步加载 CommonJS

在CommonJS中有一个全局的方法require(),可以用于加载模块。但是这个方法在浏览器端具有一定的局限性,因为JavaScript是解释性语言,从上而下直接执行。此时的困惑是

后来我得到的答案:

最后我的笔记: CommonJS是一种同步加载的方式,在服务器端模块是存在本地的,这样读取时间很快,需要等待时间很短,可以是同步加载,但是在浏览器端,依赖的模块是存放在服务器端的,读取的时间依赖网速,如果网速不好的话,需要等待很久。javascript就会报错了,所以在浏览器端需要异步加载的方式

module.exports和exports 模块导出

let num = 0
function add (a, b) {
  return a + b
}
module.exports = {
  num: num,
  add: add
}

exports 和 module.exports的区别:Node为每一个模块都提供了一个exports变量,指向module.exports。

以上的写法module.export尝试写成:

// 结果报错
let num = 0
function add (a, b) {
  return a + b
}
exports = {
  num: num,
  add: add
}

第二种写法:

// 结果成功
let num = 0
function add (a, b) {
  return a + b
}
exports.num = num
exports.add = add

node中,exports指向module.exports。如果直接将一个对象赋值给exports,那么exports原先指向module.exports会被破坏,这样这两种之间就没有联系了,就会报错。如果非要想用exports的话,可以直接给exports添加属性。

require 模块导入

let math = require('./math')

异步加载

  • AMD/RequireJS 异步加载 依赖前置、提前执行
  • CMD/sea.js 异步加载 依赖就近、延迟加载

ES6 Module

import 导入

常见用法:

// 全部加载
import * as util from 'xxx'
import AA from 'yyy'
// 按需加载
import { A, B } from 'xxx'

import * as aa from 'xxx'的语法,会将xxx文件内export的函数整合成一个对象。 import AA from 'yyy',引入的是export default的函数

import 在编辑时就执行的,所以:

foo()
import { foo } from 'xxx'

不会报错,因为import { foo } from 'xxx'在编辑时就执行了,foo()是在运行时才执行。

import()

import命令是在编辑时就会执行的,所以无法做到放到if代码中或者函数中,

if (a) {
    import { foo } from 'xxx'
}
// 会报句法错误

import export只能在模块的顶层,不可以在代码块中,这样就无法实现运行时动态加载模块(条件加载)。=> import()的出现 使用import()可以类似node里的require(),可以动态加载且import()是异步加载。import()加载模块成功以后,这个模块会作为一个对象当then方法的参数。

import('xxx').then(module => {
    ...
})

export 暴露模块

export 规定的时对外的接口,必须模块内部的变量建立一一对应关系。看到阮一峰大佬的内容里有这么一段:

目前还是不很理解:为什么export var m = 1 或者export function aa (){}就可以建立一一对应的关系。

CommonJS和ES6 Module的区别

之前一直没有考虑过他们之前的区别,今天又仔细研读了一下阮一峰的es6关于模块的讲解,觉得说的很好。 ES6的设计思想是尽量的静态化,在编译时就可以确定模块之间的依赖关系,以及输出和输入的变量CommonJS、AMD、CMD只能在运行时才可以确定模块之间的加载关系

// CommonJS
let { stat, exists, readFile } = require('fs');
// ES6
import { stat, exists, readFile } from 'fs';

第一个和第二的区别: CommonJS是将fs模块整体加载出来生成一个对象,然后在这个对象读取里找stat, exists, readFile方法,这种就是运行时加载ES6模块会只在fs中加载stat, exists, readFile这三个方法,不会加载其他方法,这种就是编辑时加载

原文链接:segmentfault.com

上一篇:【前端早读会】每天记录前端学习的过程
下一篇:js使用xpath

相关推荐

  • 🔥 从最近流行的一幅 CSS 风景画中学习 2 个知识点

    最近 CodePen 流行的一张用纯 CSS 绘制的风景画令人印象深刻: (/public/upload/d250206ad61c150f0fbec8efcd474c2a) 天空的眩光,睡眠反...

    2 个月前
  • (转载)如何通俗易懂的理解Redux

    作者:Wang Namelos 链接:https://www.zhihu.com/questio...(https://www.zhihu.com/question/41312576/answer/9...

    2 年前
  • (vuejs学习)2、使用ElementUI(*)

    1.element安装 开发环境是win10,一到node官网下载node的.msi包(https://npm.taobao.org/mirrors/node/v10.16.0/nodev10.16....

    10 个月前
  • (vuejs学习)1、Vue初上手(*)

    参考《官方(https://cli.vuejs.org/zh/guide/installation.html)》官方: Node 版本要求: Vue CLI 需要 Node.js 8.9 或更高...

    10 个月前
  • 项目过程中的小学习

    1.将多个同类元素分行,每一行有两个或者多个元素,可用li标签实现此 效果如下: clipboard.png(https://img.javascriptcn.com/a1466689a56d4...

    2 年前
  • 面试:彻底理解Cookie以及Cookie安全

    Cookie是什么 Cookie是服务端发送到用户浏览器并且保存到本地的一小块数据,它会在浏览器下次向同一服务器发起请求时,被携带到服务器上。 它的作用: 经常用来做一些用户会话状态管理、个性化设...

    2 个月前
  • 面试深入一、ES6模块化、安装和打包

    开发环境已经普及使用 浏览器环境却支持不好(需要开发环境编译) 内容很多,重点了解常用语法 面试:开发环境的使用 重点语法的掌握 问题 模块化如何使用...

    2 年前
  • 面试必须了解的前端模块化演进历程

    阅读提示: 本文很多外链需要科学上网访问 对于 JavaScript 新手,看到 "CommonJS vs AMD" 、"Requirejs vs Seajs"、"Webpack vs. Brow...

    4 个月前
  • 面试官:聊聊对Vue.js框架的理解

    前言 今年OKR定了一条KR是每一个季度进行一次前端相关技术的分享,还有十几天就到2020年了,一直忙于业务开发,没有时间准备和学习高端话题,迫于无奈,那就讲讲平时使用频率较高,却没有真正认真的了解其...

    6 个月前
  • 面试官: 说说你对async的理解

    大家好,我是小雨小雨,致力于分享有趣的、实用的技术文章。 内容分为翻译和原创,如果有问题,欢迎随时评论或私信,希望和大家一起进步。 分享不易,希望能够得到大家的支持和关注。

    2 个月前

官方社区

扫码加入 JavaScript 社区