模块出现原因

简单概述

随着 Web 2.0 时代的到来,JavaScript 不再是以前的小脚本程序了,它在前端担任了更多的职责,也逐渐地被广泛运用在了更加复杂的应用开发的级别上。

但是 JavaScript 缺乏一个最重要的模块机制,虽然它能够通过 <script> 标签重新组织代码和结构,但是依旧没有解决变量污染的问题,标签只作用于代码层面。在其他高级语言中,Java 有类文件,Python 有 import 机制,Ruby 有 require,PHP 有 include 和 require。所以 JavaScript 开发人员不得不用命名空间等方式人为地约束代码,已达到安全和易用的目的。

变量污染

在文件形式上这些不同文件的 js 以不同的身份存在着的,但是一旦引入到同一个 index.html 文件之后,如果其中两个 js 文件中声明了同名变量 c ,由于 <script> 标签并不会为每个 js 文件单独划分私有作用域,它们被全部组织到一个作用域内,(可以把 index.html 看作一个作用域)。所以,在运行期间,浏览器将抛出 SyntaxError 错误,即变量 c 已被声明。

a.js 文件:

  1. // a.js
  2. let c = 10

b.js 文件:

  1. // b.js
  2. let c = 11

在 index.html 中引入 js 文件:

  1. <script src="../../../static/js/chap06/a.js"></script>
  2. <script src="../../../static/js/chap06/b.js"></script>

两个变量 c 声明冲突,所以抛出异常:

经过数年的发展后,Mozilla 工程师 Kevin Dangoor 在 2009年8 月,发布了 CommonJS 规范,它的出现是 JavaScript 发展的重要的里程碑。

Node.js 模块

在 JS 中,方法可以形成一个闭包,使该作用域内的所有变量、方法等都限定在区域内,外界无法直接访问到这个作用域中的东西。

一个 .js 文件就是一个模块。

  1. let a = 10
  2. let b = 5
  3. module.exports.a = a
  4. module.b = b
  5. console.log(arguments)
  6. console.log(arguments.callee())

实际上,我们写的所有内容都存放在一个函数里,Node.js 自动为我们封装函数内的代码。通过调用 arguments.callee() 可以获得当前正在执行的函数。

  1. function (exports, require, module, __filename, __dirname) {
  2. let a = 10
  3. let b = 5
  4. module.exports.a = a
  5. exports.b = b
  6. console.log(arguments)
  7. console.log(arguments.callee + '')
  8. }

Node.js 将模块放进了一个函数内,通过函数形成的闭包,避免变量污染等问题。

ES6 模块

现在,最新的浏览器开始原生支持模块功能了,并且 Node.js 也支持了 ES6 的模块机制了,前提是在 package.json 中有 "type": "module"。如果在 html 页面中引入了一个 .js 文件,并且文件中用到了 ES6 的模块机制,就必须在 script 标签中添加 type="module"。

export 为导出变量和方法,import 用于引入一个模块(.js 文件)。

export

export 可以一一地对变量和方法导出,也可以在文件最后用 {} 来一次性导出这些变量和方法。

一次性导出:

  1. let a = 10
  2. let b = 10
  3. export {a, b}

或一一导出:

  1. export let a = 10
  2. export let b = 10

export 导出时,可以为这些变量和方法重命名。

  1. export {a as _a, b as _b}

export default

export default 方式的导出在一个模块中只能有一个。

  1. export default let msg = 'hello world!'

import

import 导入 export default 方式导出的变量不需要加 {},可以重命名;export 方式导出的需要加 {},也可以重命名。

  1. import msg from 'b.js'
  2. // import {default as msg} from 'b.js'
  3. import {a, b} from 'a.js'
  4. // import {a as _a, b as _b} from 'a.js'

NPM 包管理

Node 组织了自身的核心模块,也使得第三方文件模块可以有序地编写和使用。第三方模块中,模块与模块之间仍然是散列在各地的,相互之间不能直接引用。但是,包和NPM则是将模块联系起来的一种机制。包是在模块的基础上进一步组织 JavaScript 代码。

NPM 的意义

NPM 相当于 gem 之于 Ruby,Maven 之于 Java。对于 Node 而言,NPM 帮助完成了第三方模块的发布、安装和依赖等。借助 NPM,Node与第三方模块之间形成了很好的一个生态系统。

总结

Node 和 ES6 利用模块机制,弥补了 JavaScript 弱结构性的问题。NPM 通过对包规范的支持,有效地组织了第三方模块,项目开发中的依赖问题得到了很好的解决,并有效提供了分享和传播的平台。

