Posted:
Dec 5, 2013
Tags:
Comments:
30 Comments

Browserify 跑在浏览器上的Node程序

从零开始nodejs系列文章,将介绍如何利Javascript做为服务端脚本,通过Nodejs框架web开发。Nodejs框架是基于V8的引擎,是目前速度最快的Javascript引擎。chrome浏览器就基于V8,同时打开20-30个网页都很流畅。Nodejs标准的web开发框架Express,可以帮助我们迅速建立web站点,比起PHP的开发效率更高,而且学习曲线更低。非常适合小型网站,个性化网站,我们自己的Geek网站!!

关于作者

  • 张丹(Conan), 程序员Java,R,PHP,Javascript
  • weibo:@Conan_Z
  • blog: http://blog.fens.me
  • email: bsspirit@gmail.com

转载请注明出处:
http://blog.fens.me/nodejs-browserify/

nodejs-browserify

前言

Nodejs的出现,为Javascript开辟了一条新的大路,让Javascript获得了新生。虽然Nodejs也基于Javascript语法和解释器,但是前后端各自有各自的库,无法重用真的很不舒服。

Browserify 通过预编译的方法,让Javascript前端可以直接使用Node后端的程序。我们可以用一套代码完成前后端,不仅工作量变少了,程序重用性增强,还可以直接在浏览器中使用大量的NPM第三方开源库的功能。

Web时代,将是我们创新与创造的新起点。

目录

  1. Browserify介绍
  2. Browserify安装
  3. Browserify命令行参数
  4. 在浏览器中运行Nodejs程序
  5. 在浏览器中模块化调用Nodejs程序

1. Browserify介绍

Browserify的出现可以让Nodejs模块跑在浏览器中,用require()的语法格式来组织前端的代码,加载npm的模块。在浏览器中,调用browserify编译后的代码,同样写在<script>标签中。

用 Browserify 的操作,分为3个步骤。

  • 1. 写node程序或者模块
  • 2. 用Browserify 预编译成 bundle.js
  • 3. 在HTML页面中加载bundle.js

Browserify 的发布页:http://browserify.org/

2. Browserify安装

系统环境

  • win7 64bit
  • Nodejs:v0.10.5
  • Npm:1.2.19

Browserify安装


~ D:\workspace\javascript>mkdir nodejs-browserify && cd nodejs-browserify
browserify@2.36.1 node_modules\browserify
├── inherits@1.0.0
├── deep-equal@0.1.0
├── duplexer@0.1.1
├── shell-quote@0.0.1
├── parents@0.0.2
├── through@2.3.4
├── stream-combiner@0.0.2 (duplexer@0.0.4)
├── deps-sort@0.1.1 (minimist@0.0.5)
├── optimist@0.5.2 (wordwrap@0.0.2)
├── browser-resolve@1.2.1 (resolve@0.6.1)
├── JSONStream@0.6.4 (jsonparse@0.0.5, through@2.2.7)
├── syntax-error@0.0.1 (esprima@0.9.9)
├── concat-stream@1.0.1 (bops@0.0.6)
├── insert-module-globals@1.3.1 (process@0.5.1, commondir@0.0.1, duplexer@0.0.4, through@2.2.7, JSONStream@0.4.4, lex
ical-scope@0.0.14)
├── module-deps@1.1.0 (minimist@0.0.5, resolve@0.6.1, detective@2.1.2)
├── browser-pack@1.1.0 (combine-source-map@0.3.0)
├── umd@1.3.1 (rfile@1.0.0, ruglify@1.0.0, uglify-js@2.4.6)
└── browser-builtins@2.0.5 (constants-browserify@0.0.1, os-browserify@0.1.1, console-browserify@1.0.1, vm-browserify@
0.0.1, punycode@1.2.3, buffer-browserify@0.2.2, crypto-browserify@1.0.9, http-browserify@0.1.14, zlib-browserify@0.0.3)

全局安装,安装过程提示错误。不过没有关系!


