理解一下ES6的模块化开发-----《整理》

1.模块化开发背景介绍:

2.模块化有哪些规范:

           AMD、CommonJS、ES6

           其中AMD是浏览器端规范,CommonJS是服务端规范,而ES6是一个统一的规范(虽然好多浏览器还不支持)

3.首先有个整体上的认知:

           ES6中定义的:import、export

           CommonJS中定义的:require、module.exports


4.介绍一下常见用法:

4.1ES6

 

export var a = 1;

//main.js
var a = 1;
var b = 2;
function foo(){};
function boo(){};
export {a, b, foo, boo as Boo};

//main2.js
export default defaultFoo; //export {defaultFoo as default};


//导出对象时需要加{}
//导出对象时可以为每一个属性指定别名
//可以同时导出多个属性


import {a, b} from './main.js'
import {foo as Foo, Boo as B} from './main.js'
import defaultFoo from './main2.js'    //import {default as defaultFoo} from './main2.js'

//导入的变量名必须与导出的名称一致
//导入时可以按需导入
//导入时可以指定别名

4.2CommonJS

//main.js
var a = {
    name: 'leeon',
    age: 23,
    setName: function(name){
        this.name = name
    }
}
module.exports = a;





var a = require('./main.js');

5.而在项目中,通常会使用到webpack+babel:

就出现了好多混用上面两种规范的情况,实际上只是由babel将es6转成了CommonJS,并不代表es6与CommonJS的规范是一回事儿。

而webpack则会将项目中的es6、CommonJS规范转换为自己独特的模块化语法。

那么babel在转换es6的模块化输入输出时做了什么?

babel 转换 es6 的模块输出逻辑非常简单,即将所有输出都赋值给 exports,并带上一个标志 __esModule 表明这是个由 es6 转换来的 commonjs 输出。

babel将模块的导出转换为commonjs规范后,也会将引入 import 也转换为 commonjs 规范。即采用 require 去引用模块,再加以一定的处理,符合es6的使用意图。
 

众所周知,require在引入依赖时加载的整个对象,不存在按需加载的优化,那么babel统一的将import转化为了require岂不是让项目引入了很多不必要的依赖?

注意:这里有个关于require与import的问题:

// counter.js
exports.count = 0
setTimeout(function () {
  console.log('increase count to', ++exports.count, 'in counter.js after 500ms')
}, 500)

// commonjs.js
const {count} = require('./counter')
setTimeout(function () {
  console.log('read count after 1000ms in commonjs is', count)
}, 1000)

//es6.js
import {count} from './counter'
setTimeout(function () {
  console.log('read count after 1000ms in es6 is', count)
}, 1000)


//read count after 1000ms in commonjs is 0
//read count after 1000ms in es6 is 1

这里的结论是:es6的导入方式是动态的,强绑定的方式,而commonjs的导入方式则是浅拷贝的方式传递 

demo来自知乎: https://www.zhihu.com/question/56820346 寸志大佬的回答

当然不是,1.使用 babel-plugin-component 等babel 插件会将依赖的引入方式优化;

import { React, ReactDom } from 'react'


//babel会先做这件事
var a = require('react');    //引入react中导出的全部属性
var React = a.React;
var ReactDom = a.ReactDom;

//而babel-plugin-component插件所做的事情就是将依赖最小化,当然,写导出文件时也需要有一定的技巧(意想之中)
import React from 'react/lib/React'
import ReactDom from 'react/lib/ReactDom'

2.webpack使用tree-shaking技术

webpack2 开始引入 tree-shaking 技术,通过静态分析 es6 的语法,可以删除没有被使用的模块。他只对 es6 的模块有效,所以一旦 babel 将 es6 的模块转换成 commonjs,webpack2 将无法使用这项优化。所以要使用这项技术,我们只能使用 webpack 的模块处理,加上 babel 的es6转换能力(需要关闭模块转换)。

注:webpack的tree-shaking仅仅对于原本就是使用es6规范的生效

 

总结:

babel会将es6转为CommonJS的方式(exports);

webpack则会将CommonJS与es6都转为自己的方式。

参考文章:

 https://segmentfault.com/a/1190000012386576 《import、require、export、module.exports 混合使用详解

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值