为什么使用webpack

前言:webapp 一般来说是一个单页面应用,每一个视图以异步的方式进行加载,页面在加载的过程中会加载大量的js代码,为了保证这些代码在浏览器快速有序的的加载,需要我们使用模块化系统

模块系统的发展(随便巴拉几个)

1.CommonJS

服务器端的node.js遵循的就是CommonJS规范,改规范的核心思想就是允许模块通过require方法来同步加载所依赖的其他模块,然后通过exports或者module.exports来导出需要暴露的接口

优缺点:便于重用,但是同步的模块加载方式不适合在浏览器环境中,浏览器资源是异步加载的

实现:服务器端的Node.js,Browserify,浏览器端的 CommonJS 实现,可以使用 NPM 的模块,但是编译打包后的文件体积可能很大,modules-webmake,类似Browserify,还不如 Browserify 灵活,wreq,Browserify 的前身

2.AMD

Asynchronous Module Definition规范其实只有一个主要接口define(id?, dependencies?, factory),它要在声明模块的时候指定所有的依赖dependencies,并且还要当做形参传到factory中,对于依赖的模块提前执行,依赖前置。

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

优点:适合在浏览器环境中异步加载模块,可以并行加载多个模块

缺点:提高了开发成本,代码的阅读和书写比较困难,模块定义方式的语义不顺畅。不符合通用的模块化思维方式,是一种妥协的实现

实现:RequireJS curl

3.CMD

Common Module Definition规范和 AMD 很相似,尽量保持简单,并与 CommonJS 和 Node.js 的 Modules 规范保持了很大的兼容性。

define(function(require, exports, module){var$ =require('jquery');varSpinning =require('./spinning');  exports.doSomething = ...module.exports = ...})

优点:依赖就近,延迟执行,可以很容易在 Node.js 中运行

缺点:依赖 SPM 打包,模块的加载逻辑偏重

实现:Sea.js coolie

4.UMD

Universal Module Definition规范类似于兼容 CommonJS 和 AMD 的语法糖,是模块定义的跨平台解决方案。

5.ES6 模块

ECMAScript6 标准增加了 JavaScript 语言层面的模块体系定义。ES6 模块的设计思想,是尽量的静态化,使得编译时就能确定模块的依赖关系,以及输入和输出的变量。CommonJS 和 AMD 模块,都只能在运行时确定这些东西。

import"jquery";exportfunctiondoStuff(){}module"localModule"{}

优点:容易进行静态分析,面向未来的 ECMAScript 标准

缺点:原生浏览器端还没有实现该标准,全新的命令字,新版的 Node.js才支持

实现:

Babel

期望的模块系统

我们期望可以兼容多种模块风格,尽量可以利用自己已有的代码,不仅仅只是javaScript模块化,还有css、图片、字体等资源也需要模块化

前端模块加载

前端模块要在客户端中执行,所以他们需要增量加载到浏览器中。

模块的加载和传输,我们首先能想到两种极端的方式,一种是每个模块文件都能单独请求,另一种是把所有模块打包成一个文件然后只请求一次,显而易见,每个模块都发起单独的请求造成请求次数过多,导致应用启动速度慢;一次请求加载所有的模块导致流量浪费,初始化过程过慢。这两种都不是好的解决方案,他们过于简单粗暴 

分块传输,按需进行懒加载,在实际用到某些模块的时候再增量更新,才是较为合理的模块加载方案。

要实现模块的按需加载,就需要一个对整个代码库中的模块进行静态分析、编译打包的过程。

所有资源都是模块

在上面的分析过程中,我们提到的模块仅仅是指JavaScript模块文件。然而,在前端开发过程中还涉及到样式、图片、字体、HTML 模板等等众多的资源。这些资源还会以各种方言的形式存在,比如 coffeescript、 less、 sass、众多的模板库、多语言系统(i18n)等等。

如果他们都可以视作模块,并且都可以通过require的方式来加载,将带来优雅的开发体验,比如:

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

那么如何做到让require能加载各种资源呢?

静态分析

在编译的时候,要对整个代码进行静态分析,分析出各个模块的类型和他们的依赖关系,然后将不同类型的模块提交给适配的加载器来处理,比如一个用LESS写的样式模块,可以先用LESS加载器将它转成一个css模块,在通过css模块把他插入到页面的同时,为了能利用已经存在的各种框架和已经写好的文件,我们还需要一个模块加载的兼容策略,来避免重写所有的模块

那么接下来,让我们开始 Webpack 的神奇之旅吧。

标签中执行。Webpack 就是在这样的需求中应运而生。

本文摘至:http://zhaoda.net/webpack-handbook/module-system.html

你可能感兴趣的:(为什么使用webpack)