browserify
随着美丽的野兽(我们称为网络)的发展,JavaScript实现变得越来越复杂。 我们中的许多人现在都在使用JavaScript模块-独立运行的组件可以一起工作,成为一个整体,但是很高兴可以替换任何组件而不会引起大决战。 我们许多人一直在使用AMD模块模式和RequireJS来巧妙地完成此任务。
去年,Browserify登场并带来了很多兴奋。 随着尘埃落定,我想概述一下Browserify是什么,它如何工作以及将其添加到工作流程中的一些选项。
什么是Browserify?
Browserify允许我们在浏览器中使用node.js样式模块。 我们定义了依赖项,然后Browserify将其全部捆绑到一个整洁JavaScript文件中。 您可以使用require('./yourfancyJSfile.js')
语句包含所需JavaScript文件,还可以从npm导入公共可用的模块。 对于Browserify来说,为您生成源映射也非常简单,以便您可以单独调试每个JS文件,尽管事实上它们都已合并在一起。
为什么要导入节点模块?
导入模块是一种幸运– require()
访问大量站点来下载JavaScript的库,只需使用require()
语句将其包括在内,确保已安装模块并且一切正常即可。 可以使用常用JavaScript库,例如jQuery , Underscore , Backbone甚至Angular (作为非官方发行版)。 如果您正在一个已经运行了节点的站点上工作,则可以通过一种通用的结构化所有JS的方式进一步简化操作。 我真的很喜欢这个概念。
您需要什么
要开始使用Browserify,您需要的最低要求是:
- node.js
- npm –默认情况下随节点一起安装。
- Browserify –我将解释如何安装这一程序。
- 准备好应对JavaScript模块包!
入门
首先,您需要在计算机上安装node和npm 。 如果您正在寻找安装这些组件的指导,请转到上面的链接。 如果您完全陷入困境,请尝试通过软件包管理器安装Node.js的这些说明。 您实际上无需进行任何节点工作即可使用Browserify。 我们安装节点仅仅是因为npm运行它。 获得npm后,可以使用以下命令安装Browserify:
npm install -g browserify
我们在这里所做的是使用npm在您的计算机上全局安装Browserify( -g
告诉npm全局安装模块)。
如果您收到以以下内容开头的错误:
Error: EACCES, mkdir '/usr/local/lib/node_modules/browserify'
然后,您将遇到权限问题。 您可以使用sudo
命令,但是我建议改签这篇文章。
创建您的第一个Browserify文件
首先让我们来创建一个Browserified JavaScript文件导入一个非常受欢迎的模块, 下划线 。 我们将使用Underscore跟踪超人。 我已经将我的JS文件main.js
,并将其放置在项目的js
文件夹中。
我们首先使用JavaScript中的Browserify的require()
语句将_
变量分配给Underscore:
var _ = require('underscore');
接下来,我们将使用Underscore中的each()
和find()
函数。 我们将搜索两个名称数组,然后运行console.log
来说明是否看到超人。 Lex Luthor只能梦想的高级东西。 我们最终JavaScript代码如下所示:
var _ = require('underscore'),
names = ['Bruce Wayne', 'Wally West', 'John Jones', 'Kyle Rayner', 'Arthur Curry', 'Clark Kent'],
otherNames = ['Barry Allen', 'Hal Jordan', 'Kara Kent', 'Diana Prince', 'Ray Palmer', 'Oliver Queen'];
_.each([names, otherNames], function(nameGroup) {
findSuperman(nameGroup);
});
function findSuperman(values) {
_.find(values, function(name) {
if (name === 'Clark Kent') {
console.log('It\'s Superman!');
} else {
console.log('... No superman!');
}
});
}
我们想要确保Browserify尝试将npm模块添加到我们的项目时能够找到它。 这样做的基本知识包括打开终端,导航到保存JavaScript项目的文件夹,然后运行以下命令在该文件夹中安装Underscore:
npm install underscore
对于不熟悉node和npm的工作原理的人,这将在项目中创建一个名为node_modules
的文件夹,其中包含node_modules
模块的代码。 该命令从位于https://registry.npmjs.org/underscore
的npm存储库检索最新版本的Underscore。 通过该模块在我们的node_modules
文件夹中,Browserify现在可以找到并使用它。
首次运行Browserify
当我们运行Browserify时,它将需要使用所有附加模块构建一个新JavaScript文件。 在这种情况下,它将构建一个包含UnderscoreJavaScript文件。 我们需要确定这个新文件的名称,我已经使用findem.js
。 我从项目的根文件夹运行以下命令:
browserify js/main.js -o js/findem.js -d
该命令读取main.js
文件,并将其输出到-o
选项定义的findem.js
文件中。 我包括了-d
选项,以便它也可以为我们生成一个源映射,这样我们就可以将main.js
调试和underscore
清晰地作为单独的文件。
使用Browserify输出
从那里开始,就像在页面上包含文件一样简单,就像其他任何JS文件一样:
<script src="js/findem.js"></script>
导入自己JavaScript文件
您的所有应用程序都不太可能来自节点模块。 要包含自己JavaScript,可以使用相同的require()
函数。 JavaScript代码的下面一行将导入名为JS文件your_module.js
到greatestModuleEver
变量:
greatestModuleEver = require('./your_module.js');
要像这样导入我们JavaScript,我们只需要将JavaScript构造为一个模块即可。 为此,我们必须定义module.exports
。 一种显示方法如下所示。
module.exports = function(vars) {
// Your code
}
边注!
![](https://i-blog.csdnimg.cn/blog_migrate/b50dea3cbd24ae3b8574d1ba189ad643.png)
免费学习PHP!
全面介绍PHP和MySQL,从而实现服务器端编程的飞跃。
原价$ 11.95 您的完全免费
如果您有一堆不在npm中JavaScript库,并且您正在寻找一种将它们全部放入Browserify的简便方法,则可以使用Browserify-shim npm模块为您转换这些文件。 我们不会在本文中使用它,但是一些开发人员可能希望这样做。
我们的模块示例
为了给出一个简单的例子,我们将从上一个超级英雄搜索示例中取出数组,并用一个单独的JS模块替换它们,该模块返回一个名称数组。 该模块如下所示:
module.exports = function() {
return ['Barry Allen', 'Hal Jordan', 'Kara Kent', 'Diana Prince', 'Ray Palmer', 'Oliver Queen', 'Bruce Wayne', 'Wally West', 'John Jones', 'Kyle Rayner', 'Arthur Curry', 'Clark Kent'];
}
接下来,我们将使用names = require('./names.js')
将该模块导入代码中:
var _ = require('underscore'),
names = require('./names.js');
findSuperman(names());
function findSuperman(values) {
_.find(values, function(name) {
if (name === 'Clark Kent') {
console.log('It\'s Superman!');
} else {
console.log('... No superman!');
}
});
}
我们的names
变量引用了我们模块中导出的函数。 因此,当我们将名称数组传递给我们的findSuperman()
函数时,我们将上述names
变量用作带括号的函数。
从命令行再次运行该browserify
命令以对其进行编译,然后在浏览器中将其打开,它应会按预期运行,搜索数组中的每个值并记录是否看到超人:
在我们的应用程序中传递变量和共享模块
为了给这个相当简单的超人狩猎应用程序增加一点复杂性,让我们将findSuperman()
函数变成一个模块。 这样,从理论上讲,我们可以在JavaScript的各个部分中找到“超人”,并且将来总是可以很轻松地用更有效的模块替换“超人”狩猎模块。
我们可以将变量传递给我们的模块,并在我们的module.exports
函数中使用它们,因此我们将在名为findsuperman.js
的文件中创建一个模块,该文件将被分配一个名称数组:
module.exports = function (values) {
var foundSuperman = false;
_.find(values, function(name) {
if (name === 'Clark Kent') {
console.log('It\'s Superman!');
foundSuperman = true;
} else {
console.log('... No superman!');
}
});
return foundSuperman;
}
我为我们的findSuperman()
函数添加了一个返回值。 如果找到超人,它将返回true。 否则,它将返回false。 由使用此模块的代码决定使用此true / false值的代码。 但是,上面的模块中缺少一件事。 我们在函数中使用Underscore,但尚未声明。 我们可以在模块本身以及顶部声明它,如下所示:
var _ = require('underscore');
module.exports = function (values) {
...
使用Browserify时,它将浏览所有导入的JS文件,并且只会导入一次提到的每个模块。 因此,我们在主JS文件中需要下划线,在findsuperman.js
也需要下划线,但是当Browserify将所有文件打包时,只将其放入最终的JS文件中一次。 很整洁吧?
现在,我们实际JavaScript应用将使用带有新返回的true / false值的新模块。 出于演示目的,我们将坚持使用一个简单的document.write
来说明它是否从我们的名字中找到了超人:
var _ = require('underscore'),
names = require('./names.js'),
findSuperman = require('./findsuperman.js');
if (findSuperman(names())) {
document.write('We found Superman');
} else {
document.write('No Superman...');
}
我们甚至不需要在我们的主要JS文件中导入Underscore,因此您可以删除它而没有任何麻烦。 最后,它仍会通过包含在findsuperman.js
文件中而findsuperman.js
。
使用package.json
管理Browserify的npm依赖关系
假设您有一位热心的朋友,他也想使用您的代码。 期望他们知道他们需要首先安装npm underscore模块会有些困难。 解决方案是在项目的根目录中创建一个名为package.json
的文件。 该文件为您的项目提供一个名称(确保名称中没有空格),描述,作者,版本,最重要的是,在我们的案例中是npm依赖项列表。 对于那些使用node开发的人,我们在这里使用完全相同的东西:
{
"name": "FindSuperman",
"version": "0.0.1",
"author": "Patrick Catanzariti",
"description": "Code designed to find the elusive red blue blur",
"dependencies": {
"underscore": "1.6.x"
},
"devDependencies": {
"browserify": "latest"
}
}
目前,依赖项列表仅限于我们的单个"underscore": "1.6.x"
,其中依赖项的第一部分是名称,第二部分是版本。 latest
或*
将检索npm的最新版本。 另外,您可以输入数字,例如1.6
(对于1.6版)和1.6.x
(对于1.6.0之前的版本,但不包括1.7)。
我们还可以将browserify本身作为依赖项包括在内,但它不是项目运行的依赖项–我们应用程序的任何用户都可以找到超人而无需运行Browserify。 这是我们的devDependencies
-开发人员对该应用程序进行更新所需的模块。
现在我们有了一个package.json
文件,我们不需要让我们的朋友来运行npm install underscore
。 他们只需运行npm install
,所有必要的依赖项都将安装到他们的node_modules
文件夹中。
自动化Browserify流程
每次更改文件时,在命令行中运行browserify
都很烦人,而且一点也不方便。 幸运的是,有一些选项可以自动运行Browserify。
npm
npm本身能够运行命令行脚本,就像您手动输入的脚本一样。 为此,只需将scripts
部分放入package.json
如下所示:
"scripts": {
"build-js": "browserify js/main.js > js/findem.js"
}
要运行该程序,可以在命令行中键入以下内容:
npm run build-js
但这还不够方便。 我们仍然需要每次手动运行该命令。 真烦人 因此,更好的选择是使用名为watchify的npm模块。 Watchify很简单,很容易,而且可以节省大量时间。 它会监视您的JS的更改并自动重新运行Browserify。
要将其放入我们的package.json
,我们将其添加到devDependencies
并包括一个用于观看我们的JS的新脚本(有时,当我们确实希望构建我们的JS而无需更改文件时,将build-js
devDependencies
)。
"devDependencies": {
"browserify": "latest",
"watchify": "latest"
},
"scripts": {
"build-js": "browserify js/main.js > js/findem.js",
"watch-js": "watchify js/main.js -o js/findem.js"
}
要运行此命令,只需键入以下命令。
npm run watch-js
它将运行并发挥其魔力。 告诉您发生了什么事并没有说太多,这可能会造成混淆。 如果您希望它为您提供操作的详细信息,请在监视命令中添加-v
,如下所示:
"watch-js": "watchify js/main.js -o js/findem.js -v"
每次运行时,都会给您这样的反馈:
121104 bytes written to js/findem.js (0.26 seconds)
121119 bytes written to js/findem.js (0.03 seconds)
在npm中生成源地图
要使用NPM,添加生成源地图-d
你的后browserify
或watchify
命令:
"scripts": {
"build-js": "browserify js/main.js > js/findem.js -d",
"watch-js": "watchify js/main.js -o js/findem.js -d"
}
要在watchify
同时使用-d
进行调试和-v
进行详细输出,可以像这样组合它们:
"watch-js": "watchify js/main.js -o js/findem.js -dv"
咕unt声
许多人(包括我自己)已经使用Grunt一段时间了,并且已经习惯了。 幸运的是,对于这些种类,Browserify也可以很好地与Grunt版本一起玩!
为了使用grunt,我们需要更改package.json
文件。 我们将不再使用scripts
部分,而将依赖于Grunt。 相反,我们将添加一些新的devDependencies
:
{
"name": "FindSuperman",
"version": "0.0.1",
"author": "Patrick Catanzariti",
"description": "Code designed to find the elusive red blue blur",
"dependencies": {
"underscore": "1.6.x"
},
"devDependencies": {
"browserify": "latest",
"grunt": "~0.4.0",
"grunt-browserify": "latest",
"grunt-contrib-watch": "latest"
}
}
我们已经添加了依赖项:
- grunt –确保我们已为该项目安装了Grunt。
- grunt-browserify –该模块可让您在Grunt中运行Browserify。
- grunt-contrib-watch –该模块将在文件发生更改时监视我们的文件并运行Browserify。
然后,在项目的根目录中创建一个名为gruntFile.js
的文件。 在此Grunt文件中,我们将具有以下内容:
module.exports = function(grunt) {
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-browserify');
grunt.registerTask('default', ['browserify', 'watch']);
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
browserify: {
main: {
src: 'js/main.js',
dest: 'js/findem.js'
}
},
watch: {
files: 'js/*',
tasks: ['default']
}
});
}
我们通过在package.json
文件中加载所需的npm模块来启动Grunt文件:
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-browserify');
我们将要运行的唯一一组任务注册为default
任务( browserify
和watch
):
grunt.registerTask('default', ['browserify', 'watch']);
我们设置了Grunt initConfig
对象(所有Grunt文件都为此寻找):
grunt.initConfig({
在其中,我们指出package.json
文件在哪里:
pkg: grunt.file.readJSON('package.json'),
接下来是Browserify设置,它们基本上是通过我们的Browserized代码以及我们希望构建的文件来设置源JS文件所在的位置:
browserify: {
main: {
src: 'js/main.js',
dest: 'js/findem.js'
}
},
然后,我们设置了一个watch
任务,以便在js
文件夹中的任何更改时都重新运行Browserify任务:
watch: {
files: 'js/*',
tasks: ['default']
}
由于我们新的devDependencies
(我们的项目中未安装Grunt,也没有任何模块),因此我们需要先进行npm install
。 一旦允许它运行并安装任何模块,您就可以运行非常简单的grunt
命令来使其开始监视您的项目。
在Grunt中生成源地图
随着版本2.0.1的grunt-browserify
更改,需要定义源映射的方式已更改,从而导致许多在线指南不正确! 使Grunt和Browserify为您生成源地图的正确方法是在bundleOptions
内的options
添加debug: true
如下所示:
browserify: {
main: {
options: {
bundleOptions: {
debug: true
}
},
src: 'js/main.js',
dest: 'js/findem.js'
}
},
设置这些看起来很复杂的选项的目的是允许以一种很好且易于兼容的方式包含将来的Browserify选项。
古尔普
Gulp是Browserify的小报爱好者。 网络上的文章经常将Browserify和Gulp两者结合在一起,这是天堂中最先进JavaScript构建过程。 我不会说Browserify粉丝需要使用Gulp,这主要是不同语法之间的个人偏好。 您可以(如上所述)很高兴地使用npm或Grunt来构建Browserify文件。 我个人非常喜欢用于小型项目的干净,简单的npm构建过程。
为了在Gulp中完成上述操作,我们将从全局安装Gulp开始:
npm install -g gulp
我们将更新package.json
文件,使其包含一些我们需要的新devDependencies
:
"devDependencies": {
"browserify": "latest",
"watchify": "latest",
"gulp": "3.7.0",
"vinyl-source-stream": "latest"
}
我们添加了以下内容:
- watchify –我们也在npm示例中使用了此功能。 相同的模块。
- gulp –一个非常重要的模块,可以为我们提供所有的Gulp优点!
- Vinyl-Source-Stream –此模块将接受输入并返回文件供我们放置。
Browserify具有用于其输出的流API,我们可以在Gulp中直接使用它。 大量指南会建议您使用gulp gulp-browserify
browserify插件,但是Browserify不推荐这样做,而是更喜欢我们使用Browserify的流API输出。 我们使用vinyl-source-stream
来获取Browserify的输出并将其放置到文件中以供我们输出。
然后,在项目的根目录中创建一个名为gulpfile.js
的文件。 这是所有Gulp功能的去向:
var browserify = require('browserify'),
watchify = require('watchify'),
gulp = require('gulp'),
source = require('vinyl-source-stream'),
sourceFile = './js/main.js',
destFolder = './js/',
destFile = 'findem.js';
gulp.task('browserify', function() {
return browserify(sourceFile)
.bundle()
.pipe(source(destFile))
.pipe(gulp.dest(destFolder));
});
gulp.task('watch', function() {
var bundler = watchify(sourceFile);
bundler.on('update', rebundle);
function rebundle() {
return bundler.bundle()
.pipe(source(destFile))
.pipe(gulp.dest(destFolder));
}
return rebundle();
});
gulp.task('default', ['browserify', 'watch']);
我们从导入npm模块开始,这很容易解释。 然后,我们为构建设置三个变量:
-
sourceFile
–浏览器化文件的位置和文件名(在本例中为js/main.js
) -
destFolder
–我们要将最终文件输出到的文件夹位置 -
destFile
–我们希望最终文件具有的文件名
我将在下面更详细地说明代码。
Browserify和Gulp如何协同工作
我们的第一个任务是我们定义的browserify
,如下所示:
gulp.task('browserify', function() {
它首先将我们的main.js
文件传递到Browserify npm模块中:
return browserify(sourceFile)
然后,我们使用Browserify流API来返回具有JavaScript内容的可读流:
.bundle()
从那里,我们将其通过管道传递到文件findem.js
的文件中,然后通过管道将其传递到Gulp以放入我们的js
文件夹。
.pipe(source(destFile))
.pipe(gulp.dest(destFolder));
基本上,我们将在各个阶段进行输入,最后进入最终项目,该项目应该是一个闪亮的新JavaScript文件!
将Watchify和Gulp相结合
如前所述,直接使用Browserify有点烦人,因为更新文件时让它自动运行要容易得多。 为此,我们再次使用watchify
npm模块。
我们首先设置一个名为watch
的任务(如果需要,您可以将其watchify
……这实际上取决于您):
gulp.task('watch', function() {
我们将watchify模块分配给bundler
变量,因为它将使用两次:
var bundler = watchify(sourceFile);
然后,我们添加一个事件处理程序,该事件处理程序在rebundle()
调用update
事件时都会运行一个名为rebundle()
的函数。 基本上,每当watchify看到文件更改时,它将运行rebundle()
:
bundler.on('update', rebundle);
那么rebundle()
什么? 这几乎就是我们的browserify
任务在上面所做的:
function rebundle() {
return bundler.bundle()
.pipe(source(destFile))
.pipe(gulp.dest(destFolder));
}
return rebundle();
});
这将会有可能合并这两个browserify
和watchify
在一些敏锐JavaScript优化在一起,但我还是决定分开让他们在这篇文章中让事情变得简单。 有关此示例的令人印象深刻且更复杂的示例,请查看Dan Tello的入门版Gulp文件 。
为了完成gulpfile.js
,我们定义了默认任务,其工作方式与grunt中的默认任务相同。
gulp.task('default', ['browserify', 'watch']);
要运行上面的Gulp代码,您有三个选择。 最简单的方法是运行您执行的默认任务,该任务只需在命令行上输入一个单词即可:
gulp
这将运行一次browserify
任务,并且watch
任务将开始监视文件中的任何更改。
您还可以专门运行您的browserify
任务:
gulp browserify
或您的watch
任务:
gulp watch
使用Gulp和Browserify生成源地图
要为您JavaScript生成源映射,请在两个bundle()
函数中都包含{debug:true}
。
我们的browserify
任务如下所示:
gulp.task('browserify', function() {
return browserify(sourceFile)
.bundle({debug:true})
.pipe(source(destFile))
.pipe(gulp.dest(destFolder));
});
我们的watch
任务中的rebundle()
函数如下所示:
function rebundle() {
return bundler.bundle({debug:true})
.pipe(source(destFile))
.pipe(gulp.dest(destFolder));
}
结论
对于Browserify来说还处于初期,随着时间的推移,它肯定会发展和成熟。 在当前状态下,它已经是用于构造模块化JavaScript的非常方便的工具,对于在后端使用Node的用户而言,它尤其出色。 在项目的前端和后端都使用npm模块时,代码对于Node开发人员而言变得更加干净。 如果您没有给Browserify拍照,请在您的下一个JavaScript项目中尝试一下,看看它是否能打动您的世界。
其他资源
那里还有大量的其他Browserify资源。 您可能需要检查的一些方便零碎的地方:
- Browserify手册 – James Halliday关于Browserify入门的非常有价值的手册。 绝对值得一读!
- Gulp + Browserify:Dan Tello撰写的所有内容 -内容详尽的文章,显示了更高级的用法。
- 就像出现了Grunt和RequireJS一样,现在都只涉及Gulp和Browserify了 -Martin Genev举例说明了他突然转换为Browserify和Gulp的过程。
- Gulp.js简介 – Craig Buckler 撰写的有关如何使用Gulp的更多信息。
browserify