~ D:\workspace\javascript\nodejs-browserify>npm install browserify -g
D:\toolkit\nodejs\browserify -> D:\toolkit\nodejs\node_modules\browserify\bin\cmd.js
npm ERR! peerinvalid The package generator-karma does not satisfy its siblings' peerDependencies requirements!
npm ERR! peerinvalid Peer generator-angular@0.4.0 wants generator-karma@~0.5.0
npm ERR! System Windows_NT 6.1.7601
npm ERR! command "D:\\toolkit\\nodejs\\\\node.exe" "D:\\toolkit\\nodejs\\node_modules\\npm\\bin\\npm-cli.js" "install" "
browserify" "-g"
npm ERR! cwd D:\workspace\javascript\nodejs-browserify
npm ERR! node -v v0.10.5
npm ERR! npm -v 1.2.19
npm ERR! code EPEERINVALID
npm ERR!
npm ERR! Additional logging details can be found in:
npm ERR! D:\workspace\javascript\nodejs-browserify\npm-debug.log
npm ERR! not ok code 0

3. Browserify命令行参数

使用Browserify命令正常。


~ D:\workspace\javascript\nodejs-browserify>browserify
Usage: browserify [entry files] {OPTIONS}
Standard Options:
 --outfile, -o Write the browserify bundle to this file.
 If unspecified, browserify prints to stdout.
 --require, -r A module name or file to bundle.require()
 Optionally use a colon separator to set the target.
 --entry, -e An entry point of your app
 --ignore, -i Omit a file from the output bundle.
 --external, -x Reference a file from another bundle.
 --transform, -t Use a transform module on top-level files.
 --command, -c Use a transform command on top-level files.
 --standalone -s Generate a UMD bundle for the supplied export name.
 This bundle works with other module systems and sets the name
 given as a window global if no module system is found.
 --debug -d Enable source maps that allow you to debug your files
 separately.
 --help, -h Show this message
For advanced options, type `browserify --help advanced`.
Specify a parameter.
  • –outfile, -o: browserify日志打印到文件
  • –require, -r: 绑定模块名或文件,用逗号分隔
  • –entry, -e: 应用程序的入口
  • –ignore, -i: 省略输出
  • –external, -x: 从其他绑定引入文件
  • –transform, -t: 对上层文件进行转换
  • –command, -c: 对上层文件使用转换命令
  • –standalone -s: 生成一个UMB的绑定的接口,提供给其他模块使用。
  • –debug -d: 激活source maps调试文件
  • –help, -h: 显示帮助信息

高级命令:


~ D:\workspace\javascript\nodejs-browserify>browserify --help advanced
Advanced Options:
 --insert-globals, --ig, --fast [default: false]
 Skip detection and always insert definitions for process, global,
 __filename, and __dirname.
 benefit: faster builds
 cost: extra bytes
 --detect-globals, --dg [default: true]
 Detect the presence of process, global, __filename, and __dirname and define
 these values when present.
 benefit: npm modules more likely to work
 cost: slower builds
 --ignore-missing, --im [default: false]
 Ignore `require()` statements that don't resolve to anything.
 --noparse=FILE
 Don't parse FILE at all. This will make bundling much, much faster for giant
 libs like jquery or threejs.
 --deps
 Instead of standard bundle output, print the dependency array generated by
 module-deps.
 --list
 Print each file in the dependency graph. Useful for makefiles.
 --extension=EXTENSION
 Consider files with specified EXTENSION as modules, this option can used
 multiple times.
  • –insert-globals, –ig, –fast: 跳过检查,定义全局变量。[default:false]
  • –detect-globals, –dg: 检查全局变量是否存在。 [default:true]<
  • –ignore-missing, –im: 忽略require()函数。[default: false]
  • –noparse=FILE: 不解析文件,直接build。
  • –deps: 打印完整输出日志
  • –list: 打印每个文件的依赖关系
  • –extension=EXTENSION: 指名扩展名的文件做为模块加载,允许多次设置

4. Browserify使用:在浏览器中运行Nodejs程序

新建4个文件:

  • multiply.js: 乘法计算
  • square.js: 平方计算,依赖multiply.js
  • index.js: node启动程序,调用square.js
  • index.html: 用于显示的HTML网页

新建文件:multiply.js


