微信号:FrontDev

介绍:分享 Web 前端相关的技术文章、工具资源、精选课程、热点资讯

后端程序员的 Js 之旅 : 模块化(三)

2016-05-03 21:19 前端大全

(点击上方公众号,可快速关注)


作者:李少鹏(@BenjaLi) 

链接:http://lishaopeng.com/2016/02/19/js-module3/



这篇文章是「模块化」系列的最后一篇,聊一聊前端模块加载器。上一篇文章《模块化(二)》中提到的实现 AMD 规范的 RequireJS 就是一种比较常用的模块加载器,除此之外比较常用的有 Browserify 和 Webpack,接下来逐一介绍。


Browserify


npm 的模块非常丰富,但是其模块符合 CommonJS 规范,对浏览器不友好。Browserify 就是为了解决这个问题而生,递归分析应用中 require() 的调用顺序,将所有依赖的模块打包成一个 js 文件,浏览器通过一个 标签即可加载。

接下来再以 browserify 实现前两篇文章中的示例。


前提:node 和 npm 环境准备就绪,jQuery 已安装。


安装 browserify


npm install -g browserify


www/scripts 目录


math.js


exports.add = function(x, y) {

    return x + y;

};


increment.js


var math = require('./math');

exports.increment = function(val) {

    return math.add(val, 1);

}


main.js


var $ = require('jquery');

var inc = require('./increment').increment;

 

$(function() {

    $(':button').click(function() {

        var val = parseInt($('#val').val());

        var res = inc(isNaN(val) ? 0 : val);

        $('#val').val(res);    

    })

});


browserify 打包


在 www 目录下,使用 browserify 打包


browserify ./scripts/main.js -o bundle.js


index.html


www目录下的index.html文件


<!doctype html>

<html>

    <head>

    </head>

    <body>

        <div>

        Input Number: <input type="text" id="val">

        <input type="button" value="Plus One">

        </div>

        <script src="./bundle.js"></script>

    </body>

</html>


Webpack


Webpack 是一种功能强大的模块加载器,与 Browserify 相比,可以灵活按配置将 js 打成多个包按需加载,提高首次访问页面的速读,同时也支持 css 、图片等静态文件的管理。


同样,以 webpack 实现 incrememnt 功能。


前提:node 和 npm 环境准备就绪。


安装 webpack


npm install webpack -g


示例中还演示了加载 css 的功能,需要在 www 目录安装 css-loader 和 style-loader,不带 -g 参数。


npm install css-loader style-loader


www/styles 目录


style.css


body {

    background: #98887B;

}


www/scripts 目录


math.js 和 increment.js 同 Browserify,lib子目录有 jquery-2.2.0.js 文件。

main.js 文件略微不同,还加载了 css 文件。


require('../styles/style.css');

 

var $ = require('./lib/jquery-2.2.0');

var inc = require('./increment').increment;

 

$(function() {

    $(':button').click(function() {

        var val = parseInt($('#val').val());

        var res = inc(isNaN(val) ? 0 : val);

        $('#val').val(res);

    })

});


www 目录


www 目录增加 webpack 配置文件 webpack.config.js


module.exports = {

    entry: "./scripts/main.js",

    output: {

        path: __dirname,

        filename: "bundle.js"

    },

    module: {

        loaders: [

            { test: /\.css$/, loader: "style!css" }

        ]

    }

};


webpack 打包


在 www 目录下,使用 webpack 打包,由于存在配置文件,直接运行命令 webpack 即可


webpack


index.html


www 目录下的 index.html 同 Browserify 中的例子,由于加载了 css 底色会有不同。


模块加载器比较


这个表格是 Webpack 官网上所列的 RequireJS、Browserify、Webpack 支持特性的比较:


Feature webpack/webpack jrburke/requirejs substack/node-browserify
CommonJs require yes only wrapping indefine yes
CommonJs require.resolve yes no no
CommonJs exports yes only wrapping indefine yes
AMD define yes yes deamdify
AMD require yes yes no
AMD require loads on demand yes with manual configuration no
ES2015 import/export no no no
Generate a single bundle yes yes♦ yes
Load each file separate no yes no
Multiple bundles yes with manual configuration with manual configuration
Additional chunks are loaded on demand yes yes no
Multi pages build with common bundle with manual configuration yes
Concat in require require("./fi" + "le") yes no♦ no
Indirect require var r = require; r("./file") yes no♦ no
Expressions in require (guided) require("./templates/" + template) yes (all files matching included) no♦ no
Expressions in require (free) require(moduleName) with manual configuration no♦ no
Requirable files file system web file system
Plugins yes yes yes
Preprocessing loaders, transforms loaders transforms
Watch mode yes not required yes
Debugging support SourceUrl, SourceMaps not required SourceMaps
Node.js built-in libs require("path") yes no yes
Other Node.js stuff process, __dir/filename, global process, __dir/filename, global
Replacement for browser web_modules.web.js, package.json field, alias config option alias option package.json field, alias option
Minimizing uglify uglify, closure compiler uglifyify
Mangle path names yes no partial
Runtime overhead 243B + 20B per module + 4B per dependency 14.7kB + 0B per module + (3B + X) per dependency 415B + 25B per module + (6B + 2X) per dependency
Dependencies 19MB / 127 packages 11MB / 118 packages 1.2MB / 1 package


♦ in production mode (opposite in development mode)

X is the length of the path string


HACKHAT 也有一个第三方的模块加载器的对比文章 Module loader comparision: Webpack vs Require.js vs Browserify 可供参考。


结论


「后端程序员的 JavaScript 之旅 – 模块化」系列文章介绍了:模块模式,解决在天生模块化缺失的情况下如何根据 JS 自身的语言特性构建模块化的基本方法;流行的模块化规范 CommonJS 、AMD 和 ES 6 模块标准等,了解到模块化规范对生态圈的重要性;介绍了生态圈中常用的三种常用的模块加载器及其特点。


【今日微信公号推荐↓】

更多推荐请看值得关注的技术和设计公众号


其中推荐了包括技术设计极客 和 IT相亲相关的热门公众号。技术涵盖:Python、Web前端、Java、安卓、iOS、PHP、C/C++、.NET、Linux、数据库、运维、大数据、算法、IT职场等。点击《值得关注的技术和设计公众号》,发现精彩!



点击阅读原文,了解野狗

 
前端大全 更多文章 详解Javascript中的Object对象 结合个人经历总结的前端入门方法 前端不为人知的一面–前端冷知识集锦 一份优秀的前端开发工程师简历是怎么样的? 浅谈Web缓存
猜您喜欢 【干货】PHP中9大缓存技术 英语流利说基础数据平台 浅谈RDOP平台构建 设计公司大师带你走进“看不见的设计” 必看|数据行业新手职业生涯发展规划