webpack 学习(一)- 浅析JavaScript的组件系统

简介

本文主要是翻译webpack官网文档,参考网络资料,添加部分自己的理解。

起初,JavaScript(以下简称JS)语言仅仅是Web前端技术,采取<script></script> 标签方式定义组件之间的引用、导出变量与方法。
随着传统的web sites演变成web apps,以下的现象越发明显:

  • 无论是Web前端或者Web后端,越来越多的Java Script在正在被使用
  • 富客户端化,Web前端的功能越来越强大
  • 越来越少的Web前端页面重载(更加复杂的Java Script代码)

    庞大的代码库,需要更加高效的组织。Module(组件)方式系统,成为大多数开发人员的选择。

组件系统

存在很多定义组件之间的依赖、导出组件接口的方法:

  • <script></script>标签方法
  • CommonJs
  • AMD
  • ES6组件
  • 其他

script 标签 ###

在非组件系统中,使用script标签,定义组件之间的依赖,会在Java Script代码或者html文件中多次出现:

<script src='module1.js'></script>
<script src='module2.js'></script>
<script src='lib1.js'></script>

各个组件提供接口给全局对象(window对象)使用。之后,在全局对象实例中,我们能够自由地使用这些接口。
这种管理组件依赖的方法,存在以下缺点:

  1. 在全局对象里Java Script组件容易产生冲突。
  2. 我们必须关心组件的加载顺序。
  3. 我们必须了解各个Java Script组件的依赖关系。
  4. 在大项目中,Java Script组件列表,会变得非常冗长,并难以维护。

CommonJs 同步require

CommonJs使用同步的require方法加载依赖组件,同时返回创建依赖组件的接口。Java Script组件可以通过:

  1. 配置module.exports的参数 (nodejs开发者非常熟悉的方式)

  2. 添加exports对象的属性

方式设置组件的接口。

CommonJs组件,主要概念如下:

定义作用说明
module组件标识module关键字,代表组件本身
module.exports组件的导出接口组件的导出接口,方法或者变量,类似java语言的public修饰符号
exports组件的导出对象
require(‘dependencies’)加载组件引入外部组件,类似java语言的import功能

代码实例:

require("module");
require("../file.js");
exports.doStuff = function(){};
module.exports = someValue;

此种组件化系统存在以下特点
优点:

1、适用于服务端组件,组件单次加载到Cache里,可以被重复使用。
2、存在许多成熟的Java Script组件(通过npm管理)。
3、 简单易用。

缺点:

1、组件,通过阻塞方式的加载,不适合网络应用。网络应用需要异步操作。
2、缺少多个依赖组件的并行加载。

实现:

  1. nodejs - 服务端
  2. browserify
  3. modules-webmake
  4. wreq - 客户端

AMD :异步require

AMD,Asynchronous Module Definition,异步组件定义,很多需要使用组件系统的前端开发人员定义了AMD。
CommonJs主要是针对JS的后端运行制定的标准,无法适应前端的需求。
服务端的JS、客户端JS的不同点如下:

序号服务端JavaScript客户端JavaScript
场景JS代码,在服务端由解释器执行多次JS代码,由服务端分发到各个客户端,再由Web浏览器解释执行
性能瓶颈服务端的CPU与内存服务端与Web浏览器之间的带宽
读取方式通过读取磁盘加载JS代码Web浏览器通过网络下载JS代码

AMD规范,针对客户端Java Script的运行环境,制定规范。

 require(["module","../file"],function(module,file){/*...*/});
 define("mymodule",["dep1","dep2"],function(d1,d2){
    return someExportedValue;
});

优点:

1、异步加载,适合前端环境。
2、支持依赖组件并行加载。

缺点:

1、编码开销较大,代码更难开发与阅读。

实现:

require.js - 客户端
curl - 客户端

阅读更多关于CommonJsAMD

ES6 组件

ECMAScript 2015 (6th Edition)标准添加了Java Script组件之间互相引用的标准。

import "jquery";
export function doStuff() {}
module "localModule" {}

优点:

1、静态分析容易
2、ES标准是以后的发展趋势

缺点:

1、本地浏览器支持需要时间
2、此种模式的Java Script组件较少。

组件传输

虽然web客户端的组件是在浏览器运行,但是都是由web服务端下载至客户端。
关于web客户端组件的传输,存在两个极端策略:

  1. 一次请求,仅传输一个组件

    优点:仅传输必须的组件
    缺点:多次请求,意味着高负载,给web app带来更高的启动延时。

  2. 一次请求,传输所有组件

    优点:网络畅通时,低负载,更低延时
    缺点:传输了(当时)无用的组件

    这两种传输策略都曾经广泛应用,但都是次优的。

分块传输 Chunked Transferring

我们可以考虑,在取两者之间的平衡策略。

在编译所有组件时,将组件集合分割为多个批次(或者区块)。

某个批次在被请求时,再传输。既解决前者高负载、高启动延时的问题,又避免过多的传输无用组件。
开发者需要确定分割点,然后由webpack(grunt、gulp等)组件系统完成具体的分组划分工作。

webpack组件系统除了支持Java Script组件的,还通过加载器支持其他资源文件:

  • 样式文件
  • 图片
  • 字体
  • html模板
  • coffeescript → javascript
  • elm → javascript
  • less stylesheets → css stylesheets
  • jade templates → javascript which generates html
  • etc

    语法类似:

require("./style.less");
require("./template.jade");
require("./image.png");

程序分析 STATIC ANALYSIS

当编译所有组件时,webpack组件系统的程序分析模块,会尝试理清这些组件之间的依赖关系。
通常,只能发现无表达式语句的简单依赖,但是经常会出现类似语句:require("./templates/" + name + ".jade")
许多代码库,都具有不同的风格。有些是非常奇怪的。webpack必须充分考虑现有代码的可用性以及兼容性。

参考文档

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值