通过ES6 Module看import和require区别
前言
说到import和require,大家平时开发中一定不少见,尤其是需要前端工程化的项目现在都已经离不开node了,在node环境下这两者都是大量存在的,大体上来说他们都是为了实现JS代码的模块化,那为什么会出现两种方案呢,又有什么不同呢?
模块化的不同解决方案
追根溯源,JS这门脚本语言设计伊始就是没有模块化的,所以早期的全局变量容易造成命名冲突。但随着web项目越来越大,JS的代码量也与日俱增,于是社区就自发约定了几种模块化的方案:requirejs遵循AMD,seajs遵循CMD,node的module遵循CommonJS规范,虽然写法上有所不同,都是为了能够间接实现模块化的基础上保持较为一致的代码风格。
随着ES2015的发布,官方标准定义了一种模块化的方案,那就是import、export。可是,标准毕竟是标准,各大浏览器和node终端要实现标准还是有一段距离的,目前来说都2018年了主流浏览器都还没实现,还得依赖转换工具(例如babel)转为ES5的代码之后浏览器才能解析。所以这也就解释了为什么我们的工程化代码中nodeJS遵循的CommonJS规范和ES6的模块化方案并存的现象。
两者的区别
- import是ES6标准中的模块化解决方案,require是node中遵循CommonJS规范的模块化解决方案
- 后者支持动态引入,也就是require(${path}/xx.js),前者目前不支持,但是已有提案
- 前者是关键词,后者不是
- 前者是编译时加载,必须放在模块顶部,在性能上会比后者好一些,后者是运行时加载,理论上来说放在哪里都可以
- 前者采用的是实时绑定方式,即导入和导出的值都指向同一个内存地址,所以导入值会随着导出值变化。而后者在导出时是指拷贝,就算导出的值变化了,导入的值也不会变化,如果想要更新值就要重新导入
- 前者会编译成require/exports来执行
用法上的区别
import导入模块
导入模块根据模块导出时的写法有不同写法,具体可以参考这里,如果模块是普通导出:
// test.js
var firstName = 'Michael';
var lastName = 'Jackson';
var year = 1958;
export {firstName, lastName, year};
// demo.js
import { firstName } from './test.js'
console.log(firstName); // 'Michael'
import * as test from './test.js'
console.log(test); //Module{} 所有内容
import { firstName as key, lastName as value } from './test.js'
console.log(key + '--' + value); // Michael--Jackson
- 带有默认值时,也是我们日常开发中常用的方式:
// test.js
var firstName = 'Michael';
var lastName = 'Jackson';
var year = 1958;
export default { firstName, lastName, year };
// demo.js
import test from './test.js'
console.log(test); // {firstName: "Michael", lastName: "Jackson", year: 1958}
实际上这个default就是一个语法糖,只不过defaul是一个关键字,在这里等同于
import { default as test } from './test.js'
特别注意的是,export命令规定的是对外的接口,必须与模块内部的变量建立一一对应关系。可以理解为export导出的是一种引用关系而不是一个具体的值,它们的实质是,在接口名与模块内部变量之间,建立了一一对应的关系,例如下面这样就会报错:
export 1;
var m = 1;
export m;
但是改为用花括号包起来变成对象之后就成了输出引用关系就可以正常导出了:
var m = 1;
export { m }
require导入模块
- require导入模块就没那么复杂了,导出时是什么样,导入时就还是什么样:
// test.js
var firstName = 'Michael';
var lastName = 'Jackson';
var year = 1958;
module.exports = { firstName, lastName, year };
// demo.js
const test = require('./test.js');
console.log(test); // {firstName: "Michael", lastName: "Jackson", year: 1958}
- 还有一种不常用的用法,直接导出:
// test.js
var year = 1958;
exports.year = year;
// demo.js
const test = require('./test.js');
console.log(test); // {year: 1958}
- 需要注意的是,module.exports导出之后,后面的代码就对导出的模块无效了,例如上例中
// test.js
module.exports = { firstName, lastName, year };
exports.name = '222';
// demo.js
const test = require('./test.js');
console.log(test); // {firstName: "Michael", lastName: "Jackson", year: 1958}
- 特别说明一下,由于require是可以在任意地方引入的,所以,我们在开发中用~引入图片的方式实际上等效于require:
<img src="~assets/img/icon/red_logo.png" class="logo" alt="">
//等效于
<img :src="require('assets/img/icon/red_logo.png')" class="logo" alt="">
总结
import和require就是两种不同的JS模块化实现方式而已,由于之前npm生态的很多包都是基础CommonJS规范写的,所以相当一段时间之内必然是import和require这两种模块引入方式共存的。
总体来说时代总是发展的,ES6作为语言规范是迟早会被各大主流浏览器支持的,不然也就称不上主流浏览器了。所以为了长远考虑,我们还是尽量使用ES6的import来引入模块,等以后浏览器支持了我们也就可以少改一些代码了。
参考
注1:
JS报错:Cannot use import statement outside a module
在使用import和export的时候,type类型错误会导致无法使用模块化功能:
<script type="text/javascript">
import test from './test/js';
console.log(test);
</script>
需要将type中text/javascript改为module,模块化的功能方能生效:
<script type="module">
import test from './test.js';
console.log(test);
</script>
注2:
JS报错:require is not defined
报错原因:
浏览器端不能识别require关键字,require是node.js环境下的,在node_modules文件夹里面的模块下面常见require
解决方法:
通过工具browserify或者是webpack把js文件编译一下,转成浏览器端可识别的。
//安装browserify ,我这里是全局安装
npm install -g browserify
// 编译
browserify ./source/module.js -o ./dist/dist.js
即可在dist目录下看到打包后的dist.js文件。
browserify 后面的第一个参数表示要打包的前端程序的入口,-o或者>表示打包后的输出文件。browserify会根据入口文件中的require或者import(ES6,需要安装babel)自动完成依赖分析,并将依赖文件打包为一个单文件。
————————————————
版权声明:本文为CSDN博主「giao00000」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/wml00000/article/details/84181227
原文出处:
西风瘦码,ES6学习笔记(二)—— 通过ES6 Module看import和require区别,https://www.cnblogs.com/wancheng7/p/10169470.html
通过ES6 Module看import和require区别的更多相关文章
- ES6学习笔记(二)—— 通过ES6 Module看import和require区别
前言 说到import和require,大家平时开发中一定不少见,尤其是需要前端工程化的项目现在都已经离不开node了,在node环境下这两者都是大量存在的,大体上来说他们都是为了实现JS代码的模块化 ...
- module.exports,exports,export和export default,import与require区别与联系【原创】
还在为module.exports.exports.export和export default,import和require区别与联系发愁吗,这一篇基本就够了! 一.首先搞清楚一个基本问题: modu ...
- module.exports,exports,export和export default,import与require区别与联系
还在为module.exports.exports.export和export default,import和require区别与联系发愁吗,这一篇基本就够了! 一.首先搞清楚一个基本问题: modu ...
- es6+require混合开发,兼容es6 module,import,export
近一年,一直很忙,做了不少的项目,不过都不是太满意,毕竟是别人的作品,不好意思写出来.最近打算开发一个es6的项目,项目中用到require,本文主要讲解es6的module规范怎么与require的 ...
- es6+require混合开发,兼容es6 module,import,export之 加载css及公用date-main
大家好!上篇文章已经介绍了搭建文件夹,以及加载js文件.现在讲一下加载css ,以及对baseUrl的理解 1.对项目结构的认知 一个项目的结构是根据项目的架构来决定的,当然也可以做到更智能,但是意义 ...
- JS中的import和require区别
1.import xx from yy的方式是静态编译,即编译时加载,要写在文件的最上头,但是import()函数可以实现动态加载,写在任何地方 2.require是动态加载,即运行时加载,理论上可以 ...
- export,export default,module.exports,import,require之间的区别和关联
module.exports Node 应用由模块组成,采用 CommonJS 模块规范.根据这个规范,每个文件就是一个模块,有自己的作用域.在这些文件里面定义的变量.函数.类,都是私有的,对外不可见 ...
- require/exports 与 import/export 的区别?
文章作者:寸志链接:https://www.zhihu.com/question/56820346/answer/150724784来源:知乎 遵循的模块化规范不一样 模块化规范:即为 JavaScr ...
- CommonJS与ES6 Module的使用与区别
CommonJS与ES6 Module的使用与区别 1. CommonJS 1.1 导出 1.2 导入 2. ES6 Module 2.1 导出 2.2 导入 3. CommonJS 与 ES6 Mo ...
随机推荐
- SAP用户角色分配函数权限
事务码 PFCG修改角色 选择[权限缺省] 选择 RFC 输入的函数只能是允许远程连接的函数,否则不能调用和添加到角色. 完成添加.
- 团队项目之Scrum4
小组:BLACK PANDA 时间:2019.11.24 每天举行站立式会议 提供当天站立式会议照片一张 2 昨天已完成的工作 2 基本实现web富文本编辑功能 后台的编辑接口已经基本完成,还有一些b ...
- CODING 2.0:为什么我们需要 DevOps
CODING 在前两天的 Kubecon 2019 大会上发布了 CODING 2.0.这背后是 CODING 对研发管理和研发团队组建的思考.从 CODING 成立以来,我们一直在探索"让 ...
- diango中有三种response
from django.shortcuts import render, redirect, HttpResponse HttpResponse() render() redirect()
- django admin显示多对多字段ManyToManyField
参考文档https://jingyan.baidu.com/article/4e5b3e190f55c591901e24b3.html admin.py from .models import *cl ...
- 用POI 3.17 导出EXECL
代码参考 https://www.cnblogs.com/bmbm/archive/2011/12/08/2342261.html 效果 导入jar包 <dependency> <g ...
- [C]副作用和序列点
概述 副作用: <C语言核心技术>对副作用的描述: 表达式内包含了一串的常量.标识符.运算符(指示的运算方式).表达式的目的可以是获得结果值,或者得到运算的副作用(side effect) ...
- react 项目引入路由
下载路由包 npm i react-router-dom -d 前台路由 登陆: /login /login.jsx App.js import React ,{Component} from 're ...
- [译]Vulkan教程(21)顶点input描述
[译]Vulkan教程(21)顶点input描述 Vertex input description 顶点input描述 Introduction 入门 In the next few chapters ...
- 01-Nginx安装
一.安装编译工具及库文件 yum -y install make zlib zlib-devel gcc-c++ libtool openssl openssl-devel 二.首先安装PCRE PC ...