您的位置:首页 > Web前端 > JavaScript

浅谈JavaScript模块:Bundling

2016-04-17 14:26 471 查看
模块,依赖管理和动态加载应该是大家对任何现代编程语言一个基本要求。在2015年,这些都是一些新特性被添加到了JavaScript中。

在NodeJS中,模块化被广泛使用,但在这里我们的重点将是我们如何在浏览器端模块化编程。我们将探讨一些历史,对现状的分析以及和对当前各种解决方案的比较:Browserify,WebPACK中和JSPM。

模块的历史

自1995年JavaScript诞生至现在,浏览器原生并不支持模块。Node和CommonJS诞生自2009年,并在NPM使用绝大多数的package使用CommonJS的模块。

Browserify发布于2011年,为浏览器带来了CommonJS的模块化用法,允许客户端JavaScript
require
NPM package。该工具bundle(捆绑)了所有所需的依赖到一个单一的JavaScript文件。

过去

像jQuery这类库,会暴露一个全局对象给
window


window.$ = function() { ... };


通过script标签引入脚本,使用它暴露的对象

<script src="jquery.js"></script>
<script>
$(function() { ... });
</script>


自己的代码通常顶一个全局命名空间,像
App
一样,以防止污染全局z作用域。如果没有这个,很容易造成命名冲突。

var App = {};
App.Models = {};
App.Models.Note = function() {};


将来

使用ES6 module 导出对象

export default function $() { ... }


引入模块到本地作用域并且使用它

import $ from 'jquery';

$(function() { ... });


没有全局要求

来源顺序无关

可以访问NPM

无需自己定义命名空间

在任何时候根据需要动态地加载模块

目前

目前的状况真的很复杂。首先,有多种模块化的方案可以使用:

CommonJS

AMD

UMD

ES6 Modules

bundle文件的工具

Browserify

jspm

Webpack

Gulp

transpiler工具

Babel结合ES6

CoffeeScript

TypeScript

另外,还有一些可以允许动态加载的工具

requirejs

systemjs

共识

有几件事情,我们可以同意:

ES2015 module是JavaScript未来统一的模块化方式。

Babel是目前的ES2015编译器。

如果你现在就想使用模块,这将很可能多多少少涉及在一些CommonJS。

让我们来通过简单配置使用Browserify,WebPACK中和JSPM,这些是最重要的JavaScript bundler。

新建一个工程

mkdir modules-app
cd modules-app
npm init -y
npm install --save-dev browserify webpack jspm
mkdir src
touch src/{entry,lib}.js index.html


更新一下index.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Modules!</title>
</head>
<body>
<script src="bundle.js"></script>
</body>
</html>


至此,启动一个本地服务器。

Browserify

Browserify可以允许在浏览器端使用
require("modules")
语法,最终bundle所有依赖。


打开
src/lib.js
添加第一个模块

var double = function(number) {
return number * 2;
}

module.exports = {
double: double
}


打开
src/entry.js
我们将
require
第一个模块,调用该模块.

var lib = require('./lib.js');
console.log(lib.double(2));


package.json
文件中更新
script


"scripts": {
"browserify": "browserify ./src/entry.js -o ./bundle.js"
}


在项目的根目录下运行
npm run browserify


browserify会在根目录下创建一个bundle.js文件,打开index.html,控制台会出现4。

Browserify 不仅仅可以bundle自己写的js文件,它还可以结合npm module一起使用,下面使用lodash看看。

执行
npm install lodash


编辑
src/lib.js


var sum = require('lodash/sum');

var double = function(number) {
return number * 2;
}
var addFive = function(number) {
return sum([number, 5]);
}

module.exports = {
double: double,
addFive: addFive
}


编辑
src/entry.js
调用
addFive
函数

var lib = require('./lib.js');
console.log(lib.double(2));
console.log(lib.addFive(2));


使用
npm run browserify
创建bundle.js,打开index.html, 可以看到在控制台输出4和7,说明lodash引入成功了。

如果你已经跟着动手执行到了这一步了,你就应该发现了在文章开头,模块化的各种好处了。

没有全局要求

来源顺序无关

可以访问NPM

无需自己定义命名空间

稍后我们将看看如何在运行时动态加载module

Webpack

Webpack中是一个module bundler。 Webpack持有依赖性的模块,并生成表示这些模块的静态资源。

在package.json中添加一个新的script

"webpack": "webpack ./src/entry.js bundle.js"


运行
npm run webpack


webpack将重写bundle.js文件,输出的结果与之前是一样的。

尝试运行
npm run browserify
npm run webpack
,对比看看编译之后的bundle.js文件的差异。了解这些工具的内部是如何工作的并不是首要解决的任务,重要的是,虽然的实现不同,它们基本上是将CommonJS模块编译集成供标准的浏览器使用。每个模块被置于bundle.js内的函数内,并分配一个ID,以便它可以根据需要时加载。

webpack的功能远远不止这些。它就像一把module bundler中的瑞士军刀。webpack中还附带了额外的开发工具,像 hot module replacement,类似于LiveReload,当模块发生改变时,它会自动重新加载在浏览器中各个模, 但没有刷新页面。

get started webpack

参考文章:http://www.sitepoint.com/javascript-modules-bundling-transpiling/?utm_source=javascriptweekly&utm_medium=email
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息