热门搜索 :
宠物故事
您的当前位置:首页正文

深入解析node.js的exports、module.exports与ES6的export、exportdefault

2023-11-29 来源:微宠网
这篇文章主要给大家介绍了关于node.js中的exports、module.exports与ES6中的export、export default到时是什么的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友来一起学习学习吧。

前言

最近难得有空,决定开始重新规范的学习一下node编程。但是引入模块我看到用 require的方式,再联想到咱们的ES6各种export 、export default。

阿西吧,头都大了....

头大完了,那我们坐下先理理他们的使用范围。

  • require: node 和 es6 都支持的引入

  • export / import : 只有es6 支持的导出引入

  • module.exports / exports: 只有 node 支持的导出

  • 这一刻起,我觉得是时候要把它们之间的关系都给捋清楚了,不然我得混乱死。话不多少,咱们开干!!

    node模块

    Node里面的模块系统遵循的是CommonJS规范。

    那问题又来了,什么是CommonJS规范呢?

    由于js以前比较混乱,各写各的代码,没有一个模块的概念,而这个规范出来其实就是对模块的一个定义。

    CommonJS定义的模块分为: 模块标识(module)、模块定义(exports) 、模块引用(require)

    先解释 exports 和 module.exports

    在一个node执行一个文件时,会给这个文件内生成一个 exports和module对象,

    而module又有一个exports属性。他们之间的关系如下图,都指向一块{}内存区域。

    exports = module.exports = {};

    那下面我们来看看代码的吧。

    //utils.jslet a = 100;console.log(module.exports); //能打印出
    结果为:{}console.log(exports); //能打印出结果为:{}exports.a = 200; //这里辛苦劳作帮 module.exports 的内容给改成 {a : 200}exports = '指向其他内存区'; //这里把exports的指向指走//test.jsvar a = require('/utils');console.log(a) // 打印为 {a : 200}

    从上面可以看出,其实require导出的内容是module.exports的指向的内存块内容,并不是exports的。

    简而言之,区分他们之间的区别就是 exports 只是 module.exports的引用,辅助后者添加内容用的。

    用白话讲就是,exports只辅助module.exports操作内存中的数据,辛辛苦苦各种操作数据完,累得要死,结果到最后真正被require出去的内容还是module.exports的,真是好苦逼啊。

    其实大家用内存块的概念去理解,就会很清楚了。

    然后呢,为了避免糊涂,尽量都用 module.exports 导出,然后用require导入。

    ES中的模块导出导入

    说实话,在es中的模块,就非常清晰了。不过也有一些细节的东西需要搞清楚。

    比如 export 和 export default,还有 导入的时候,import a from ..,import {a} from ..,总之也有点乱,那么下面我们就开始把它们捋清楚吧。

    export 和 export default

    首先我们讲这两个导出,下面我们讲讲它们的区别

  • export与export default均可用于导出常量、函数、文件、模块等

  • 在一个文件或模块中,export、import可以有多个,export default仅有一个

  • 通过export方式导出,在导入时要加{ },export default则不需要

  • export能直接导出变量表达式,export default不行。

  • 下面咱们看看代码去验证一下

    testEs6Export.js

    'use strict'//导出变量export const a = '100'; //导出方法export const dogSay = function(){ console.log('wang wang');} //导出方法第二种function catSay(){ console.log('miao miao'); }export { catSay };//export default导出const m = 100;export default m; //export defult const m = 100;// 这里不能写这种格式。

    index.js

    //index.js'use strict'var express = require('express');var router = express.Router();import { dogSay, catSay } from './testEs6Export'; //导出了 export 方法 import m from './testEs6Export'; //导出了 export default import * as testModule from './testEs6Export'; //as 集合成对象导出/* GET home page. */router.get('/', function(req, res, next) { dogSay(); catSay(); console.log(m); testModule.dogSay(); console.log(testModule.m); // undefined , 因为 as 导出是 把 零散的 export 聚集在一起作为一个对象,而export default 是导出为 default属性。 console.log(testModule.default); // 100 res.send('恭喜你,成功验证');});module.exports = router;

    从上面可以看出,确实感觉 ES6的模块系统非常灵活的。

    代码地址

    GitHub: https://github.com/XuXiaoGH/exportImportTest

    小编还为您整理了以下内容,可能对您也有帮助:

    export、export default 、module.exports详解

    javascript没有模块体系,无法将大程序分拆成互相依赖的小文件,再用简单的方法将它们拼装起来.为了解决这个问题,ES6推出了export和export default.

    export和export default是es6提出来的,它在编译时就完成模块加载,export命令可以出现在模块的任何位置,只要处于模块顶层即可,如果处于块级作用域就会报错,import也是如此.

    从上面图片我们可以看出export后面必须跟变量名和值,可以直接声明或写在一个对象中,都会以键值对的形式导出数据.

    以上五种写法都可以,export default后面只能跟值.

    总结:export后面必须有变量名和值,导出的数据是键值对形式,而export default后面只能是值,因为它已经有变量名default

    require和mole.exports是CommonJS规范,它是在运行时加载,就是说运行时才能得到这个对象,mole.exports后面跟的值和export default一样

    以上五种写法都可以

    mole.export可以用import来引入,后面可以跟大括号或不跟,跟的话相当于解构赋值,不跟就是整体引入,export也可以用require来引入.require('path.js')或import('path.js')都表示执行这个模块,不会返回值.

    export一般导出方法,引入的时候使用大括号按需引入你需要的方法,export default导出对象或数组,比如接口api对象,routes路由数组,但是引入的时候会整体引入,mole.exports一般导出对象,可以用import或require整体引入或按需引入,这样子比较灵活,所以mole.exports和import使用的场景也挺多的,import只能写在js文件顶部,但是require可以写在任何地方,所以要根据场景不同使用不同方法.

    总结:export后面跟变量名和值,import后面是{}或* as 变量名,export default后面跟值,import后面没有{},mole.exports后面和export default一样都是值,require后面有{}表示解构赋值,没有表示整体引入,import和require都可以引入export和mole.exports,import只能写在js文件顶部,但是require可以写在任何地方.CommonJS模块输出是一个值的拷贝,ES6模块输出是值的引用.CommonJS模块是运行时加载,ES6模块是编译时输出接口.

    module.exports和export详解

    概念:mole.exports和exports是属于commonJs规范,export和export default是ES6模块规范。

    exports 等于 mole.exports,相当于在js文件头部,有一个mole对象,mole.exports = exports;
    exports是一个对象,所以可以exports多个值

    1、对于要导出的属性,可以简单直接挂到exports对象上

    2、对于类,为了直接使导出的内容作为类的构造器可以让调用者使用new操作符创建实例对象,应该把构造函数挂到mole.exports对象上,不要和导出属性值混在一起

    mole.exports 初始值为一个空对象 {}

    exports 是指向的 mole.exports 的引用

    require() 返回的是 mole.exports 而不是 exports

    也就是: exports = mole.exports = {}, exports和mole.exports都指向一个引用地址{},如果exports.name = 'xxx',那mole.exports = {name:'xxx'},引用对象改变,两者又是同时指向一个对象,所以都改变了。

    import 的时候可以使用 通配符 * 导入外部的模块:
    import * as xxx from ‘xxx’: 会将若干export导出的内容组合成一个对象返回;
    import xxx from ‘xxx’:(export default Din)只会导出这个默认的对象作为一个对象
    ;
    以上。

    module.exports和export详解

    概念:mole.exports和exports是属于commonJs规范,export和export default是ES6模块规范。

    exports 等于 mole.exports,相当于在js文件头部,有一个mole对象,mole.exports = exports;
    exports是一个对象,所以可以exports多个值

    1、对于要导出的属性,可以简单直接挂到exports对象上

    2、对于类,为了直接使导出的内容作为类的构造器可以让调用者使用new操作符创建实例对象,应该把构造函数挂到mole.exports对象上,不要和导出属性值混在一起

    mole.exports 初始值为一个空对象 {}

    exports 是指向的 mole.exports 的引用

    require() 返回的是 mole.exports 而不是 exports

    也就是: exports = mole.exports = {}, exports和mole.exports都指向一个引用地址{},如果exports.name = 'xxx',那mole.exports = {name:'xxx'},引用对象改变,两者又是同时指向一个对象,所以都改变了。

    import 的时候可以使用 通配符 * 导入外部的模块:
    import * as xxx from ‘xxx’: 会将若干export导出的内容组合成一个对象返回;
    import xxx from ‘xxx’:(export default Din)只会导出这个默认的对象作为一个对象
    ;
    以上。

    export与exports、import与require区别与联系

    一、区别于联系

    1.mole.exports、exports、require是属于CommonJS模块规范。

    2.export、export default、import是属于ES6语法

    3.mole.exports和exports、export和export default都是导出模块。

    4.import和require则是导入模块。

    5.mole.exports导出对应require导入,export导出对应import导入

    二、CommonJS规范(exports与require)

    Node应用由模块组成,采用CommonJS模块规范。

    根据这个规范,每个文件就是一个模块,有自己的作用域。在一个文件里面定义的变量、函数、类,都是私有的,对其他文件不可见。

    CommonJS规范规定,每个模块内部,mole变量代表当前模块。这个变量是一个对象,它的exports属性(即mole.exports)是对外的接口。加载某个模块,其实是加载该模块的mole.exports属性。

    require方法用于加载模块。

    三、ES6语法(export、export default、import)

    模块功能主要由:export和import构成。export导出模块的对外接口,import命令导入其他模块暴露的接口。

    export其实和export default就是写法上面有点差别,一个是导出一个个单独接口,一个是默认导出一个整体接口。使用import命令的时候,用户需要知道所要加载的变量名或函数名,否则无法加载。这里就有一个简单写法不用去知道有哪些具体的暴露接口名,就用export default命令,为模块指定默认输出。

    export与exports、import与require区别与联系

    一、区别于联系

    1.mole.exports、exports、require是属于CommonJS模块规范。

    2.export、export default、import是属于ES6语法

    3.mole.exports和exports、export和export default都是导出模块。

    4.import和require则是导入模块。

    5.mole.exports导出对应require导入,export导出对应import导入

    二、CommonJS规范(exports与require)

    Node应用由模块组成,采用CommonJS模块规范。

    根据这个规范,每个文件就是一个模块,有自己的作用域。在一个文件里面定义的变量、函数、类,都是私有的,对其他文件不可见。

    CommonJS规范规定,每个模块内部,mole变量代表当前模块。这个变量是一个对象,它的exports属性(即mole.exports)是对外的接口。加载某个模块,其实是加载该模块的mole.exports属性。

    require方法用于加载模块。

    三、ES6语法(export、export default、import)

    模块功能主要由:export和import构成。export导出模块的对外接口,import命令导入其他模块暴露的接口。

    export其实和export default就是写法上面有点差别,一个是导出一个个单独接口,一个是默认导出一个整体接口。使用import命令的时候,用户需要知道所要加载的变量名或函数名,否则无法加载。这里就有一个简单写法不用去知道有哪些具体的暴露接口名,就用export default命令,为模块指定默认输出。

    vue 导入、导出模块的几种方式

    ES6规范 模块导入方式:import
    ES6规范 模块导出方式:export、export default

    nodejs commonjs规范 模块导入方式:require
    nodejs commonjs规范 模块导出方式:exports、mole.exports

    vue 导入、导出模块的几种方式

    ES6规范 模块导入方式:import
    ES6规范 模块导出方式:export、export default

    nodejs commonjs规范 模块导入方式:require
    nodejs commonjs规范 模块导出方式:exports、mole.exports

    module.exports和export default的区别

    这篇文章主要给大家介绍了关于node.js中的exports、module.exports与ES6中的export、export default到时是什么的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友来一起学习学习吧。

    前言

    最近难得有空,决定开始重新规范的学习一下node编程。但是引入模块我看到用 require的方式,再联想到咱们的ES6各种export 、export default。

    阿西吧,头都大了....

    头大完了,那我们坐下先理理他们的使用范围。

  • require: node 和 es6 都支持的引入

  • export / import : 只有es6 支持的导出引入

  • module.exports / exports: 只有 node 支持的导出

  • 这一刻起,我觉得是时候要把它们之间的关系都给捋清楚了,不然我得混乱死。话不多少,咱们开干!!

    node模块

    Node里面的模块系统遵循的是CommonJS规范。

    那问题又来了,什么是CommonJS规范呢?

    由于js以前比较混乱,各写各的代码,没有一个模块的概念,而这个规范出来其实就是对模块的一个定义。

    CommonJS定义的模块分为: 模块标识(module)、模块定义(exports) 、模块引用(require)

    先解释 exports 和 module.exports

    在一个node执行一个文件时,会给这个文件内生成一个 exports和module对象,

    而module又有一个exports属性。他们之间的关系如下图,都指向一块{}内存区域。

    exports = module.exports = {};


    那下面我们来看看代码的吧。

    //utils.jslet a = 100;console.log(module.exports); //能打印出
    结果为:{}console.log(exports); //能打印出结果为:{}exports.a = 200; //这里辛苦劳作帮 module.exports 的内容给改成 {a : 200}exports = '指向其他内存区'; //这里把exports的指向指走//test.jsvar a = require('/utils');console.log(a) // 打印为 {a : 200}

    从上面可以看出,其实require导出的内容是module.exports的指向的内存块内容,并不是exports的。

    简而言之,区分他们之间的区别就是 exports 只是 module.exports的引用,辅助后者添加内容用的。

    用白话讲就是,exports只辅助module.exports操作内存中的数据,辛辛苦苦各种操作数据完,累得要死,结果到最后真正被require出去的内容还是module.exports的,真是好苦逼啊。

    其实大家用内存块的概念去理解,就会很清楚了。

    然后呢,为了避免糊涂,尽量都用 module.exports 导出,然后用require导入。

    ES中的模块导出导入

    说实话,在es中的模块,就非常清晰了。不过也有一些细节的东西需要搞清楚。

    比如 export 和 export default,还有 导入的时候,import a from ..,import {a} from ..,总之也有点乱,那么下面我们就开始把它们捋清楚吧。

    export 和 export default

    首先我们讲这两个导出,下面我们讲讲它们的区别

  • export与export default均可用于导出常量、函数、文件、模块等

  • 在一个文件或模块中,export、import可以有多个,export default仅有一个

  • 通过export方式导出,在导入时要加{ },export default则不需要

  • export能直接导出变量表达式,export default不行。

  • 下面咱们看看代码去验证一下

    testEs6Export.js

    'use strict'//导出变量export const a = '100'; //导出方法export const dogSay = function(){ console.log('wang wang');} //导出方法第二种function catSay(){ console.log('miao miao'); }export { catSay };//export default导出const m = 100;export default m; //export defult const m = 100;// 这里不能写这种格式。

    index.js

    //index.js'use strict'var express = require('express');var router = express.Router();import { dogSay, catSay } from './testEs6Export'; //导出了 export 方法 import m from './testEs6Export'; //导出了 export default import * as testModule from './testEs6Export'; //as 集合成对象导出/* GET home page. */router.get('/', function(req, res, next) { dogSay(); catSay(); console.log(m); testModule.dogSay(); console.log(testModule.m); // undefined , 因为 as 导出是 把 零散的 export 聚集在一起作为一个对象,而export default 是导出为 default属性。 console.log(testModule.default); // 100 res.send('恭喜你,成功验证');});module.exports = router;

    从上面可以看出,确实感觉 ES6的模块系统非常灵活的。

    代码地址

    GitHub: https://github.com/XuXiaoGH/exportImportTest

    module.exports和export default的区别

    这篇文章主要给大家介绍了关于node.js中的exports、module.exports与ES6中的export、export default到时是什么的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友来一起学习学习吧。

    前言

    最近难得有空,决定开始重新规范的学习一下node编程。但是引入模块我看到用 require的方式,再联想到咱们的ES6各种export 、export default。

    阿西吧,头都大了....

    头大完了,那我们坐下先理理他们的使用范围。

  • require: node 和 es6 都支持的引入

  • export / import : 只有es6 支持的导出引入

  • module.exports / exports: 只有 node 支持的导出

  • 这一刻起,我觉得是时候要把它们之间的关系都给捋清楚了,不然我得混乱死。话不多少,咱们开干!!

    node模块

    Node里面的模块系统遵循的是CommonJS规范。

    那问题又来了,什么是CommonJS规范呢?

    由于js以前比较混乱,各写各的代码,没有一个模块的概念,而这个规范出来其实就是对模块的一个定义。

    CommonJS定义的模块分为: 模块标识(module)、模块定义(exports) 、模块引用(require)

    先解释 exports 和 module.exports

    在一个node执行一个文件时,会给这个文件内生成一个 exports和module对象,

    而module又有一个exports属性。他们之间的关系如下图,都指向一块{}内存区域。

    exports = module.exports = {};


    那下面我们来看看代码的吧。

    //utils.jslet a = 100;console.log(module.exports); //能打印出
    结果为:{}console.log(exports); //能打印出结果为:{}exports.a = 200; //这里辛苦劳作帮 module.exports 的内容给改成 {a : 200}exports = '指向其他内存区'; //这里把exports的指向指走//test.jsvar a = require('/utils');console.log(a) // 打印为 {a : 200}

    从上面可以看出,其实require导出的内容是module.exports的指向的内存块内容,并不是exports的。

    简而言之,区分他们之间的区别就是 exports 只是 module.exports的引用,辅助后者添加内容用的。

    用白话讲就是,exports只辅助module.exports操作内存中的数据,辛辛苦苦各种操作数据完,累得要死,结果到最后真正被require出去的内容还是module.exports的,真是好苦逼啊。

    其实大家用内存块的概念去理解,就会很清楚了。

    然后呢,为了避免糊涂,尽量都用 module.exports 导出,然后用require导入。

    ES中的模块导出导入

    说实话,在es中的模块,就非常清晰了。不过也有一些细节的东西需要搞清楚。

    比如 export 和 export default,还有 导入的时候,import a from ..,import {a} from ..,总之也有点乱,那么下面我们就开始把它们捋清楚吧。

    export 和 export default

    首先我们讲这两个导出,下面我们讲讲它们的区别

  • export与export default均可用于导出常量、函数、文件、模块等

  • 在一个文件或模块中,export、import可以有多个,export default仅有一个

  • 通过export方式导出,在导入时要加{ },export default则不需要

  • export能直接导出变量表达式,export default不行。

  • 下面咱们看看代码去验证一下

    testEs6Export.js

    'use strict'//导出变量export const a = '100'; //导出方法export const dogSay = function(){ console.log('wang wang');} //导出方法第二种function catSay(){ console.log('miao miao'); }export { catSay };//export default导出const m = 100;export default m; //export defult const m = 100;// 这里不能写这种格式。

    index.js

    //index.js'use strict'var express = require('express');var router = express.Router();import { dogSay, catSay } from './testEs6Export'; //导出了 export 方法 import m from './testEs6Export'; //导出了 export default import * as testModule from './testEs6Export'; //as 集合成对象导出/* GET home page. */router.get('/', function(req, res, next) { dogSay(); catSay(); console.log(m); testModule.dogSay(); console.log(testModule.m); // undefined , 因为 as 导出是 把 零散的 export 聚集在一起作为一个对象,而export default 是导出为 default属性。 console.log(testModule.default); // 100 res.send('恭喜你,成功验证');});module.exports = router;

    从上面可以看出,确实感觉 ES6的模块系统非常灵活的。

    代码地址

    GitHub: https://github.com/XuXiaoGH/exportImportTest

    如何让node运行es6模块文件及其原理详解



    最新版的 node 支持最新版 ECMAScript 几乎所有特性,但有一个特性却一直到现在都还没有支持,那就是从 ES2015 开始定义的模块化机制。而现在我们很多项目都是用 es6 的模块化规范来写代码的,包括 node 项目,所以,node 不能运行 es6 模块文件就会很不便。

    让 node 运行 es6 模块文件的方式有两种:

    转码 es6 模块为 commonjs 模块
    hook node 的 require 机制,直接让 node 的 require 加载 import/export
    1. 转码 es6 模块为 commonjs 模块

    因为 node 支持几乎所有除 import/export 外的语法,所以我们只需要将 import/export 转码成 require/exports,而不需要转码其他语法。

    比如下面的项目:

    - package.json
    - src/
    - index.js
    - print.js
    - ...
    # package.json
    {
    "main": "lib/index.js" # 由工具转码 src 目录下源文件到 lib 目录下
    }
    # src/index.js
    import print from './print';
    print('index');
    export default print;
    # src/print.js
    export default str => {
    console.log('print: ' + str);
    };
    因为 src 目录下的源文件都是 es6 模块化规范的,node 并不能直接运行,所以需要转码成 commonjs 规范的代码。

    这个过程有两个方案:

    如果不会单独使用 src 目录下的某个文件,而仅仅是以 src/index.js 为入口文件使用,可以把 src 目录下的文件打包成一个文件到 lib/index.js:这种方式推荐使用工具 rollup
    如果需要单独使用 src 目录下的文件,那就需要把 src 目录下的文件一对一的转码到 lib 目录下:这种方式推荐使用工具 gulp + babel
    1.1 用 rollup 把 src 目录下的文件打包成一个文件到 lib/index.js

    相关文件:

    # rollup.config.js
    export default {
    input: 'src/index.js',
    output: {
    file: 'lib/index.js',
    format: 'cjs',
    },
    };
    # package.json
    {
    "scripts": {
    "build": "rollup -c"
    },
    "devDependencies": {
    "rollup": "^0.66.4"
    }
    }
    运行命令:

    npm run build
    结果:

    # lib/index.js
    'use strict';
    var print = str => {
    console.log('print: ' + str);
    };
    print('index');
    mole.exports = print;
    1.2 用 gulp + babel 把 src 目录下的文件一对一的转码到 lib 目录下

    相关文件:

    # build.js
    const gulp = require('gulp');
    const babel = require('gulp-babel');
    gulp.task('babel', () =>
    gulp.src('src/**/*.js')
    .pipe(babel({
    plugins: ['@babel/plugin-transform-moles-commonjs']
    }))
    .pipe(gulp.dest('lib'))
    );
    gulp.series('babel')();
    # package.json
    {
    "scripts": {
    "build": "node build.js"
    },
    "devDependencies": {
    "@babel/core": "^7.1.2",
    "@babel/plugin-transform-moles-commonjs": "^7.2.0",
    "gulp": "^4.0.0",
    "gulp-babel": "^8.0.0"
    }
    }
    运行命令:

    npm run build
    结果:

    # lib/index.js
    "use strict";
    Object.defineProperty(exports, "__esMole", {
    value: true
    });
    exports.default = void 0;
    var _print = _interopRequireDefault(require("./print"));
    function _interopRequireDefault(obj) { return obj && obj.__esMole ? obj : { default: obj }; }
    (0, _print.default)('index');
    var _default = _print.default;
    exports.default = _default;
    # lib/print.js
    "use strict";
    Object.defineProperty(exports, "__esMole", {
    value: true
    });
    exports.default = void 0;
    var _default = str => {
    console.log('print: ' + str);
    };
    exports.default = _default;
    2. hook node 的 require 机制,直接加载 import/export

    这种机制一般是通过对 node 的 require 机制进行 hook,劫持 require 抓取的源文件代码,把源代码转码成 commonjs 规范之后,再传送给 require 机制原本的代码流中。

    pirates 之类的第三方 npm 包提供了这种添加 hook 的功能。

    babel-register 便是使用这种方式达到 node 运行 es6 模块文件的目的的。

    2.1 使用 babel-register 直接运行 es6 模块文件

    示例目录:

    - package.json
    - src/
    - entry.js # 这里多了一个入口文件,专门用于注册 babel-register
    - index.js
    - print.js
    - ...
    相关文件:

    # package.json
    {
    "scripts": {
    "run": "node src/entry.js"
    },
    "devDependencies": {
    "@babel/core": "^7.1.2",
    "@babel/plugin-transform-moles-commonjs": "^7.2.0",
    "@babel/register": "^7.0.0"
    }
    }
    # src/entry.js # 入口文件必须使用 commonjs 规范来写,因为还没有注册 hook
    require('@babel/register')({
    plugins: ['@babel/plugin-transform-moles-commonjs']
    });
    require('./index');
    # src/index.js
    import print from './print';
    print('index');
    # src/print.js
    export default str => {
    console.log('print: ' + str);
    };
    运行:

    npm run run
    结果:

    # 命令行打印
    print: index
    这种方式因为中间转码会有额外的性能损耗,所以不建议在生产环境下使用,只建议在开发模式下使用。

    2.2 使用babel-node 直接运行 es6 模块文件

    babel-node 对 babel-register 进行了封装,提供了在命令行直接运行 es6 模块文件的便捷方式。

    示例目录:

    - package.json
    - src/
    - index.js
    - print.js
    - ...
    相关文件:

    # package.json
    {
    "scripts": {
    "run": "babel-node src/index.js --plugins @babel/plugin-transform-moles-commonjs"
    },
    "devDependencies": {
    "@babel/core": "^7.1.2",
    "@babel/node": "^7.2.0",
    "@babel/plugin-transform-moles-commonjs": "^7.2.0"
    }
    }
    # src/index.js
    import print from './print';
    print('index');
    # src/print.js
    export default str => {
    console.log('print: ' + str);
    };
    运行:

    npm run run
    结果:

    # 命令行打印
    print: index
    这种方式也不建议在生产环境下使用,只建议在开发模式下使用。

    3. 链接

    es6 就是指 ECMAScript 2015

    es7 就是指 ECMAScript 2016

    es8 就是指 ECMAScript 2017

    es9 就是指 ECMAScript 2018

    到写这篇文章为止,已发布了 ECMAScript 2018。

    如何让node运行es6模块文件及其原理详解



    最新版的 node 支持最新版 ECMAScript 几乎所有特性,但有一个特性却一直到现在都还没有支持,那就是从 ES2015 开始定义的模块化机制。而现在我们很多项目都是用 es6 的模块化规范来写代码的,包括 node 项目,所以,node 不能运行 es6 模块文件就会很不便。

    让 node 运行 es6 模块文件的方式有两种:

    转码 es6 模块为 commonjs 模块
    hook node 的 require 机制,直接让 node 的 require 加载 import/export
    1. 转码 es6 模块为 commonjs 模块

    因为 node 支持几乎所有除 import/export 外的语法,所以我们只需要将 import/export 转码成 require/exports,而不需要转码其他语法。

    比如下面的项目:

    - package.json
    - src/
    - index.js
    - print.js
    - ...
    # package.json
    {
    "main": "lib/index.js" # 由工具转码 src 目录下源文件到 lib 目录下
    }
    # src/index.js
    import print from './print';
    print('index');
    export default print;
    # src/print.js
    export default str => {
    console.log('print: ' + str);
    };
    因为 src 目录下的源文件都是 es6 模块化规范的,node 并不能直接运行,所以需要转码成 commonjs 规范的代码。

    这个过程有两个方案:

    如果不会单独使用 src 目录下的某个文件,而仅仅是以 src/index.js 为入口文件使用,可以把 src 目录下的文件打包成一个文件到 lib/index.js:这种方式推荐使用工具 rollup
    如果需要单独使用 src 目录下的文件,那就需要把 src 目录下的文件一对一的转码到 lib 目录下:这种方式推荐使用工具 gulp + babel
    1.1 用 rollup 把 src 目录下的文件打包成一个文件到 lib/index.js

    相关文件:

    # rollup.config.js
    export default {
    input: 'src/index.js',
    output: {
    file: 'lib/index.js',
    format: 'cjs',
    },
    };
    # package.json
    {
    "scripts": {
    "build": "rollup -c"
    },
    "devDependencies": {
    "rollup": "^0.66.4"
    }
    }
    运行命令:

    npm run build
    结果:

    # lib/index.js
    'use strict';
    var print = str => {
    console.log('print: ' + str);
    };
    print('index');
    mole.exports = print;
    1.2 用 gulp + babel 把 src 目录下的文件一对一的转码到 lib 目录下

    相关文件:

    # build.js
    const gulp = require('gulp');
    const babel = require('gulp-babel');
    gulp.task('babel', () =>
    gulp.src('src/**/*.js')
    .pipe(babel({
    plugins: ['@babel/plugin-transform-moles-commonjs']
    }))
    .pipe(gulp.dest('lib'))
    );
    gulp.series('babel')();
    # package.json
    {
    "scripts": {
    "build": "node build.js"
    },
    "devDependencies": {
    "@babel/core": "^7.1.2",
    "@babel/plugin-transform-moles-commonjs": "^7.2.0",
    "gulp": "^4.0.0",
    "gulp-babel": "^8.0.0"
    }
    }
    运行命令:

    npm run build
    结果:

    # lib/index.js
    "use strict";
    Object.defineProperty(exports, "__esMole", {
    value: true
    });
    exports.default = void 0;
    var _print = _interopRequireDefault(require("./print"));
    function _interopRequireDefault(obj) { return obj && obj.__esMole ? obj : { default: obj }; }
    (0, _print.default)('index');
    var _default = _print.default;
    exports.default = _default;
    # lib/print.js
    "use strict";
    Object.defineProperty(exports, "__esMole", {
    value: true
    });
    exports.default = void 0;
    var _default = str => {
    console.log('print: ' + str);
    };
    exports.default = _default;
    2. hook node 的 require 机制,直接加载 import/export

    这种机制一般是通过对 node 的 require 机制进行 hook,劫持 require 抓取的源文件代码,把源代码转码成 commonjs 规范之后,再传送给 require 机制原本的代码流中。

    pirates 之类的第三方 npm 包提供了这种添加 hook 的功能。

    babel-register 便是使用这种方式达到 node 运行 es6 模块文件的目的的。

    2.1 使用 babel-register 直接运行 es6 模块文件

    示例目录:

    - package.json
    - src/
    - entry.js # 这里多了一个入口文件,专门用于注册 babel-register
    - index.js
    - print.js
    - ...
    相关文件:

    # package.json
    {
    "scripts": {
    "run": "node src/entry.js"
    },
    "devDependencies": {
    "@babel/core": "^7.1.2",
    "@babel/plugin-transform-moles-commonjs": "^7.2.0",
    "@babel/register": "^7.0.0"
    }
    }
    # src/entry.js # 入口文件必须使用 commonjs 规范来写,因为还没有注册 hook
    require('@babel/register')({
    plugins: ['@babel/plugin-transform-moles-commonjs']
    });
    require('./index');
    # src/index.js
    import print from './print';
    print('index');
    # src/print.js
    export default str => {
    console.log('print: ' + str);
    };
    运行:

    npm run run
    结果:

    # 命令行打印
    print: index
    这种方式因为中间转码会有额外的性能损耗,所以不建议在生产环境下使用,只建议在开发模式下使用。

    2.2 使用babel-node 直接运行 es6 模块文件

    babel-node 对 babel-register 进行了封装,提供了在命令行直接运行 es6 模块文件的便捷方式。

    示例目录:

    - package.json
    - src/
    - index.js
    - print.js
    - ...
    相关文件:

    # package.json
    {
    "scripts": {
    "run": "babel-node src/index.js --plugins @babel/plugin-transform-moles-commonjs"
    },
    "devDependencies": {
    "@babel/core": "^7.1.2",
    "@babel/node": "^7.2.0",
    "@babel/plugin-transform-moles-commonjs": "^7.2.0"
    }
    }
    # src/index.js
    import print from './print';
    print('index');
    # src/print.js
    export default str => {
    console.log('print: ' + str);
    };
    运行:

    npm run run
    结果:

    # 命令行打印
    print: index
    这种方式也不建议在生产环境下使用,只建议在开发模式下使用。

    3. 链接

    es6 就是指 ECMAScript 2015

    es7 就是指 ECMAScript 2016

    es8 就是指 ECMAScript 2017

    es9 就是指 ECMAScript 2018

    到写这篇文章为止,已发布了 ECMAScript 2018。

    模块化的理解和规范

    把相同功能的封装为一个模块,提供向外的接口,以供使用,使得开发的时候,彼此互不影响!
    ESMole

    es6模块化规范
    采用的是
    import 导入
    export 导出
    特点:

    1:一个文件为一个模块,每一个模块只会加载一次,即使多次调用,还是加载一次,多次引入的时候,是从内存中获取
    2:导出和导入
    import导入 import
    export导出 export defalut {}
    3:import为静态的导入
    导出

    let a = 10;
    let b = 20;

    function add(a, b) {
    return a + b;
    }
    let c = 30;

    function sub(a, b) {
    return a - b;
    }

    export {
    a,
    b,
    c,
    add
    }
    let d = 100;
    let e = 22;

    export default {
    d,
    e
    }; //注意点:就是export default 导出的只能是一个变量或者对象等等!
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    导入
    import XXX form “路径” => 这是对应 export let XXX 的格式
    import { } form “路径” => 这是对应 export {} 的格式
    import XX from “路径” => 这是对应 export default {} 的格式
    注意点:就是export 导入的必须按照导出的名称来接受,如果重名了,那么使用 as 来修改别名
    eg: import { d as dd} from "路径" 当d变量重名的时候,就把个导出为dd
    import {
    a,
    b,
    c,
    add
    } from "./js/01.es6的导入和导出.js";
    1
    2
    3
    4
    5
    6
    AMD

    sea.js
    CMD

    require.js
    commom.js

    node语言的模块化规范
    导出

    var flag = true;
    function getSum(num, num2) {
    return num + num2;
    }
    if (flag) {
    console.log('小明');
    }
    //这是common.js方式 导出 对象
    mole.exports = {
    flag,
    getSum
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    导入
    语法:let {flag,getSum} = require 路径"
    //这是commom.js导入的语法
    let aaa = require('./aaa'); // 从 aaa文件导入
    let flag = aaa.flag;
    let getSum = aaa.getSum;
    // getSum(2, 90);
    console.log(getSum(2, 90));

    模块化的理解和规范

    把相同功能的封装为一个模块,提供向外的接口,以供使用,使得开发的时候,彼此互不影响!
    ESMole

    es6模块化规范
    采用的是
    import 导入
    export 导出
    特点:

    1:一个文件为一个模块,每一个模块只会加载一次,即使多次调用,还是加载一次,多次引入的时候,是从内存中获取
    2:导出和导入
    import导入 import
    export导出 export defalut {}
    3:import为静态的导入
    导出

    let a = 10;
    let b = 20;

    function add(a, b) {
    return a + b;
    }
    let c = 30;

    function sub(a, b) {
    return a - b;
    }

    export {
    a,
    b,
    c,
    add
    }
    let d = 100;
    let e = 22;

    export default {
    d,
    e
    }; //注意点:就是export default 导出的只能是一个变量或者对象等等!
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    导入
    import XXX form “路径” => 这是对应 export let XXX 的格式
    import { } form “路径” => 这是对应 export {} 的格式
    import XX from “路径” => 这是对应 export default {} 的格式
    注意点:就是export 导入的必须按照导出的名称来接受,如果重名了,那么使用 as 来修改别名
    eg: import { d as dd} from "路径" 当d变量重名的时候,就把个导出为dd
    import {
    a,
    b,
    c,
    add
    } from "./js/01.es6的导入和导出.js";
    1
    2
    3
    4
    5
    6
    AMD

    sea.js
    CMD

    require.js
    commom.js

    node语言的模块化规范
    导出

    var flag = true;
    function getSum(num, num2) {
    return num + num2;
    }
    if (flag) {
    console.log('小明');
    }
    //这是common.js方式 导出 对象
    mole.exports = {
    flag,
    getSum
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    导入
    语法:let {flag,getSum} = require 路径"
    //这是commom.js导入的语法
    let aaa = require('./aaa'); // 从 aaa文件导入
    let flag = aaa.flag;
    let getSum = aaa.getSum;
    // getSum(2, 90);
    console.log(getSum(2, 90));

    vue 中exports 和module.exports

    1.exports 和mole.exports  这两个到处对象,变量 ,方法,可以在全局使用 require('./a')。 当两个同时我在一个模块到处 对象时只有mole.exports导出有效。

    2.在es5中遵循了commonJs   mole.exports导出模块  require 引入模块

    3.exports 和mole.exports 必须后面跟=

    exports=

    mole.exports =

    es6  不需要=

    export ...

    export default ...

    4.

    vue 中exports 和module.exports

    1.exports 和mole.exports  这两个到处对象,变量 ,方法,可以在全局使用 require('./a')。 当两个同时我在一个模块到处 对象时只有mole.exports导出有效。

    2.在es5中遵循了commonJs   mole.exports导出模块  require 引入模块

    3.exports 和mole.exports 必须后面跟=

    exports=

    mole.exports =

    es6  不需要=

    export ...

    export default ...

    4.

    为什么有的地方用module.exports有的地方用export default

    和 Vue 无关,和 Webpack 有关。
    mole.exports 是遵循 CommonJS 模块格式
    exports default 是 ES6 的模块化写法

    为什么有的地方用module.exports有的地方用export default

    和 Vue 无关,和 Webpack 有关。
    mole.exports 是遵循 CommonJS 模块格式
    exports default 是 ES6 的模块化写法

    exports和module.exports的区别是什么

    mole.exports与exports的区别
    每一个node.js执行文件,都自动创建一个mole对象,同时,mole对象会创建一个叫exports的属性,初始化的值是 {}
    mole.exports = {};
    Node.js为了方便地导出功能函数,node.js会自动地实现以下这个语句
    foo.js
    exports.a = function(){
    console.log('a')
    }
    exports.a = 1
    test.js
    var x = require('./foo');
    console.log(x.a)
    看到这里,相信大家都看到答案了,exports是引用 mole.exports的值。mole.exports 被改变的时候,exports不会被改变,而模块导出的时候,真正导出的执行是mole.exports,而不是exports
    再看看下面例子
    foo.js
    exports.a = function(){
    console.log('a')
    }
    mole.exports = {a: 2}
    exports.a = 1
    test.js
    var x = require('./foo');
    console.log(x.a)
    result:
    2
    exports在mole.exports 被改变后,失效。
    是不是开始有点廓然开朗,下面将会列出开源模块中,经常看到的几个使用方式。
    ##mole.exports = View
    function View(name, options) {
    options = options || {};
    this.name = name;
    this.root = options.root;
    var engines = options.engines;
    this.defaultEngine = options.defaultEngine;
    var ext = this.ext = extname(name);
    if (!ext !this.defaultEngine) throw new Error('No default engine was specified and no extension was provided.');
    if (!ext) name += (ext = this.ext = ('.' != this.defaultEngine[0] ? '.' : '') + this.defaultEngine);
    this.engine = engines[ext] || (engines[ext] = require(ext.slice(1)).__express);
    this.path = this.lookup(name);
    }
    mole.exports = View;
    javascript里面有一句话,函数即对象,View 是对象,mole.export =View, 即相当于导出整个view对象。外面模块调用它的时候,能够调用View的所有方法。不过需要注意,只有是View的静态方法的时候,才能够被调用,prototype创建的方法,则属于View的私有方法。
    foo.js
    function View(){
    }
    View.prototype.test = function(){
    console.log('test')
    }
    View.test1 = function(){
    console.log('test1')
    }
    mole.exports = View
    test.js
    var x = require('./foo');
    console.log(x) //{ [Function: View] test1: [Function] }
    console.log(x.test) //undefined
    console.log(x.test1) //[Function]
    x.test1() //test1
    ##var app = exports = mole.exports = {};
    其实,当我们了解到原理后,不难明白这样的写法有点冗余,其实是为了保证,模块的初始化环境是干净的。同时也方便我们,即使改变了 mole.exports 指向的对象后,依然能沿用 exports的特性
    exports = mole.exports = createApplication;
    /**
    * Expose mime.
    */
    exports.mime = connect.mime;
    例子,当中mole.exports = createApplication改变了mole.exports了,让exports失效,通过exports = mole.exports的方法,让其恢复原来的特点。
    ##exports.init= function(){}
    这种最简单,直接就是导出模块 init的方法。
    ##var mongoose = mole.exports = exports = new Mongoose;
    集多功能一身,不过根据上文所描述的,大家应该不能得出答案。
    (摘自网络)

    exports和module.exports的区别是什么

    mole.exports与exports的区别
    每一个node.js执行文件,都自动创建一个mole对象,同时,mole对象会创建一个叫exports的属性,初始化的值是 {}
    mole.exports = {};
    Node.js为了方便地导出功能函数,node.js会自动地实现以下这个语句
    foo.js
    exports.a = function(){
    console.log('a')
    }
    exports.a = 1
    test.js
    var x = require('./foo');
    console.log(x.a)
    看到这里,相信大家都看到答案了,exports是引用 mole.exports的值。mole.exports 被改变的时候,exports不会被改变,而模块导出的时候,真正导出的执行是mole.exports,而不是exports
    再看看下面例子
    foo.js
    exports.a = function(){
    console.log('a')
    }
    mole.exports = {a: 2}
    exports.a = 1
    test.js
    var x = require('./foo');
    console.log(x.a)
    result:
    2
    exports在mole.exports 被改变后,失效。
    是不是开始有点廓然开朗,下面将会列出开源模块中,经常看到的几个使用方式。
    ##mole.exports = View
    function View(name, options) {
    options = options || {};
    this.name = name;
    this.root = options.root;
    var engines = options.engines;
    this.defaultEngine = options.defaultEngine;
    var ext = this.ext = extname(name);
    if (!ext !this.defaultEngine) throw new Error('No default engine was specified and no extension was provided.');
    if (!ext) name += (ext = this.ext = ('.' != this.defaultEngine[0] ? '.' : '') + this.defaultEngine);
    this.engine = engines[ext] || (engines[ext] = require(ext.slice(1)).__express);
    this.path = this.lookup(name);
    }
    mole.exports = View;
    javascript里面有一句话,函数即对象,View 是对象,mole.export =View, 即相当于导出整个view对象。外面模块调用它的时候,能够调用View的所有方法。不过需要注意,只有是View的静态方法的时候,才能够被调用,prototype创建的方法,则属于View的私有方法。
    foo.js
    function View(){
    }
    View.prototype.test = function(){
    console.log('test')
    }
    View.test1 = function(){
    console.log('test1')
    }
    mole.exports = View
    test.js
    var x = require('./foo');
    console.log(x) //{ [Function: View] test1: [Function] }
    console.log(x.test) //undefined
    console.log(x.test1) //[Function]
    x.test1() //test1
    ##var app = exports = mole.exports = {};
    其实,当我们了解到原理后,不难明白这样的写法有点冗余,其实是为了保证,模块的初始化环境是干净的。同时也方便我们,即使改变了 mole.exports 指向的对象后,依然能沿用 exports的特性
    exports = mole.exports = createApplication;
    /**
    * Expose mime.
    */
    exports.mime = connect.mime;
    例子,当中mole.exports = createApplication改变了mole.exports了,让exports失效,通过exports = mole.exports的方法,让其恢复原来的特点。
    ##exports.init= function(){}
    这种最简单,直接就是导出模块 init的方法。
    ##var mongoose = mole.exports = exports = new Mongoose;
    集多功能一身,不过根据上文所描述的,大家应该不能得出答案。
    (摘自网络)

    微宠网还为您提供以下相关内容希望对您有帮助:

    export、export default 、module.exports详解

    import后面没有{},module.exports后面和export default一样都是值,require后面有{}表示解构赋值,没有表示整体引入,import和require都可以引入export和module.exports,import只能写在js文件顶部,但是require可以写在任何地方.CommonJS模块输出是一个值的拷贝,...

    module.exports和export详解

    概念:module.exports和exports是属于commonJs规范,export和export default是ES6模块规范。exports 等于 module.exports,相当于在js文件头部,有一个module对象,module.exports = exports; exports是一个对象,所以可以exports多个值 1、对于要导出的属性,可以简单直接挂到exports对象上 2、对于类,为了...

    vue 导入、导出模块的几种方式

    ES6规范 模块导入方式:import ES6规范 模块导出方式:export、export default nodejs commonjs规范 模块导入方式:require nodejs commonjs规范 模块导出方式:exports、module.exports

    如何让node运行es6模块文件及其原理详解

    让 node 运行 es6 模块文件的方式有两种: 转码 es6 模块为 commonjs 模块 hook node 的 require 机制,直接让 node 的 require 加载 import/export1. 转码 es6 模块为 commonjs 模块因为 node 支持几乎所有除 import/export 外的语法,所以我们只需要将 import/export 转码成 require/exports,而不...

    模块化的理解和规范

    import XX from “路径” => 这是对应 export default {} 的格式 注意点:就是export 导入的必须按照导出的名称来接受,如果重名了,那么使用 as 来修改别名 eg: import { d as dd} from "路径" 当d变量重名的时候,就把个导出为dd import { a,b,c,add } from "./js/01.es6的导入和...

    小程序使用export无法导入使用

    这两个是es6的语法,在小程序中也是可以使用的export与exportdefault都是用来导出变量的,并且他们两个作用与exports相同,只是语法不同二者同样,export与exportdefault是es6用来导出模块的。

    JavaScript 中 import * as x from x'是否有明确的规范

    TypeScript 对 ES6 export 的转译,是将所有 export 的东西,都作为 exports,即 module.exports 的属性,比如 // test.ts export function hello() {} const a = 0;export default a;用 tsc 按 AMD 模块转译 tsc test.ts --module AMD 得到 define(["require", "exports"], function (...

    es5和es6的中的this有什么区别

    1,引入与导出方式不同 //ES5 var React = require("react");//ES6 import React, { Component, PropTypes } from 'react ?0?2 ?0?2导入: ES5使用require导入,而ES6使用了import //ES5 module.exports = Test;?0?2 //ES6 export default Test;?0?2 2,创建组件的方式不同 //ES5 var...

    模块化开发的核心?

    //exportconstnum1=123;//导出函数:exportfunctionadd(num1,num2){ returnnum1+num2 } //导出类 exportclassPerson{ run(){console.log('this.a')} } //导入函数和类 import{add,Person}from'./export.js'console.log(add(1,2));constp=newPerson();p.run()5、exportdefault:导入者...

    js import 和 require的区别

    ES6 模块之中,顶层的this指向undefined,即不应该在顶层代码使用this。Module 主要由两个命令组成,import和export,export用于规定模块的对外接口,import命令用于输入其他模块提供的功能 3.Export 模块是独立的文件,该文件内部的所有的变量外部都无法获取。如果希望获取某个变量,必须通过export输出,// ...

    Top