~ vi multiply.js
module.exports = function (a, b) {
 console.log("js:multiply");
 return a * b;
};

新建文件:square.js


~ vi square.js
var multiply = require('./multiply');
module.exports = function (n) {
 console.log("js:square");
 return multiply(n, n);
};

新建文件:index.js


~ vi index.js
var square = require('./square');
console.log("js:index");
console.log(square(125));

在node环境中运行


~ node index.js
js:index
js:square
js:multiply
15625

用browserify编译index.js文件到bundle.js


~ browserify index.js > bundle.js

新建文件:index.html


<!DOCTYPE html>
<html>
<head>
<title>Browserify</title>
<style>input{width:50px;}</style>
</head>
<body>
<h1>Browserify</h1>
<script src="bundle.js"></script>
</body>
</html>

在index.html中,我们加载刚才生成的bundle.js文件。

在浏览器中预览效果:

browserify-console

5. 在浏览器中模块化调用Nodejs函数

新建文件:

  • multiply.js: 同上面的文件
  • module.html: 用于显示的HTML网页

查看文件:multiply.js


~ vi multiply.js
module.exports = function (a, b) {
 console.log("js:multiply");
 return a * b;
};

用browserify编译multiply.js文件到bundle.js,作为模块

~ browserify -r ./multiply.js > bundle.js

新建文件:module.html


<!DOCTYPE html>
<html>
<head>
<title>Browserify</title>
<style>input{width:50px;}</style>
</head>
<body>
<form>
<p>
<input type="text" id="x" value="2"/> * <input type="text" id="y" value="3" /> = <span id="result"></span>
</p>
<input type="button" onclick="add()" value="M1"/>
<input type="button" onclick="add2()" value="M2"/>
</form>
<script src="bower_components/jquery/jquery.min.js"></script>
<script src="bundle.js"></script>
<script>
function add(){
var x = parseInt($('#x').val());
var y = parseInt($('#y').val());
console.log(x*y);
$('#result').text(x*y);
}
var m = require('./multiply.js');
function add2(){
var x = parseInt($('#x').val());
var y = parseInt($('#y').val());
console.log(m);
console.log(x*y);
$('#result').text(m(x,y));
}
</script>
</body>
</html>

在浏览器中打开:
browserify-click

  • 点击M1,通过add1函数计算出6
  • 点击M2,通过add2函数,调用bundle.js中的multiply.js的函数,计算出6

转载请注明出处:
http://blog.fens.me/nodejs-browserify/

[画像:打赏作者]

Post Views: 3,651

This entry was posted in Javascript语言实践

0 0 votes
Article Rating
Subscribe
Notify of

This site uses Akismet to reduce spam. Learn how your comment data is processed.

30 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
jiyinyiyong
12 years ago

建议增加 watchify.. 另外一般调试的话, –debug 参数是必开的.

0
Reply
Reply to jiyinyiyong
12 years ago

watchify,是另外一个项目吧?

0
Reply
jiyinyiyong
Reply to Conan Zhang
12 years ago

其实就是 browserify –watch-files

0
Reply
Reply to jiyinyiyong
12 years ago

watch还是用grunt好点吧

0
Reply
jiyinyiyong
Reply to Conan Zhang
12 years ago

这个是作者定制的 watch 功能, 比 Grunt 用起来性能高.
当然这主要适合用在命令行里, Grunt 就是写在构建脚本里好处

0
Reply
Reply to jiyinyiyong
10 years ago

都说道自动化工具了,那还不用grunt。。。

0
Reply
penJunTan
11 years ago

之前只关注到 AMD 在浏览器端优化方案: r.js
这个 commonJs 在浏览器端解决方案 browserify 看来更有野心啊

0
Reply
Reply to penJunTan
11 years ago

确实,browserify 很有野心的。如果能完全打通 browser和node,又会带来了一种新的思路。

0
Reply
Annie
11 years ago

你好。看你上面的说明,是不是 browserify 是将 node 的模块直接拿到浏览器上用,而不是 browserify 另外去实现了一套跟 node 一样的模块放到浏览器用?

0
Reply
Reply to Annie
11 years ago