Web 前端模块出现的原因,以及 Node.js 中的模块的更多相关文章

  1. node.js中express模块创建服务器和http模块客户端发请求

    首先下载express模块,命令行输入 npm install express 1.node.js中express模块创建服务端 在js代码同文件位置新建一个文件夹(www_root),里面存放网页文 ...

  2. node.js中ws模块创建服务端和客户端,网页WebSocket客户端

    首先下载websocket模块,命令行输入 npm install ws 1.node.js中ws模块创建服务端 // 加载node上websocket模块 ws; var ws = require( ...

  3. node.js中net模块创建服务器和客户端(TCP)

    node.js中net模块创建服务器和客户端 1.node.js中net模块创建服务器(net.createServer) // 将net模块 引入进来 var net = require(" ...

  4. node.js中module模块的理解

    node.js中使用CommonJS规范实现模块功能,一个单独的文件就是一个单独的模块.通过require方法实现模块间的依赖管理. 通过require加载模块,是同步操作. 加载流程如下: 1.找到 ...

  5. 前端走进机器学习生态,在 Node.js 中使用 Python

    这次给大家带来一个好东西,它的主要用途就是能让大家在 Node.js 中使用 Python 的接口和函数.可能你看到这里会好奇,会疑惑,会不解,我 Node.js 大法那么好,干嘛要用 Python ...

  6. 在 Node.js 中引入模块:你所需要知道的一切都在这里

    本文作者:Jacob Beltran 编译:胡子大哈 翻译原文:http://huziketang.com/blog/posts/detail?postId=58eaf471a58c240ae35bb ...

  7. Node.js中的模块接口module.exports浅析

    在写node.js代码时,我们经常需要自己写模块(module).同时还需要在模块最后写好模块接口,声明这个模块对外暴露什么内容.实际上,node.js的模块接口有多种不同写法.这里作者对此做了个简单 ...

  8. Node.js中的模块接口module.exports

    在写node.js代码时,我们经常需要自己写模块(module).同时还需要在模块最后写好模块接口,声明这个模块对外暴露什么内容.实际上,node.js的模块接口有多种不同写法.在此做了个简单的总结. ...

  9. [Web 前端] 使用yarn代替npm作为node.js的模块管理器

    cp from : https://www.jianshu.com/p/bfe96f89da0e     Fast, reliable, and secure dependency managemen ...

随机推荐

  1. Go微服务框架go-kratos实战03:使用 gorm 实现增删改查操作

    一.简介 在上一篇文章 go-kratos实战02 中,详细介绍了用 kratos 编写项目代码的步骤.这篇就在上篇基础上,再结合 Go 数据库操作库 gorm 一步一步来实现一个简单的增删改查操作. ...

  2. Java - ConcurrentHashMap的原理

    Java - ConcurrentHashMap的原理 **这是JDK1.7的实现** ConcurrentHashMap 类中包含两个静态内部类 HashEntry 和 Segment. HashE ...

  3. 在CabloyJS中将Webpack生成的文件自动上传到阿里云OSS

    背景 阿里云OSS提供了一个Webpack插件,可在Webpack打包结束后将webpack生成的文件自动上传到阿里云OSS中 下面看看在CabloyJS中如何使用该插件 新建项目,并配置MySQL连 ...

  4. Python装饰器,Python闭包

    可参考:https://www.cnblogs.com/lianyingteng/p/7743876.html suqare(5)等价于power(2)(5):cube(5)等价于power(3)(5 ...

  5. Maven POM文件介绍

    1. POM文件是什么 1.1 Super POM 1.2 Minimal POM 1.3 Effective POM 3. 项目继承 和 项目聚合 2.1 Project Inheritance 项 ...

  6. 线上问题定位利器 jprofiler

    1.导出dump windows: jps -l   查看Java进行 jmap -dump:format=b,file=webapi.hprof 20840 查看进程,根据进程号导出hprof文件 ...

  7. 上线项目之局域网上线软件使用-----phpStudy

    上面的图片是phpStudy的软件截图.那么你在哪里会下到呢?链接: https://pan.baidu.com/s/1lvX9jY_K6gGkMOqo76p4nA 提取码: h1it 复制这段内容后 ...

  8. 正在运行中的docker容器设置自动重启

    # demo : 你的容器名称 docker update –-restart=always demo

  9. 【MAUI】为 Label、Image 等控件添加点击事件

    一.前言 已经习惯了 WPF.WinForm 中"万物皆可点击"的方式. 但是在 MAUI 中却不行了. 在 MAUI 中,点击.双击的效果,是需要通过"手势识别器&qu ...

  10. Web开发小妙招:巧用ThreadLocal规避层层传值

    摘要:我们可以在处理每次请求的过程中,无需从Controller以及Service中的方法层层传值,只需要直接通过该局部变量取值即可. 本文分享自华为云社区<拦截器中巧用ThreadLocal规 ...