一、ES6模块输入输出
// actions.js export const GET_LIST = 'getList'; export const GET_OBJ_LIST = 'getObjList'; export const SET_OBJ_LIST = 'setObjList'; export function getListAct() { return { type: GET_LIST }; } export function getObjListAct(param) { return { type: GET_OBJ_LIST, param }; } export function setObjListAct(data) { return { type: SET_OBJ_LIST, data }; }
// 或者
function getListAct(data) { return { type: GET_LIST, data }; }
export { getListAct };
// reducer.js const initState = { list: [] }; export default function objList(state = initState, action) { }
// index.js import * as actions from './models/actions.js'; import reducer from './models/reducer.js';
// 应用
actions.getListAct()
// 也可以这样写 import {getListAct, getObjListAct, setObjListAct} from './models/actions.js'; import reducer from './models/reducer.js';
// 应用
getListAct()
二、阶段总结
可以看出,如果要用import * as from的方式把A文件导入C文件,前提是A文件是以export逐个导出的,模块的整体加载;
如果要用import from的方式把B文件导入C文件,前提是B文件是以export default统一导出的。
三、问题描述
A文件用node编写,B文件最终会在A文件里面运行,如果B文件写了import,将不能成功引入其他模块,需要改为require。
如果一个二方包既在server端跑,也在浏览器端跑,需要用module.exports导出,如果用export default导出会报错。
四、问题分析
1、module.exports导出的模块,可以用 import,require导入;
// 定义circle.js模块 function circleLength(r) { return 2 * Math.PI * r; } function circleArea(r) {return Math.PI * r * r; }; module.exports = { circleLength, circleArea }; // index.jsx // import * as circle from './circle'; const circle = require('./circle'); <div>{circle.circleLength(2)}</div> <div>{circle.circleArea(2)}</div>
2、export default导出的模块,不能用require直接导入,必须写成
require('./demo.js').default。
// 定义square.js模块 function squareArea(r) { return r * r; } export default squareArea; // index.jsx文件 // import square from './square'; const square = require('./square').default; <div>{square(2)}</div>
3、require,exports,module.exports属于AMD规范,import,export,export default属于ES6规范。
4、require支持动态导入,动态匹配路径,import对这两者都不支持。
5、require是运行时调用(可以在任意地方),import是编译时调用(在文件头,首先执行)。
6、require是赋值过程,import是解构过程。
7、babel会把es6模块转化为commonjs模块,由于浏览器不识别commonjs规范,还要经过webpack打包,包裹js模块,注入module、exports、require等环境变量,最后在浏览器中运行。
五、解决方案
在node文件中使用es6模块,如何避免报错?
1、在node中require符合commonjs规范的模块,不要用es6模块;
2、babel-register进行转换
require('@babel/register') ({ presets: [ '@babel/preset-env' ] }) module.exports = require('./demo.js');
3、node --experimental-modules(实验中,慎用!)
es6模块用mjs为后缀名,比如某node文件为demo.mjs。