你好。
1. 通过browserify的封装,可以直接让node程序运行在浏览器中。
2. browserify其实是把原node的程序自动重新改写了,把所有的依赖都压缩到1个文件中,变成一个纯的js文件,在浏览器中运行。

3. browserify封装是自动完成的,我们只需要执行一条命令就可以了,

0
Reply
Annie
Reply to Conan Zhang
11 years ago

那调用通过 browserfiy 自动重新改写的 node 模块(比如 buffer)会有性能上的差异吗?因为我们知道 node 是可以直接调用到 native 的 c 的部分,不知道 browserify 的调用层次是怎样的?封装后的性能有没有影响到?

0
Reply
Reply to Annie
11 years ago

1. 这种封装只是function call,没有性能的差异。
2. native的调用都是基于v8,也不应该有差异。

0
Reply
mityburner
11 years ago

用楼主的方法,报了个错Uncaught ReferenceError: require is not defined

0
Reply
Reply to mityburner
11 years ago

问题描述不清楚,哪里出了错?

0
Reply
mityburner
Reply to Conan Zhang
11 years ago

问题解决了,是编译的问题。谢谢

0
Reply
cc
11 years ago

browserify 对浏览器的兼容情况不知道怎么样?

0
Reply
Reply to cc
11 years ago

你可以在官网找到浏览器兼容介绍,http://browserify.org/
IE(7,8,9,10), chrome(14,15,16),FF(10,11,12,13),Opera(10,11), Safari(5.0, 5.1) 主流基本都支持

0
Reply
rambo
11 years ago

楼主 可以在浏览器上访问fs模块不? 哈哈

0
Reply
Reply to rambo
11 years ago

我没试过,理论上是不行的,浏览器没有本地文件系统的访问权限。

0
Reply
Reply to rambo
10 years ago

肯定不行哈,你要知道browserify做的工作就是预编译,查找依赖,前置的一个过程

0
Reply
Reply to yanhaijing
10 years ago

🙂

0
Reply
cc
10 years ago

请教下,browserify 的模块能异步加么?所有模块都打包成一个文件可能会很大呀。。

0
Reply
Reply to cc
10 years ago

写文章时候,browserify 所有代码都是打包到一起的;我没有注意后来有没有优化。

0
Reply
NiKaWaLi
10 years ago

$(‘#result’).text(m(x,y)); 这一行报错:Uncaught Type Error: undefined is not a function.

0
Reply
NiKaWaLi
10 years ago

已解决, var m = require(‘./multiply.js’);—->var m = require(‘/multiply.js’); 路径问题

0
Reply
Reply to NiKaWaLi
10 years ago

刚看到,解决就好。:-)

0
Reply
newebug
10 years ago

预编译后函数和参数都被优化成a,b,c,d了,楼主有什么关于浏览器调试好的建议吗?

0
Reply
Reply to newebug
10 years ago

chrome按F12,FireFox的Firebug。

0
Reply
pc
9 years ago

C:UsersadminDesktopnode>browserify -r .multiply.js > bundel.js
Error: Cannot find module ‘C:UsersadminDesktopnodemultiply.js’ from ‘C:Use
rsadminDesktopnode’
at C:UsersadminAppDataRoamingnpmnode_modulesbrowserifynode_modulesr
esolvelibasync.js:55:21
at load (C:UsersadminAppDataRoamingnpmnode_modulesbrowserifynode_mod
ulesresolvelibasync.js:69:43)
at onex (C:UsersadminAppDataRoamingnpmnode_modulesbrowserifynode_mod
ulesresolvelibasync.js:92:31)
at C:UsersadminAppDataRoamingnpmnode_modulesbrowserifynode_modulesr
esolvelibasync.js:22:47
at FSReqWrap.oncomplete (fs.js:82:15)

模块是存在的,但是编译的时候确报找不到,求楼主解答

0
Reply
Reply to pc
9 years ago

browserify -r ./multiply.js > bundel.js

是不是路径的问题?!

0
Reply
wpDiscuz
30
0
Would love your thoughts, please comment.x
()
x

AltStyle によって変換されたページ (->オリジナル) /