0% found this document useful (0 votes)
7 views

JavaScript Frameworks for Modern Web Dev 1st Edition Tim Ambler Nicholas Cloud download

The document is a promotional material for various eBooks related to JavaScript frameworks and web development. It includes links to download titles such as 'JavaScript Frameworks for Modern Web Dev' and other related works. Additionally, it provides information about the authors and the structure of the content within the books.

Uploaded by

pocztafante
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
7 views

JavaScript Frameworks for Modern Web Dev 1st Edition Tim Ambler Nicholas Cloud download

The document is a promotional material for various eBooks related to JavaScript frameworks and web development. It includes links to download titles such as 'JavaScript Frameworks for Modern Web Dev' and other related works. Additionally, it provides information about the authors and the structure of the content within the books.

Uploaded by

pocztafante
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 70

JavaScript Frameworks for Modern Web Dev 1st

Edition Tim Ambler Nicholas Cloud install


download

https://ebookmeta.com/product/javascript-frameworks-for-modern-
web-dev-1st-edition-tim-ambler-nicholas-cloud/

Download more ebook from https://ebookmeta.com


We believe these products will be a great fit for you. Click
the link to download now, or visit ebookmeta.com
to discover even more!

JavaScript Frameworks for Modern Web Development, 2nd


Edition Sufyan Bin Uzayr

https://ebookmeta.com/product/javascript-frameworks-for-modern-
web-development-2nd-edition-sufyan-bin-uzayr/

Building Web Applications with .NET Core 2.1 and


JavaScript: Leveraging Modern JavaScript Frameworks -
Second Edition Philip Japikse

https://ebookmeta.com/product/building-web-applications-with-net-
core-2-1-and-javascript-leveraging-modern-javascript-frameworks-
second-edition-philip-japikse/

Building Web Applications with Visual Studio 2017:


Using .NET Core and Modern JavaScript Frameworks 1st
Edition Philip Japikse

https://ebookmeta.com/product/building-web-applications-with-
visual-studio-2017-using-net-core-and-modern-javascript-
frameworks-1st-edition-philip-japikse/

Chicana o Studies Survey and Analysis 4th Edition


Dennis J Bixler Marquez Carlos F Ortega

https://ebookmeta.com/product/chicana-o-studies-survey-and-
analysis-4th-edition-dennis-j-bixler-marquez-carlos-f-ortega/
Visualizing with Text 1st Edition Richard Brath

https://ebookmeta.com/product/visualizing-with-text-1st-edition-
richard-brath/

Tableau Desktop Cookbook Quick Simple Recipes to Help


You Navigate Tableau Desktop 1st Edition Lorna Brown

https://ebookmeta.com/product/tableau-desktop-cookbook-quick-
simple-recipes-to-help-you-navigate-tableau-desktop-1st-edition-
lorna-brown/

Dad Bod Bodyguard Dad Bod Men Built for Comfort 16 1st
Edition Penn Rivers

https://ebookmeta.com/product/dad-bod-bodyguard-dad-bod-men-
built-for-comfort-16-1st-edition-penn-rivers/

Fallen Giants The Combat Debut of the T 35A Tank 1st


Edition Pulham

https://ebookmeta.com/product/fallen-giants-the-combat-debut-of-
the-t-35a-tank-1st-edition-pulham/

Studying English Literature in Context Critical


Readings Paul Poplawski

https://ebookmeta.com/product/studying-english-literature-in-
context-critical-readings-paul-poplawski/
Galaxy Watercolor : Paint the Universe with 30 Awe-
Inspiring Projects 1st Edition Sosha Davis

https://ebookmeta.com/product/galaxy-watercolor-paint-the-
universe-with-30-awe-inspiring-projects-1st-edition-sosha-davis/
I
Fa Ma Kn Re Grun nclu
ye ch oc q t, de
, Q , ko uir Ye s B
, A Mo ut eJ om o
sy ng , A S,B a we
nc o ng ro n, r,
.js ose ul w PM
, U , ar se 2
nd K n JS, rif ,
er ex, Kr y,
sco B ak
re, ook en
an she ,
d L lf,
od
as
h

www.it-ebooks.info
JavaScript Frameworks
for Modern Web Dev

Tim Ambler
Nicholas Cloud

www.it-ebooks.info
JavaScript Frameworks for Modern Web Dev
Copyright © 2015 by Tim Ambler and Nicholas Cloud
This work is subject to copyright. All rights are reserved by the Publisher, whether the whole or part of the
material is concerned, specifically the rights of translation, reprinting, reuse of illustrations, recitation,
broadcasting, reproduction on microfilms or in any other physical way, and transmission or information
storage and retrieval, electronic adaptation, computer software, or by similar or dissimilar methodology now
known or hereafter developed. Exempted from this legal reservation are brief excerpts in connection with
reviews or scholarly analysis or material supplied specifically for the purpose of being entered and executed
on a computer system, for exclusive use by the purchaser of the work. Duplication of this publication or
parts thereof is permitted only under the provisions of the Copyright Law of the Publisher’s location, in its
current version, and permission for use must always be obtained from Springer. Permissions for use may be
obtained through RightsLink at the Copyright Clearance Center. Violations are liable to prosecution under
the respective Copyright Law.
ISBN-13 (pbk): 978-1-4842-0663-8
ISBN-13 (electronic): 978-1-4842-0662-1
Trademarked names, logos, and images may appear in this book. Rather than use a trademark symbol
with every occurrence of a trademarked name, logo, or image we use the names, logos, and images only
in an editorial fashion and to the benefit of the trademark owner, with no intention of infringement of the
trademark.
The use in this publication of trade names, trademarks, service marks, and similar terms, even if they are
not identified as such, is not to be taken as an expression of opinion as to whether or not they are subject to
proprietary rights.
While the advice and information in this book are believed to be true and accurate at the date of publication,
neither the authors nor the editors nor the publisher can accept any legal responsibility for any errors or
omissions that may be made. The publisher makes no warranty, express or implied, with respect to the
material contained herein.
Managing Director: Welmoed Spahr
Lead Editor: Louise Corrigan
Technical Reviewer: Robin Hawkes
Editorial Board: Steve Anglin, Mark Beckner, Gary Cornell, Louise Corrigan, James DeWolf,
Jonathan Gennick, Robert Hutchinson, Michelle Lowman, James Markham, Matthew Moodie,
Jeffrey Pepper, Douglas Pundick, Ben Renow-Clarke, Gwenan Spearing, Matt Wade, Steve Weiss
Coordinating Editor: Kevin Walter
Copy Editor: Bill McManus
Compositor: SPi Global
Indexer: SPi Global
Artist: SPi Global
Cover Designer: Crest
Distributed to the book trade worldwide by Springer Science+Business Media New York,
233 Spring Street, 6th Floor, New York, NY 10013. Phone 1-800-SPRINGER, fax (201) 348-4505, e-mail
[email protected], or visit www.springeronline.com. Apress Media, LLC is a California LLC
and the sole member (owner) is Springer Science + Business Media Finance Inc (SSBM Finance Inc).
SSBM Finance Inc is a Delaware corporation.
For information on translations, please e-mail [email protected], or visit www.apress.com.
Apress and friends of ED books may be purchased in bulk for academic, corporate, or promotional use.
eBook versions and licenses are also available for most titles. For more information, reference our Special
Bulk Sales–eBook Licensing web page at www.apress.com/bulk-sales.
Any source code or other supplementary material referenced by the author in this text is available to
readers at www.apress.com/. For detailed information about how to locate your book’s source code, go to
www.apress.com/source-code/.

www.it-ebooks.info
There was a young lady named Laura,
Who was a beautiful señora.
Her love and assurance
Was a frequent occurrence
Which allowed me to write this book for yah.
—Tim

Dedicated to Brittany who supported me and gave me space


during the long hours that writing demands.
—Nicholas

www.it-ebooks.info
Contents at a Glance

About the Authors���������������������������������������������������������������������������������������������������xix


About the Technical Reviewer��������������������������������������������������������������������������������xxi
Acknowledgments������������������������������������������������������������������������������������������������xxiii
Introduction�����������������������������������������������������������������������������������������������������������xxv


■Chapter 1: Bower��������������������������������������������������������������������������������������������������� 1

■Chapter 2: Grunt�������������������������������������������������������������������������������������������������� 11

■Chapter 3: Yeoman���������������������������������������������������������������������������������������������� 37

■Chapter 4: PM2���������������������������������������������������������������������������������������������������� 53

■Chapter 5: RequireJS������������������������������������������������������������������������������������������� 73

■Chapter 6: Browserify���������������������������������������������������������������������������������������� 101

■Chapter 7: Knockout������������������������������������������������������������������������������������������ 121

■Chapter 8: AngularJS���������������������������������������������������������������������������������������� 155

■Chapter 9: Kraken���������������������������������������������������������������������������������������������� 191

■Chapter 10: Mach���������������������������������������������������������������������������������������������� 251

■Chapter 11: Mongoose��������������������������������������������������������������������������������������� 297

■Chapter 12: Knex and Bookshelf����������������������������������������������������������������������� 345

■Chapter 13: Faye������������������������������������������������������������������������������������������������ 381

www.it-ebooks.info
■ Contents at a Glance


■Chapter 14: Q����������������������������������������������������������������������������������������������������� 395

■Chapter 15: Async.js����������������������������������������������������������������������������������������� 425

■Chapter 16: Underscore and Lodash����������������������������������������������������������������� 447

Index��������������������������������������������������������������������������������������������������������������������� 477

vi

www.it-ebooks.info
Contents

About the Authors���������������������������������������������������������������������������������������������������xix


About the Technical Reviewer��������������������������������������������������������������������������������xxi
Acknowledgments������������������������������������������������������������������������������������������������xxiii
Introduction�����������������������������������������������������������������������������������������������������������xxv


■Chapter 1: Bower��������������������������������������������������������������������������������������������������� 1
Getting Started����������������������������������������������������������������������������������������������������������������� 2
Configuring Bower������������������������������������������������������������������������������������������������������������ 2
The Manifest�������������������������������������������������������������������������������������������������������������������� 2
Creating a New Manifest������������������������������������������������������������������������������������������������������������������������ 3

Finding, Adding, and Removing Bower Packages������������������������������������������������������������ 3


Finding Packages����������������������������������������������������������������������������������������������������������������������������������� 3
Adding Packages������������������������������������������������������������������������������������������������������������������������������������ 4
Removing Packages������������������������������������������������������������������������������������������������������������������������������� 5

Semantic Versioning��������������������������������������������������������������������������������������������������������� 6
Managing the Dependency Chain������������������������������������������������������������������������������������� 7
Creating Bower Packages������������������������������������������������������������������������������������������������ 8
Choose a Valid Name������������������������������������������������������������������������������������������������������������������������������ 8
Use Semver Git Tags������������������������������������������������������������������������������������������������������������������������������� 8
Publish Your Package to the Registry����������������������������������������������������������������������������������������������������� 9

Summary�������������������������������������������������������������������������������������������������������������������������� 9

vii

www.it-ebooks.info
■ Contents


■Chapter 2: Grunt�������������������������������������������������������������������������������������������������� 11
Installing Grunt��������������������������������������������������������������������������������������������������������������� 12
How Grunt Works������������������������������������������������������������������������������������������������������������ 12
Gruntfile.js�������������������������������������������������������������������������������������������������������������������������������������������� 12
Tasks���������������������������������������������������������������������������������������������������������������������������������������������������� 14
Plugins�������������������������������������������������������������������������������������������������������������������������������������������������� 14
Configuration���������������������������������������������������������������������������������������������������������������������������������������� 15

Adding Grunt to Your Project������������������������������������������������������������������������������������������ 15


Maintaining a Sane Grunt Structure����������������������������������������������������������������������������������������������������� 15

Working with Tasks�������������������������������������������������������������������������������������������������������� 18


Managing Configuration����������������������������������������������������������������������������������������������������������������������� 18
Task Descriptions��������������������������������������������������������������������������������������������������������������������������������� 18
Asynchronous Tasks����������������������������������������������������������������������������������������������������������������������������� 19
Task Dependencies������������������������������������������������������������������������������������������������������������������������������� 20
Multi-Tasks������������������������������������������������������������������������������������������������������������������������������������������� 20
Multi-Task Options�������������������������������������������������������������������������������������������������������������������������������� 22
Configuration Templates����������������������������������������������������������������������������������������������������������������������� 23
Command-Line Options������������������������������������������������������������������������������������������������������������������������ 24
Providing Feedback������������������������������������������������������������������������������������������������������������������������������ 24
Handling Errors������������������������������������������������������������������������������������������������������������������������������������� 25

Interacting with the File System������������������������������������������������������������������������������������ 25


Source-Destination Mappings�������������������������������������������������������������������������������������������������������������� 26
Watching for File Changes�������������������������������������������������������������������������������������������������������������������� 28

Creating Plugins������������������������������������������������������������������������������������������������������������� 32
Getting Started������������������������������������������������������������������������������������������������������������������������������������� 32
Creating the Task���������������������������������������������������������������������������������������������������������������������������������� 32
Publishing to npm��������������������������������������������������������������������������������������������������������������������������������� 35

Summary������������������������������������������������������������������������������������������������������������������������ 36
Related Resources��������������������������������������������������������������������������������������������������������� 36

viii

www.it-ebooks.info
■ Contents


■Chapter 3: Yeoman���������������������������������������������������������������������������������������������� 37
Installing Yeoman����������������������������������������������������������������������������������������������������������� 38
Creating Your First Project���������������������������������������������������������������������������������������������� 38
Subcommands�������������������������������������������������������������������������������������������������������������������������������������� 41

Creating Your First Generator����������������������������������������������������������������������������������������� 42


Yeoman Generators are Node Modules������������������������������������������������������������������������������������������������ 42
Sub-Generators������������������������������������������������������������������������������������������������������������������������������������ 43
Defining Secondary Commands����������������������������������������������������������������������������������������������������������� 49
Composability��������������������������������������������������������������������������������������������������������������������������������������� 51

Summary������������������������������������������������������������������������������������������������������������������������ 52
Related Resources��������������������������������������������������������������������������������������������������������� 52

■Chapter 4: PM2���������������������������������������������������������������������������������������������������� 53
Installation���������������������������������������������������������������������������������������������������������������������� 53
Working with Processes������������������������������������������������������������������������������������������������� 54
Recovering from Errors������������������������������������������������������������������������������������������������������������������������ 56
Responding to File Changes����������������������������������������������������������������������������������������������������������������� 58

Monitoring Logs������������������������������������������������������������������������������������������������������������� 58
Monitoring Resource Usage������������������������������������������������������������������������������������������� 60
Monitoring Local Resources����������������������������������������������������������������������������������������������������������������� 60
Monitoring Remote Resources������������������������������������������������������������������������������������������������������������� 61
Advanced Process Management������������������������������������������������������������������������������������ 63
JSON Application Declarations������������������������������������������������������������������������������������������������������������� 63

Load-Balancing Across Multiple Processors������������������������������������������������������������������ 68


Zero-Downtime Deployments��������������������������������������������������������������������������������������������������������������� 70

Summary������������������������������������������������������������������������������������������������������������������������ 72
Related Resources��������������������������������������������������������������������������������������������������������� 72

ix

www.it-ebooks.info
■ Contents


■Chapter 5: RequireJS������������������������������������������������������������������������������������������� 73
Running the Examples���������������������������������������������������������������������������������������������������� 74
Working with RequireJS������������������������������������������������������������������������������������������������� 74
Installation�������������������������������������������������������������������������������������������������������������������������������������������� 75
Configuration���������������������������������������������������������������������������������������������������������������������������������������� 75
Application Modules and Dependencies����������������������������������������������������������������������������������������������� 78
Paths and Aliases��������������������������������������������������������������������������������������������������������������������������������� 81
Shims���������������������������������������������������������������������������������������������������������������������������������������������������� 84
Loader Plugins�������������������������������������������������������������������������������������������������������������������������������������� 88
Cache Busting��������������������������������������������������������������������������������������������������������������������������������������� 94

RequireJS Optimizer������������������������������������������������������������������������������������������������������� 96
Configuring r.js������������������������������������������������������������������������������������������������������������������������������������� 96
Running the r.js Command������������������������������������������������������������������������������������������������������������������� 97

Summary������������������������������������������������������������������������������������������������������������������������ 99

■Chapter 6: Browserify���������������������������������������������������������������������������������������� 101
The AMD API vs. CommonJS���������������������������������������������������������������������������������������� 102
Installing Browserify���������������������������������������������������������������������������������������������������� 102
Creating Your First Bundle�������������������������������������������������������������������������������������������� 103
Visualizing the Dependency Tree���������������������������������������������������������������������������������� 104
Creating New Bundles As Changes Occur�������������������������������������������������������������������� 105
Watching for File Changes with Grunt������������������������������������������������������������������������������������������������ 106
Watching for File Changes with Watchify������������������������������������������������������������������������������������������� 106

Using Multiple Bundles������������������������������������������������������������������������������������������������ 108


The Node Way��������������������������������������������������������������������������������������������������������������� 111
Module Resolution and the NODE_PATH Environment Variable���������������������������������������������������������� 111
Dependency Management������������������������������������������������������������������������������������������������������������������ 114

Defining Browser-Specific Modules����������������������������������������������������������������������������� 115

www.it-ebooks.info
■ Contents

Extending Browserify with Transforms������������������������������������������������������������������������� 116


brfs����������������������������������������������������������������������������������������������������������������������������������������������������� 116
folderify���������������������������������������������������������������������������������������������������������������������������������������������� 117
bulkify������������������������������������������������������������������������������������������������������������������������������������������������� 118
Browserify-Shim��������������������������������������������������������������������������������������������������������������������������������� 119

Summary���������������������������������������������������������������������������������������������������������������������� 120
Related Resources������������������������������������������������������������������������������������������������������� 120

■Chapter 7: Knockout������������������������������������������������������������������������������������������ 121
Views, Models, and View Models��������������������������������������������������������������������������������� 122
The Recipe List����������������������������������������������������������������������������������������������������������������������������������� 124
Recipe Details������������������������������������������������������������������������������������������������������������������������������������� 127

Binding View Models to the DOM��������������������������������������������������������������������������������� 129


View Models and Forms����������������������������������������������������������������������������������������������� 131
Switching to “Edit” Mode������������������������������������������������������������������������������������������������������������������� 131
Changing the Recipe Title������������������������������������������������������������������������������������������������������������������� 134
Updating Recipe Servings and Cooking Time������������������������������������������������������������������������������������� 135
Adding and Removing Ingredients������������������������������������������������������������������������������������������������������ 138
Instructions����������������������������������������������������������������������������������������������������������������������������������������� 142
Citation����������������������������������������������������������������������������������������������������������������������������������������������� 144

Custom Components���������������������������������������������������������������������������������������������������� 144


The Input List View Model������������������������������������������������������������������������������������������������������������������ 145
The Input List Template���������������������������������������������������������������������������������������������������������������������� 146
Registering the Input List Tag������������������������������������������������������������������������������������������������������������� 148

Subscribables: Cheap Messaging�������������������������������������������������������������������������������� 150


Summary���������������������������������������������������������������������������������������������������������������������� 152
Related Resources������������������������������������������������������������������������������������������������������� 153

xi

www.it-ebooks.info
■ Contents


■Chapter 8: AngularJS���������������������������������������������������������������������������������������� 155
A Declarative Approach to Building Web Applications�������������������������������������������������� 155
The Imperative Approach�������������������������������������������������������������������������������������������������������������������� 155
The Declarative Approach������������������������������������������������������������������������������������������������������������������� 157

Modules: A Foundation for Building Loosely Coupled Applications������������������������������ 158


Specifying a Bootstrap Module����������������������������������������������������������������������������������������������������������� 159

Directives: An Abstraction Layer for the DOM��������������������������������������������������������������� 160


Taking Control�������������������������������������������������������������������������������������������������������������� 163
Scopes and Prototypal Inheritance����������������������������������������������������������������������������������������������������� 163
Manipulating Scope with Controllers������������������������������������������������������������������������������������������������� 165

Loose Coupling Through Services and Dependency Injection�������������������������������������� 168


Dependency Injection������������������������������������������������������������������������������������������������������������������������� 168
Thin Controllers and Fat Services������������������������������������������������������������������������������������������������������� 169

Creating Routes������������������������������������������������������������������������������������������������������������ 173


Route Parameters������������������������������������������������������������������������������������������������������������������������������� 175
Route Resolutions������������������������������������������������������������������������������������������������������������������������������� 176

Creating Complex Forms���������������������������������������������������������������������������������������������� 178


Validation�������������������������������������������������������������������������������������������������������������������������������������������� 178
Conditional Logic�������������������������������������������������������������������������������������������������������������������������������� 183
Repeatable Sections��������������������������������������������������������������������������������������������������������������������������� 185
Summary���������������������������������������������������������������������������������������������������������������������� 188
Related Resources������������������������������������������������������������������������������������������������������� 189

■Chapter 9: Kraken���������������������������������������������������������������������������������������������� 191
Environment-Aware Configuration������������������������������������������������������������������������������� 192
Shortstop Handlers����������������������������������������������������������������������������������������������������������������������������� 196

Configuration-Based Middleware Registration������������������������������������������������������������ 200


Event Notifications������������������������������������������������������������������������������������������������������������������������������ 203

xii

www.it-ebooks.info
■ Contents

Structured Route Registration�������������������������������������������������������������������������������������� 203


Index Configuration���������������������������������������������������������������������������������������������������������������������������� 204
Directory Configuration����������������������������������������������������������������������������������������������������������������������� 205
Routes Configuration�������������������������������������������������������������������������������������������������������������������������� 207

Dust Templates������������������������������������������������������������������������������������������������������������� 208


Context and References��������������������������������������������������������������������������������������������������������������������� 209
Sections���������������������������������������������������������������������������������������������������������������������������������������������� 212
Iteration���������������������������������������������������������������������������������������������������������������������������������������������� 212
Conditionality�������������������������������������������������������������������������������������������������������������������������������������� 213
Partials����������������������������������������������������������������������������������������������������������������������������������������������� 214
Blocks������������������������������������������������������������������������������������������������������������������������������������������������� 215
Filters�������������������������������������������������������������������������������������������������������������������������������������������������� 216
Context Helpers���������������������������������������������������������������������������������������������������������������������������������� 218
Dust Helpers��������������������������������������������������������������������������������������������������������������������������������������� 225
Let’s Get Kraken��������������������������������������������������������������������������������������������������������������������������������� 230

Summary���������������������������������������������������������������������������������������������������������������������� 250
Related Resources������������������������������������������������������������������������������������������������������� 250

■Chapter 10: Mach���������������������������������������������������������������������������������������������� 251
Chapter Examples�������������������������������������������������������������������������������������������������������� 251
Installation�������������������������������������������������������������������������������������������������������������������� 252
Mach, the Web Server�������������������������������������������������������������������������������������������������� 252
HTTP Routes��������������������������������������������������������������������������������������������������������������������������������������� 254
Making Connections��������������������������������������������������������������������������������������������������������������������������� 260
Common Middleware�������������������������������������������������������������������������������������������������������������������������� 262
These Are Not the Routes You’re Looking for������������������������������������������������������������������������������������� 280
The Hosts with the Most��������������������������������������������������������������������������������������������������������������������� 282
Custom Middleware���������������������������������������������������������������������������������������������������������������������������� 287

Mach, the HTTP Client�������������������������������������������������������������������������������������������������� 289


Mach, the HTTP Proxy�������������������������������������������������������������������������������������������������� 291
Summary���������������������������������������������������������������������������������������������������������������������� 295

xiii

www.it-ebooks.info
■ Contents


■Chapter 11: Mongoose��������������������������������������������������������������������������������������� 297
Basic MongoDB Concepts�������������������������������������������������������������������������������������������� 297
A Simple Mongoose Example��������������������������������������������������������������������������������������� 300
Creating a Mongoose Schema for JSON Data������������������������������������������������������������������������������������ 301
Importing Data with Mongoose���������������������������������������������������������������������������������������������������������� 302
Querying Data with Mongoose����������������������������������������������������������������������������������������������������������� 305

Working with Schemas������������������������������������������������������������������������������������������������ 307


Data Types������������������������������������������������������������������������������������������������������������������������������������������ 307
Nested Schemas��������������������������������������������������������������������������������������������������������������������������������� 308
Default Property Values���������������������������������������������������������������������������������������������������������������������� 309
Required Properties���������������������������������������������������������������������������������������������������������������������������� 310
Secondary Indexes����������������������������������������������������������������������������������������������������������������������������� 310
Schema Validation������������������������������������������������������������������������������������������������������������������������������ 311
Schema References���������������������������������������������������������������������������������������������������������������������������� 314
Schema Middleware��������������������������������������������������������������������������������������������������������������������������� 318

Working with Models and Documents�������������������������������������������������������������������������� 321


Document Instance Methods�������������������������������������������������������������������������������������������������������������� 323
Document Virtuals������������������������������������������������������������������������������������������������������������������������������ 325
Static Model Methods������������������������������������������������������������������������������������������������������������������������� 327

Working with Queries��������������������������������������������������������������������������������������������������� 329


Model.find( )���������������������������������������������������������������������������������������������������������������������������������������� 329
Finding Documents with Query Operators������������������������������������������������������������������������������������������ 336
Summary���������������������������������������������������������������������������������������������������������������������� 343

■Chapter 12: Knex and Bookshelf����������������������������������������������������������������������� 345
Knex����������������������������������������������������������������������������������������������������������������������������� 346
Installing the Command-Line Utility��������������������������������������������������������������������������������������������������� 346
Adding Knex to Your Project��������������������������������������������������������������������������������������������������������������� 346
Configuring Knex�������������������������������������������������������������������������������������������������������������������������������� 347
The SQL Query Builder������������������������������������������������������������������������������������������������������������������������ 347
Migration Scripts�������������������������������������������������������������������������������������������������������������������������������� 355
Seed Scripts��������������������������������������������������������������������������������������������������������������������������������������� 360
xiv

www.it-ebooks.info
■ Contents

Bookshelf��������������������������������������������������������������������������������������������������������������������� 361
What Is an Object-Relational Mapper?����������������������������������������������������������������������������������������������� 361
Creating Your First Bookshelf Model��������������������������������������������������������������������������������������������������� 362
Relationships�������������������������������������������������������������������������������������������������������������������������������������� 370

Summary���������������������������������������������������������������������������������������������������������������������� 379
Related Resources������������������������������������������������������������������������������������������������������� 379

■Chapter 13: Faye������������������������������������������������������������������������������������������������ 381
HTTP, Bayeux, and WebSockets������������������������������������������������������������������������������������ 381
WebSockets���������������������������������������������������������������������������������������������������������������������������������������� 383
The Bayeux Protocol��������������������������������������������������������������������������������������������������������������������������� 384

Getting Started with Faye��������������������������������������������������������������������������������������������� 385


PubSub Messaging������������������������������������������������������������������������������������������������������� 387
Wildcard Channels������������������������������������������������������������������������������������������������������������������������������ 388

Summary���������������������������������������������������������������������������������������������������������������������� 393
Related Resources������������������������������������������������������������������������������������������������������� 394

■Chapter 14: Q����������������������������������������������������������������������������������������������������� 395
Timing Is Everything����������������������������������������������������������������������������������������������������� 395
Promises vs. Callbacks������������������������������������������������������������������������������������������������ 399
The Promise of Q���������������������������������������������������������������������������������������������������������� 401
Deferreds and Promises��������������������������������������������������������������������������������������������������������������������� 401
Values and Errors������������������������������������������������������������������������������������������������������������������������������� 406
Reporting Progress����������������������������������������������������������������������������������������������������������������������������� 412
Everything Ends���������������������������������������������������������������������������������������������������������������������������������� 415

Flow Control with Q������������������������������������������������������������������������������������������������������ 418


Sequential Flow���������������������������������������������������������������������������������������������������������������������������������� 418
Parallel Flow��������������������������������������������������������������������������������������������������������������������������������������� 420
Pipeline Flow�������������������������������������������������������������������������������������������������������������������������������������� 421

Summary���������������������������������������������������������������������������������������������������������������������� 423
Related Resources������������������������������������������������������������������������������������������������������� 423

xv

www.it-ebooks.info
■ Contents


■Chapter 15: Async.js����������������������������������������������������������������������������������������� 425
Sequential Flow������������������������������������������������������������������������������������������������������������ 426
Parallel Flow����������������������������������������������������������������������������������������������������������������� 428
Pipeline Flow���������������������������������������������������������������������������������������������������������������� 430
Reusing a Pipeline������������������������������������������������������������������������������������������������������������������������������ 433

Loop Flow��������������������������������������������������������������������������������������������������������������������� 435


Looping While Some Condition Remains True������������������������������������������������������������������������������������ 435
Looping Until Some Condition Becomes False����������������������������������������������������������������������������������� 437
Retry Loops����������������������������������������������������������������������������������������������������������������������������������������� 439
Infinite Loops�������������������������������������������������������������������������������������������������������������������������������������� 441

Batch Flow������������������������������������������������������������������������������������������������������������������� 442


Asynchronous Queue�������������������������������������������������������������������������������������������������������������������������� 442

Summary���������������������������������������������������������������������������������������������������������������������� 446

■Chapter 16: Underscore and Lodash����������������������������������������������������������������� 447
Installation and Usage�������������������������������������������������������������������������������������������������� 449
Aggregation and Indexing�������������������������������������������������������������������������������������������� 449
countBy( )�������������������������������������������������������������������������������������������������������������������������������������������� 449
groupBy( )�������������������������������������������������������������������������������������������������������������������������������������������� 451
indexBy( )�������������������������������������������������������������������������������������������������������������������������������������������� 452

Being Choosy���������������������������������������������������������������������������������������������������������������� 453


Selecting Data from Collections��������������������������������������������������������������������������������������������������������� 453
Selecting Data from Objects��������������������������������������������������������������������������������������������������������������� 456

Chaining����������������������������������������������������������������������������������������������������������������������� 460
Function Timing������������������������������������������������������������������������������������������������������������ 463
defer( )������������������������������������������������������������������������������������������������������������������������������������������������ 463
debounce( )����������������������������������������������������������������������������������������������������������������������������������������� 465
throttle( )��������������������������������������������������������������������������������������������������������������������������������������������� 466

xvi

www.it-ebooks.info
■ Contents

Templates��������������������������������������������������������������������������������������������������������������������� 468
Loops and Other Arbitrary JavaScript in Templates���������������������������������������������������������������������������� 470
Living Without Gator Tags������������������������������������������������������������������������������������������������������������������� 472
Accessing the Data Object Within a Template������������������������������������������������������������������������������������ 473
Default Template Data������������������������������������������������������������������������������������������������������������������������ 474

Summary���������������������������������������������������������������������������������������������������������������������� 475
Related Resources������������������������������������������������������������������������������������������������������� 476

Index��������������������������������������������������������������������������������������������������������������������� 477

xvii

www.it-ebooks.info
About the Authors

Tim Ambler is a software engineer from Nashville, Tennessee. His passion


for programming follows in the footsteps of his father, who introduced him
to computers at a young age with a Commodore 64. Tim is the author of
several popular open source projects, one of which (whenLive) has been
featured by GitHub’s staff. An occasional conference speaker and frequent
writer, Tim has been referenced multiple times in online publications such
as JavaScript Weekly and Node Weekly. He currently lives in the 12 South
area with his wife, Laura, and two cats. You can follow him on Twitter at
@tkambler.

Nicholas Cloud is a software developer who lives in the very humid city of
St. Louis. For over a decade he has forged his skills into a successful career.
He has developed web applications, web services, and desktop software on
diverse platforms with JavaScript, C#, and PHP. A strong proponent of open
source software, Nicholas contributes to userland projects and has written
several of his own open source libraries libraries. He speaks at a variety of
user groups and conferences and writes books, technical articles, and blog
posts in his spare time. He opines on Twitter at @nicholascloud.

xix

www.it-ebooks.info
About the Technical Reviewer

Robin Hawkes lives to learn and thrives on combining design and


code to solve problems. He’s the author of Foundation HTML5 Canvas
(Apress, 2011), which is all about making games with JavaScript. He’s
also the one-man band behind ViziCities, a WebGL-powered 3D city
visualization platform. In a previous life Robin worked in worldwide
developer relations at both Mozilla and Pusher.

xxi

www.it-ebooks.info
Acknowledgments

This book would not have been possible without the encouragement and support of a number of people:
Nicholas Cloud, my friend and co-author, without whom this book would be much more limited
in scope and depth. His knowledge, experience, and steadfast dedication to this project have been
immeasurably helpful. Thank you.
Louise Corrigan, Kevin Walter, Christine Ricketts, Melissa Maldonado, and the rest of the staff at Apress
who supported us throughout the course of this project. I am grateful for the invitation that was extended to
embark upon this journey and for the ongoing support that you have provided.
Robin Hawkes, our technical reviewer. The examples and source code included with this book have
greatly benefited from his keen insight and sharp eye.
James Coglan, the creator of Faye. Thank you for taking the time to share your technical expertise
and feedback.
My friends and colleagues Greg Jones, Jeff Crump, Seth Steele, Jon Zumbrun, and Brian Hiatt. I am
grateful for your feedback and encouragement.
—Tim
Acknowledgements are slippery things. I have so many debts, and so little space to repay.
First, the debt to my co-author Tim who reached out and invited me on this journey. We’ve never met
in person but worked remotely as co-workers for about half a year—enough time for each of us to leave an
impression on each other across the miles. For his trust, encouragement, and constant effort I am grateful.
Second, my debt to the staff at Apress who guided us through the publishing process: Kevin, Louise,
Christine, and Melissa. Their patience and careful guidance spared you, the reader, from no small amount of
cringes, and kept me on my toes during the entire writing process. They are all sharp professionals with whom
I hope to work again some day.
Third, I am indebted to Robin for his excellent technical reviews; for reading and executing more code
samples than a developer should ever be tasked with groking.
Finally, I cannot repay the subject-matter expertise I gleaned from Michael Jackson (@mjackson) while
researching Mach, and Ryan Niemeyer (@RPNiemeyer) while researching Knockout—I can only pay it forward
to you, the reader.
—Nicholas

xxiii

www.it-ebooks.info
Introduction

They tell me we’re living in an information age, but none of it seems to be the information
I need or brings me closer to what I want to know. In fact (I’m becoming more and more
convinced) all this electronic wizardry only adds to our confusion, delivering inside scoops
and verdicts about events that have hardly begun: a torrent of chatter moving at the speed
of light, making it nearly impossible for any of the important things to be heard.
—Matthew Flaming, The Kingdom of Ohio

The notion that “technology moves quickly” is a well-worn aphorism, and with good reason: technology
does move quickly. But at this moment, JavaScript in particular is moving very quickly indeed—much like
that “torrent of chatter moving at the speed of light” that Matthew Flaming refers to in The Kingdom of Ohio.
The language is in the midst of what many have called a renaissance, brought about by the rapidly increasing
sophistication of browser-based applications and the rising popularity of JavaScript on the server, thanks to
Node.js.
An almost feverish pace of innovation is occurring within the JavaScript community that, while
endlessly fascinating to follow, also presents some unique challenges of its own. JavaScript’s ecosystem of
libraries, frameworks, and utilities has grown dramatically. Where once a small number of solutions for any
given problem existed, many can now be found… and the options continue to grow by the day. As a result,
developers find themselves faced with the increasingly difficult task of choosing the appropriate tools from
among many seemingly good options.
If you’ve ever found yourself wondering why JavaScript seems to be attracting so much attention lately,
as we have, it’s worth stopping for a moment to consider the fact that JavaScript, a language that was created
by one person in ten days, now serves as the foundation upon which much of the Web as we know it sits.
A language that was originally created to solve relatively simple problems is now being applied in new
and innovative ways that were not originally foreseen. What’s more, JavaScript is a beautifully expressive
language, but it’s not without its share of rough edges and potential pitfalls. While flexible, efficient, and
ubiquitous, JavaScript concepts such as the event loop and prototypal inheritance can prove particularly
challenging for those coming to the language for the first time.
For these and many other reasons, the development community at large is still coming to terms with
how best to apply the unique features that JavaScript brings to the table. We’ve no doubt only scratched
the surface of what the language and the community behind it are capable of. For those with an insatiable
appetite for knowledge and a desire to create, now is the perfect time to be a JavaScript developer.
We have written Pro JavaScript Frameworks for Modern Web Dev to serve as your guide to a wide
range of popular JavaScript tools that solve difficult problems at both ends of the development stack: in
the browser and on the server. The tutorials and downloadable code examples contained within this book
illustrate the usage of tools that manage dependencies, structure code in a modular fashion, automate
repetitive build tasks, create specialized servers, structure client side applications, facilitate horizontal
scaling, perform event logging, and interacting with disparate data stores.
The libraries and frameworks covered include Bower, Grunt, Yeoman, PM2, RequireJS, Browserify,
Knockout, AngularJS, Kraken, Mach, Mongoose, Knex, Bookshelf, Faye, Q, Async.js, Underscore, and Lodash.

xxv

www.it-ebooks.info
■ Introduction

In writing Pro JavaScript Frameworks for Modern Web Dev, our goal was to create a filter for the
“torrent of chatter” that often seems to surround JavaScript, and in so doing, to allow what we believe are
some important things to be heard. We hope the information contained within these pages proves as useful
to you as it has to us.

Who This Book Is For


This book is intended for web developers who are already confident with JavaScript, but also frustrated with
the sheer number of solutions that exist for seemingly every problem. This book helps lift the fog, providing
the reader with an in-depth guide to specific libraries and frameworks that well-known organizations are
using right now with great success. Topics pertaining to both client-side and server-side development
are covered. As a result, readers will gain the most benefit from this book if they already have at least an
intermediate familiarity with both the web browser Document Object Model (DOM), common client-side
libraries like jQuery, and Node.js.

How This Book Is Structured


This book covers a wide selection of JavaScript tools that are applicable throughout the entire development
process, from a project’s first commit to its first release and beyond. To that end, the chapters have been
grouped into the following parts.

Part 1: Development Tools


Bower
Dependency management is hardly a new idea - well-known examples include Node’s npm, Python’s pip,
and PHP’s composer. A practice that has only recently begun to see widespread adoption, however, is the
application of this concept to the management of front-end web assets - the JavaScript libraries, stylesheets,
fonts, icons, and images that serve as the building blocks of modern web applications. In this chapter, we’ll
discover several ways in which Bower - a popular tool within this field - can improve your development
process by providing you with a mechanism for organizing these dependencies within your application.

Grunt
Larry Wall, the creator of Perl, describes the three virtues of a great programmer as: laziness, impatience,
and hubris. In this chapter, we’ll focus on a tool that will help you strengthen the virtue of laziness - Grunt.
This popular task runner provides developers with a framework for creating command-line utilities
that automative repetitive build tasks such as running tests, concatenating files, compiling SASS / LESS
stylesheets, checking for JavaScript errors, and more. After reading this chapter, you’ll know how to use several
popular Grunt plugins, as well as how to go about creating and sharing your own plugins with the community.

xxvi

www.it-ebooks.info
■ Introduction

Yeoman
Yeoman provides JavaScript developers with a mechanism for creating reusable templates (“generators”)
that describe the overall structure of a project (initially required dependencies, Grunt tasks, etc…) in a way
that can be easily re-used over and over. Broad community support also allows you to take advantage of a
wide variety of pre-existing templates. In this chapter, we’ll walk through the process of installing Yeoman
and using several popular pre-existing generators. Finally, we’ll take a look at how we can create and share
our own templates with the community.

PM2
In this chapter, we will close out our discussion of development tools by taking a look at PM2, a command-line
utility that simplifies many of the tasks associated with running Node applications, monitoring their status,
and efficiently scaling them to meet increasing demand.

Part 2: Module Loaders


RequireJS and Browserify
JavaScript’s lacks a native method for loading external dependencies in the browser—a frustrating oversight
for developers. Fortunately, the community has stepped in to fill this gap with two very different and
competing standards: the Asynchronous Module Definition (AMD) API and CommonJS. We’ll dive into the
details of both and take a look at widely-used implementations of each: RequireJS and Browserify. Each
have their merits, which we’ll discuss in detail, but both can have a profoundly positive impact on the way in
which you go about structuring your applications.

Part 3: Client-Side Frameworks


Knockout and AngularJS
In recent years, web developers have witnessed a sharp rise in popularity of so-called “single-page apps.”
Such applications exhibit behavior once available only on the desktop, but at the expense of increased code
complexity within the browser. In this section, we’ll dive into two widely-used front-end frameworks that
help minimize that complexity by providing proven patterns for solving frequently-encountered problems:
Knockout and AngularJS. Knockout focuses on the relationship between view and data, but otherwise leaves
the application architecture and plumbing to the developer’s discretion. AngularJS takes a more prescriptive
approach, covering the view, application routing, data transfer, and module design.

Part 4: Server-Side Frameworks


Kraken and Mach
Client-side applications aren’t very useful without a server with which to interact. In this section, we’ll take
a look at two popular frameworks that support developers in the creation of back-end applications: Kraken
and Mach.
Mach is more than just a simple web server: it is HTTP for the web. Mach can both serve and retrieve
content via an intuitive, extensible HTTP stack. The Mach interface remains the same whether servicing
web page requests in a Node.js application, fetching JSON data with a Mach AJAX request in the browser,
or rewriting and proxying requests to another web stack entirely. In many ways Mach is the Swiss army knife
of HTTP.

xxvii

www.it-ebooks.info
■ Introduction

Part 5: Managing Database Interaction


Mongoose, Knex, and Bookshelf
At the core of every application lies the most important component of any development stack - the data
that our users seek. In this section, we’ll become familiar with two libraries that help simplify some of the
complexity that’s often experienced when interacting with popular storage platforms such as MongoDB,
MySQL, PostgreSQL, and SQLite. After reading this section, you’ll be comfortable defining schemas,
associations, lifecycle “hooks”, and more.

Part 6: Communication
Faye
In this section, you’ll be introduced to Faye, a Node.js library that provides developers with a robust and
easy-to-use platform for building products that rely on real-time communication between servers and all
major browsers.Much of Faye’s popularity stems from the project’s goal of working everywhere the Web
works. Faye accomplishes this by providing seamless fallback support for a number of communication
protocols.

Part 7: Managing Control Flow


Q and Async.js
The asynchronous nature of JavaScript provides developers with a significant degree of flexibility - as
opposed to forcing developers to execute their code in a linear fashion, JavaScript allows developers to
orchestrate multiple actions simultaneously. Unfortunately, along with this flexibility comes a significant
degree of additional complexity - what many developers refer to as “callback hell” or the “pyramid of
doom.” In this section, we’ll examine two popular libraries that will aid you in taming the complexities of
asynchronous control flow: Q and Async.js.

Part 8: Further Useful Libraries


A number of wonderfully useful libraries exist that this book would be remiss not to cover, but for which
additional parts are not necessarily warranted. This part will cover such libraries.

Underscore and Lo-Dash


Underscore (and its successor, Lo-Dash) is an incredibly useful collection of functions that simplifies many
frequently used patterns that can be tedious to implement otherwise. This brief chapter will bring these
libraries to your attention, along with some of the more popular extensions that can also be included to
enhance their usefulness even further. Examples are included that that highlight some of the most frequently
used portions of these libraries.

xxviii

www.it-ebooks.info
■ Introduction

Downloading the Code


Each chapter in this book contains many examples, the source code for which may be downloaded from
http://www.apress.com/9781484206638 in zipped form.
Subdirectories within each chapter’s zip file contain source code (often executable) that corresponds
to specific example listings in each chapter. The first line in each chapter listing will be a source code
comment identifying the specific file path where the source code lives. If you were to encounter
Listing 0-1 in Chapter 10 (covering Mach), for example, the actual source code file would be located in
mach/example-000/no-such-file.js, relative to where the mach.zip file was extracted.

Listing 0-1. Not a Real Example


// example-000/no-such-file.js
console.log('this is not a real example');

Most examples are run with the Node.js runtime, which may be obtained from https://nodejs.org.
Chapters with additional prerequisites will explain the necessary procedures for downloading and
installing the examples. (For example, MongoDB is necessary to run examples in Chapter 11, which covers
Mongoose.)
Any additional steps necessary for running code examples (e.g., executing curl requests) or interacting
with a running example (e.g., opening a web browser and navigating to a specific URL) are explained
alongside each listing.

xxix

www.it-ebooks.info
Chapter 1

Bower

Great things are done by a series of small things brought together.


—Vincent Van Gogh

The concept of package management, also known as dependency management, is not new. Utilities within
this category provide developers with a mechanism for managing the various third-party libraries that a
project relies on. Widely used examples include
• npm: The package manager for Node.js
• Composer: A tool for dependency management in PHP
• pip: The PyPA recommended tool for installing Python packages
• NuGet: The package manager for the Microsoft development platform including .NET
While package management is hardly a new idea, a practice that has only recently begun to see
widespread adoption is the application of this concept to the management of front-end web assets—the
JavaScript libraries, stylesheets, fonts, icons, and images that serve as the building blocks of modern web
applications. The need for such structure has become evident as the foundations on which modern web
applications are built have grown in complexity. Web applications that once relied on a small selection of
broadly defined, “one size fits all” third-party libraries (e.g., jQuery) now find themselves using the work
of many more smaller libraries, each with a tightly defined purpose. Benefits of this approach include
smaller modules that are easier to test, as well as an enhanced degree of flexibility on the part of the
parent application, which can more easily extend third-party libraries or replace them altogether when
necessary.
This chapter is designed to get you up and running quickly with Bower, the front-end package manager
whose roots lie in open source initiatives at Twitter. Topics covered include
• Installing and configuring Bower
• Adding Bower to a project
• Finding, adding, and removing packages
• Semantic Versioning
• Managing the dependency chain
• Creating Bower packages

www.it-ebooks.info
Chapter 1 ■ Bower

Getting Started
All interaction with Bower occurs through a command-line utility that can be installed via npm. If you do not
already have Bower installed, you should install it before you continue, as shown in Listing 1-1.

Listing 1-1. Installing the bower Command-Line Utility via npm


$ npm install -g bower
$ bower --version
1.3.12

■■Note Node’s package manager (npm) allows users to install packages in one of two contexts: locally
or globally. In this example, bower is installed within the global context, which is typically reserved for
command-line utilities.

Configuring Bower
Bower is configured on a per-project basis through a single (optional) JSON file that exists in your project’s
root folder, .bowerrc. For the purposes of this introduction, we’ll only look at the most frequently changed
setting within this file (see Listing 1-2).

Listing 1-2. The .bowerrc File from This Chapter’s Sample Project
// example-bootstrap/.bowerrc

{
"directory": "./public/bower_components"
}

By default, Bower will store your project’s dependencies in the bower_components folder. You will likely
want to change this location, and the directory setting allows you to do so.

The Manifest
Bower provides developers with a single point of entry from which third-party libraries can be found, added,
upgraded, and removed. As these actions occur, Bower updates a JSON file referred to as the “manifest”
with an up-to-date list of the project’s dependencies. The Bower manifest for this chapter’s sample project is
shown in Listing 1-3. In this example, Bower is aware of a single dependency, the Bootstrap CSS framework.

Listing 1-3. Bower Manifest for This Chapter’s Sample Project


// example-bootstrap/bower.json

{
"name": "example-bootstrap",
"version": "1.0.0",
"homepage": "https://github.com/username/project",

www.it-ebooks.info
Chapter 1 ■ Bower

"authors": [
"John Doe <[email protected]>"
],
"dependencies": {
"bootstrap": "3.2.0"
}
}

If we were to accidentally delete all of our project’s dependencies by removing the public/bower_
components folder, we could easily restore our project to its previous state by issuing a single command, as
shown next. Doing so would cause Bower to compare its manifest with our project’s current file structure,
determine what dependencies are missing, and restore them.

$ bower install

As a result of this behavior, we have the option of ignoring our project’s /public/bower_components
folder within version control. By committing only Bower’s manifest, and not the dependencies themselves,
our project’s source code can be kept in a cleaner state, containing only files that pertain directly to our
own work.

■■Note Opinions differ as to whether or not keeping your project’s dependencies out of version control is
a good idea. On the one hand, doing so results in a cleaner repository. On the other hand, this also opens the
door to potential problems should you (or the Bower registry, or GitHub, etc.) encounter connection issues.
The general consensus seems to be that if you are working on a “deployable” project (i.e., an application,
not a module), committing your dependencies is the preferred approach. Otherwise, keeping your project’s
dependencies out of version control is probably a good idea.

Creating a New Manifest


When you begin to use Bower within a project for the first time, it’s typically best to allow Bower to create a
new manifest for you, as shown next. Afterward, you can modify it further if necessary.

$ bower init

Finding, Adding, and Removing Bower Packages


Bower’s command-line utility provides a number of useful commands for locating, installing, and removing
packages. Let’s take a look at how these commands can help simplify the process of managing a project’s
external dependencies.

Finding Packages
One of the primary ways in which Bower can improve your development workflow is by providing you with a
centralized registry from which third-party libraries can be found. To search the Bower registry, simply pass
the search argument to Bower, followed by a keyword to search for, as shown in Listing 1-4. In this example,
only a short excerpt from the returned list of search results is shown.

www.it-ebooks.info
Chapter 1 ■ Bower

Listing 1-4. Searching Bower for jQuery


$ bower search jquery

Search results:

jquery git://github.com/jquery/jquery.git
jquery-ui git://github.com/components/jqueryui
jquery.cookie git://github.com/carhartl/jquery-cookie.git
jquery-placeholder git://github.com/mathiasbynens/jquery-placeholder.git

Adding Packages
Each search result includes the name under which the package was registered, along with the URL of the
GitHub repository at which it can be accessed directly. Once we have located the desired package, we can
add it to our project as shown in Listing 1-5.

Listing 1-5. Adding jQuery to Our Project


$ bower install jquery --save
bower jquery#* cached git://github.com/jquery/jquery.git#2.1.3
bower jquery#* validate 2.1.3 against git://github.com/jquery/jquery.git#*
bower jquery#>= 1.9.1 cached git://github.com/jquery/jquery.git#2.1.3
bower jquery#>= 1.9.1 validate 2.1.3 against git://github.com/jquery/jquery.git#>= 1.9.1
bower jquery#>= 1.9.1 cached git://github.com/jquery/jquery.git#2.1.3
bower jquery#>= 1.9.1 validate 2.1.3 against git://github.com/jquery/jquery.git#>= 1.9.1
bower jquery#>= 1.9.1 install jquery#2.1.3

jquery#2.1.3 public/bower_components/jquery

■■Note Bower does not host any of the files associated with the packages contained within its registry; it
defers to GitHub for that responsibility. While it is possible to host packages at any URL, the majority of public
packages are found on GitHub.

Take note of the fact that in Listing 1-5, we pass the --save option to Bower’s install command. By
default, the install command will add the requested package to a project without updating its manifest.
By passing the --save option, we instruct Bower to permanently store this package within its list of
dependencies.
Listing 1-6 shows the HTML from this chapter’s sample project. After adding jQuery to our project via
Bower, we can load it via a script tag as we would any other library.

www.it-ebooks.info
Chapter 1 ■ Bower

Listing 1-6. HTML from Our Sample Project That References the jQuery Package Just Added
// example-jquery/public/index.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Bower Example</title>
</head>
<body>
<div id="container"></div>
<script src="/bower_components/jquery/dist/jquery.min.js"></script>
<script>
$(document).ready(function() {
$('#container').html('<p>Hello, world!</p>');
});
</script>
</body>
</html>

Development Dependencies
By default, any packages that Bower installs are considered to be “production” dependencies, but this
behavior can be overridden by passing the --save-dev option. Doing so will flag any installed packages as
“development” dependencies. Such packages are intended for development purposes only, not for the final
users of a project.
Once we are ready to deploy our application to a production environment, we can instruct Bower to
install only the production dependencies, as shown next, resulting in a leaner build that does not contain
extraneous files of no interest to the end user.

$ bower install --production

Removing Packages
The process of removing Bower packages is straightforward. As in previous examples, we pass the --save
argument to update Bower’s manifest to reflect this change:

$ bower uninstall jquery --save

www.it-ebooks.info
Chapter 1 ■ Bower

Semantic Versioning
If you were to install jQuery (as shown in Listing 1-5) and then look at the contents of your project’s Bower
manifest, you would see something that resembles Listing 1-7.

Listing 1-7. Semantic Version (Semver) Number


"dependencies": {
"jquery": "~2.1.3"
}

The version number 2.1.3 that we see in Listing 1-7 (ignore the ~ character for a moment) is what is
known as a semantic version number (semver for short). Semantic versioning is a standard that describes
a common format that developers can use to assign version numbers to their projects. The format is
illustrated here:

Version X.Y.Z (Major.Minor.Patch)

The semantic versioning format dictates that developers create clearly defined (either by
documentation or by clear, self-documenting code) APIs that provide users with a single point of entry into a
library. New projects that are just getting off the ground typically begin at version 0.0.0 and work their way up
incrementally as new releases are created. A project with a version number below 1.0.0 is considered to be
under heavy development and, as such, is allowed to make sweeping changes to its API without altering its
major version number. A project with a version number at or above 1.0.0, however, is guided by the following
set of rules that determines how version numbers should be changed:
• A project’s major version number should change when updates occur that result in
breaking changes with how users have interacted with a project’s API in previous
versions.
• A project’s minor version number should change when new features are added to a
project in a way that is backward-compatible (i.e., the existing API is not broken).
• A project’s patch version number should change when backward-compatible bug
fixes are introduced.
These rules provide developers with insight into the extent of changes that have occurred between any
two versions. Such insight will prove useful as our Bower manifest grows and we begin adding more and
more dependencies to our project.

■■Note The ~ character shown in Listing 1-7 tells Bower that whenever the install command is run, it is
allowed to automatically install future versions of jQuery that are “relatively close to” version 2.1.3. If the use of
the phrases “relatively close to” and “automatically install” within the same sentence makes your skin crawl,
you’re not alone. Best practices suggest that you avoid the “~X.Y.Z” format when referencing dependencies
with Bower. Instead, you are better off specifying the exact version of the dependency that you wish to include
within your project. As future updates are released, you can then manually review them and make your own
decisions regarding if and when to update. Subsequent examples within this chapter will follow this advice.

www.it-ebooks.info
Chapter 1 ■ Bower

Managing the Dependency Chain


One of the primary benefits that developers gain as a result of using Bower is the ease with which updates to
a project’s entire dependency chain can be monitored and integrated. To illustrate this point, let’s take a look
at the list of dependencies contained within this chapter’s sample project (see Listing 1-8).

Listing 1-8. Installing and Listing the Various Bower Packages Required by Our Sample Project
$ bower install
bower bootstrap#3.2.0 cached git://github.com/twbs/bootstrap.git#3.2.0
bower bootstrap#3.2.0 validate 3.2.0 against git://github.com/twbs/bootstrap.git#3.2.0
bower jquery#>= 1.9.0 cached git://github.com/jquery/jquery.git#2.1.3
bower jquery#>= 1.9.0 validate 2.1.3 against git://github.com/jquery/jquery.git#>= 1.9.0
bower bootstrap#3.2.0 install bootstrap#3.2.0
bower jquery#>= 1.9.0 install jquery#2.1.3

bootstrap#3.2.0 public/bower_components/bootstrap
└── jquery#2.1.3

jquery#2.1.3 public/bower_components/jquery

$ bower list
bower check-new Checking for new versions of the project dependencies..
example-bootstrap#1.0.0 /opt/example-bootstrap
└─┬ bootstrap#3.2.0 (latest is 3.3.2)
└── jquery#2.1.3

Thanks to Bower, we now have a simple graph that describes the external dependencies that our project
relies on, as well as the relationships between them. We can see that we have a Bootstrap dependency,
which in turn has its own dependency on jQuery. Bower also prints the specific version of each component
that is currently installed.

■■Note Many third-party libraries are not entirely self-contained—they have dependencies of their own.
Bootstrap (with its reliance on jQuery) is one such example. When adding such a package, Bower is smart
enough to recognize these additional dependencies and will proactively add them to your project if they don’t
already exist. It is important to note, however, that unlike more sophisticated package managers (e.g., npm),
Bower stores all of its packages within a flat folder structure, which means you will occasionally run into version
conflicts, if you’re not careful.

In Listing 1-8, Bower has informed us that a version of Bootstrap (3.3.2) newer than the version currently
relied upon by our project (3.2.0) is available. We can update this dependency by modifying our project’s
manifest to refer to this newer version and rerunning the install command, as shown in Listing 1-9.

www.it-ebooks.info
Chapter 1 ■ Bower

Listing 1-9. Installing Bower Packages After Having Updated the Version of jQuery Our Project Relies On
$ bower install
bower bootstrap#3.3.2 cached git://github.com/twbs/bootstrap.git#3.3.2
bower bootstrap#3.3.2 validate 3.3.2 against git://github.com/twbs/bootstrap.git#3.3.2
bower bootstrap#3.3.2 install bootstrap#3.3.2

bootstrap#3.3.2 public/bower_components/bootstrap
└── jquery#2.1.3

Creating Bower Packages


Until now, our focus has been on integrating Bower into our own projects. We’ve initialized Bower within
our project and discovered how we can go about finding, adding, and removing packages. At a certain point,
however, you’ll hopefully find yourself wanting to share your own packages with others. To do so, you’ll need
to ensure that you follow a few simple guidelines, starting with choosing a valid name.

Choose a Valid Name


You’ll need to settle on a name for your package that is unique throughout Bower’s public registry. Use
Bower’s search command to find out if your desired name is available. Additional requirements include
• The name should be in “slug” format; for example, my-unique-project.
• The name should be all lowercase.
• Only alphanumeric characters, dots, and dashes are allowed.
• The name should begin and end with an alphabetic character.
• Consecutive dots and dashes are not allowed.
• After settling on a name, update the contents of your project’s bower.json file
accordingly.

Use Semver Git Tags


Earlier in the chapter, we took a look at the concept of semantic versioning, a common standard for
assigning meaningful version numbers to projects. You’ll want to ensure that you follow this standard, as this
will allow the consumers of your package to track and integrate your future changes.
If the package you want to share is just getting started, an appropriate version number would be
0.0.0. As you commit future changes and create new releases, you can increment this value as appropriate,
depending on the extent of your updates. When you determine that your project has reached its first “stable”
milestone, update your version number to 1.0.0 to reflect that status.
Every version number of your project should have a corresponding tag on GitHub. It is this relationship
between GitHub tags and the versions of your package that allows consumers to reference specific versions
within their projects.
Assuming you’ve already committed your code to GitHub, see Listing 1-10 for an example of how you
might go about creating your first tag.

www.it-ebooks.info
Chapter 1 ■ Bower

Listing 1-10. Creating Your First Semver Git Tag


$ git tag -a 0.0.1 -m "First release."
$ git push origin 0.0.1

Publish Your Package to the Registry


Now that we’ve chosen an appropriate name for our package and assigned a version number (along with a
corresponding tag on GitHub), it’s time to publish our package to the public Bower registry:

$ bower register my-package-name https://github.com/username/my-package-name.git

■■Note Bear in mind that Bower is intended to serve as a centralized registry for libraries and components
that other developers can use within their own projects. It is not intended to serve as a distribution mechanism
for entire applications.

Summary
Bower is a simple command-line utility that eases some of the tedious tasks associated with managing
front-end assets. Unlike well-known package managers from other platforms (e.g., Node’s npm), Bower
was not designed to handle the specific needs of any one platform or language; instead, it favors a rather
generic approach to the concept of package management. The developers who created Bower intentionally
set out to create a very simple tool for managing a wide variety of front-end assets—not just code, but also
stylesheets, fonts, images, and other, unforeseen future dependencies.
Developers working on trivial web applications with few external dependencies may find little value
in the benefits that Bower brings to the table. That said, trivial web applications have a tendency to quickly
evolve into complex web applications, and as that process occurs, developers often come to appreciate
Bower’s benefits.
Regardless of how complex (or simple) you consider your project to be, we would encourage you to
consider integrating Bower into your workflow sooner rather than later. As bitter experience has taught
us—the project itself. Err on the side of too little structure, and you risk creating an ever-increasing burden
of “technical debt” for which you must eventually pay a price. The process of striking a delicate balance
between these undesired alternatives is as much an art as it is a science. It is also a process that is never fully
learned, but must continuously be adapted as the tools of our trade change.

www.it-ebooks.info
Chapter 2

Grunt

I’m lazy. But it’s the lazy people who invented the wheel and the bicycle because they didn’t
like walking or carrying things.
—Lech Walesa, former president of Poland

In his book Programming Perl, Larry Wall (the well-known creator of the language) puts forth the idea that
all successful programmers share three important characteristics: laziness, impatience, and hubris. At first
glance, these traits all sound quite negative, but dig a little deeper, and you’ll find the hidden meaning in his
statement:
Laziness: Lazy programmers hate to repeat themselves. As a result, they tend to
put a lot of effort into creating useful tools that perform repetitive tasks for them.
They also tend to document those tools well, to spare themselves the trouble of
answering questions about them later.
Impatience: Impatient programmers have learned to expect much from their
tools. This expectation teaches them to create software that doesn’t just react to
the needs of its users, but that actually attempts to anticipate those needs.
Hubris: Good programmers take great pride in their work. It is this pride that
compels them to write software that others won’t want to criticize—the type of
work that we should all be striving for.
In this chapter, we’ll focus on the first of these three characteristics, laziness, along with Grunt, a
popular JavaScript “task runner” that supports developers in nurturing this trait by providing them with a
toolkit for automating the repetitive build tasks that often accompany software development, such as:
• Script and stylesheet compilation and minification
• Testing
• Linting
• Database migrations
• Deployments

11

www.it-ebooks.info
Chapter 2 ■ Grunt

In other words, Grunt helps developers who strive to work smarter, not harder. If that idea appeals to
you, read on. After you have finished this chapter, you will be well on your way toward mastering Grunt.
You’ll learn how to do the following in this chapter:
• Create configurable tasks that automate the repetitive aspects of software
development that accompany nearly every project
• Interact with the file system using simple yet powerful abstractions provided
by Grunt
• Publish Grunt plugins from which other developers can benefit and to which they
can contribute
• Take advantage of Grunt’s preexisting library of community-supported plugins, of
which over 4,400 examples exist at the time of writing

Installing Grunt
Before continuing, you should ensure that you have installed Grunt’s command-line utility. Available as an
npm package, the installation process is shown in Listing 2-1.

Listing 2-1. Installing the grunt Command-Line Utility via npm


$ npm install -g grunt-cli
$ grunt --version
grunt-cli v0.1.13

How Grunt Works


Grunt provides developers with a toolkit for creating command-line utilities that perform repetitive project
tasks. Examples of such tasks include the minification of JavaScript code and the compilation of Sass
stylesheets, but there’s no limit to how Grunt can be put to work. Grunt can be used to create simple tasks
that address the specific needs of a single project—tasks that you don’t intend to share or reuse—but Grunt’s
true power derives from its ability to package tasks as reusable plugins that can then be published, shared,
used, and improved upon by others. At the time of this writing, over 4,400 such plugins exist.
Four core components make Grunt tick, which we will now cover.

Gruntfile.js
At Grunt’s core lies the Gruntfile, a Node module saved as Gruntfile.js (see Listing 2-2) at the root of
your project. It’s within this file that we can load Grunt plugins, create our own custom tasks, and configure
them according to the needs of our project. Each time Grunt is run, its first order of business is to retrieve its
marching orders from this module.

12

www.it-ebooks.info
Chapter 2 ■ Grunt

Listing 2-2. Sample Gruntfile


// example-starter/Gruntfile.js

module.exports = function(grunt) {

/**
* Configure the various tasks and plugins that we'll be using
*/
grunt.initConfig({
/* Grunt's 'file' API provides developers with helpful abstractions for
interacting with the file system. We'll take a look at these in greater
detail later in the chapter. */
'pkg': grunt.file.readJSON('package.json'),
'uglify': {
'development': {
'files': {
'build/app.min.js': ['src/app.js', 'src/lib.js']
}
}
}
});

/**
* Grunt plugins exist as Node packages, published via npm. Here, we load the
* 'grunt-contrib-uglify' plugin, which provides a task for merging and minifying
* a project's source code in preparation for deployment.
*/
grunt.loadNpmTasks('grunt-contrib-uglify');

/**
* Here we create a Grunt task named 'default' that does nothing more than call
* the 'uglify' task. In other words, this task will serve as an alias to
* 'uglify'. Creating a task named 'default' tells Grunt what to do when it is
* run from the command line without any arguments. In this example, our 'default'
* task calls a single, separate task, but we could just as easily have called
* multiple tasks (to be run in sequence) by adding multiple entries to the array
* that is passed.
*/
grunt.registerTask('default', ['uglify']);

/**
* Here we create a custom task that prints a message to the console (followed by
* a line break) using one of Grunt's built-in methods for providing user feedback.
* We'll look at these in greater detail later in the chapter.
*/
grunt.registerTask('hello-world', function() {
grunt.log.writeln('Hello, world.');
});

};

13

www.it-ebooks.info
Chapter 2 ■ Grunt

Tasks
Tasks are the basic building blocks of Grunt and are nothing more than functions that are registered with
assigned names via Grunt’s registerTask() method. In Listing 2-2, a simple hello-world task is shown that
prints a message to the console. This task can be called from the command line as shown in Listing 2-3.

Listing 2-3. Running the hello-world Task Shown in Listing 2-2


$ grunt hello-world
Running "hello-world" task
Hello, world.

Done, without errors.

Multiple Grunt tasks can also be run in sequence with a single command, as shown in Listing 2-4.
Each task will be run in the order in which it was passed.

Listing 2-4. Running Multiple Grunt Tasks in Sequence


$ grunt hello-world uglify
Running "hello-world" task
Hello, world.

Running "uglify:development" (uglify) task


>> 1 file created.

Done, without errors.

The hello-world task that we’ve just seen serves as an example of a basic, stand-alone Grunt task. Such
tasks can be used to implement simple actions specific to the needs of a single project that you don’t intend
to re-use or share. Most of the time, however, you will find yourself interacting not with stand-alone tasks,
but instead with tasks that have been packaged as Grunt plugins and published to npm so that others can
reuse them and contribute to them.

Plugins
A Grunt plugin is a collection of configurable tasks (published as an npm package) that can be reused across
multiple projects. Thousands of such plugins exist. In Listing 2-2, Grunt’s loadNpmTasks() method is used to
load the grunt-contrib-uglify Node module, a Grunt plugin that merges a project’s JavaScript code into a
single, minified file that is suitable for deployment.

■■Note A list of all available Grunt plugins can be found at http://gruntjs.com/plugins. Plugins whose
names are prefixed with contrib- are officially maintained by the developers behind Grunt.

14

www.it-ebooks.info
Chapter 2 ■ Grunt

Configuration
Grunt is known for emphasizing “configuration over code”: the creation of tasks and plugins whose
functionality is tailored by configuration that is specified within each project. It is this separation of code
from configuration that allows developers to create plugins that are easily reusable by others. Later in the
chapter, we’ll take a look at the various ways in which Grunt plugins and tasks can be configured.

Adding Grunt to Your Project


Earlier in the chapter, we installed Grunt’s command-line utility by installing the grunt-cli npm package
as a global module. We should now have access to the grunt utility from the command line, but we still
need to add a local grunt dependency to each project we intend to use it with. The command to be called
from within the root folder of your project is shown next. This example assumes that npm has already been
initialized within the project and that a package.json file already exists.

$ npm install grunt --save-dev

Our project’s package.json file should now contain a grunt entry similar to that shown in Listing 2-5.

Listing 2-5. Our Project’s Updated package.json File


// example-tasks/package.json

{
"name": "example-tasks",
"version": "1.0.0",
"devDependencies": {
"grunt": "0.4.5"
}
}

The final step toward integrating Grunt with our project is the creation of a Gruntfile (see Listing 2-6),
which should be saved within the root folder of the project. Within our Gruntfile, a single method is called,
loadTasks(), which is discussed in the upcoming section.

Listing 2-6. Contents of Our Project’s Gruntfile


// example-tasks/Gruntfile.js

module.exports = function(grunt) {
grunt.loadTasks('tasks');
};

Maintaining a Sane Grunt Structure


We hope that by the time you have finished this chapter, you will have found Grunt to be a worthwhile tool
for automating many of the repetitive, tedious tasks that you encounter during the course of your daily
workflow. That said, we’d be lying if we told you that our initial reaction to Grunt was positive. In fact,
we were quite turned off by the tool at first. To help explain why, let’s take a look at the Gruntfile that is
prominently displayed within Grunt’s official documentation (see Listing 2-7).

15

www.it-ebooks.info
Chapter 2 ■ Grunt

Listing 2-7. Example Gruntfile Provided by Grunt’s Official Documentation


module.exports = function(grunt) {

grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
concat: {
options: {
separator: ';'
},
dist: {
src: ['src/**/*.js'],
dest: 'dist/<%= pkg.name %>.js'
}
},
uglify: {
options: {
banner: '/*! <%= grunt.template.today("dd-mm-yyyy") %> */\n'
},
dist: {
files: {
'dist/<%= pkg.name %>.min.js': ['<%= concat.dist.dest %>']
}
}
},
qunit: {
files: ['test/**/*.html']
},
jshint: {
files: ['Gruntfile.js', 'src/**/*.js', 'test/**/*.js'],
options: {
// options here to override JSHint defaults
globals: {
jQuery: true,
console: true,
module: true,
document: true
}
}
},
watch: {
files: ['<%= jshint.files %>'],
tasks: ['jshint', 'qunit']
}
});

16

www.it-ebooks.info
Chapter 2 ■ Grunt

grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.loadNpmTasks('grunt-contrib-qunit');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-contrib-concat');

grunt.registerTask('test', ['jshint', 'qunit']);

grunt.registerTask('default', ['jshint', 'qunit', 'concat', 'uglify']);

};

The Gruntfile shown in Listing 2-7 is for a relatively simple project. We already find this example to be
slightly unwieldy, but within larger projects we have seen this file balloon to many times this size. The result
is an unreadable and difficult-to-maintain mess. Experienced developers would never write their code in a
way that combines functionality from across unrelated areas into a single, monolithic file, so why should we
approach our task runner any differently?
The secret to maintaining a sane Grunt structure lies with Grunt’s loadTasks() function, as shown in
Listing 2-6. In this example, the tasks argument refers to a tasks folder relative to our project’s Gruntfile.
Once this method is called, Grunt will load and execute each Node module it finds within this folder,
passing along a reference to the grunt object each time. This behavior provides us with the opportunity to
organize our project’s Grunt configuration as a series of separate modules, each responsible for loading and
configuring a single task or plugin. An example of one of these smaller modules is shown in Listing 2-8. This
task can be executed by running grunt uglify from the command line.

Listing 2-8. Example Module (uglify.js) Within Our New tasks Folder
// example-tasks/tasks/uglify.js

module.exports = function(grunt) {

grunt.loadNpmTasks('grunt-contrib-uglify');

grunt.config('uglify', {
'options': {
'banner': '/*! <%= grunt.template.today("dd-mm-yyyy") %> */\n'
},
'dist': {
'files': {
'dist/app.min.js': ['src/index.js']
}
}
});

};

17

www.it-ebooks.info
Chapter 2 ■ Grunt

Working with Tasks


As previously mentioned, tasks serve as the foundation on which Grunt is built—everything begins here.
A Grunt plugin, as you’ll soon discover, is nothing more than one or more tasks that have been packaged into
a Node module and published via npm. We’ve already seen a few examples that demonstrate the creation of
basic Grunt tasks, so let’s take a look at some additional features that can help us get the most out of them.

Managing Configuration
Grunt’s config() method serves as both a “getter” and a “setter” for configuration. In Listing 2-9, we see how
a basic Grunt task can access its configuration through the use of this method.

Listing 2-9. Managing Configuration Within a Basic Grunt Task


module.exports = function(grunt) {

grunt.config('basic-task', {
'message': 'Hello, world.'
});

grunt.registerTask('basic-task', function() {
grunt.log.writeln(grunt.config('basic-task.message'));
});

};

■■Note In Listing 2-9, “dot notation” is used for accessing nested configuration values. In the same way,
dot notation can be used to set nested configuration values. If at any point Grunt encounters a path within the
configuration object that does not exist, Grunt will create a new, empty object without throwing an error.

Task Descriptions
Over time, projects have a tendency to grow in complexity. With this additional complexity often comes
new Grunt tasks. As new tasks are added, it’s often easy to lose track of what tasks are available, what they
do, and how they are called. Fortunately, Grunt provides us with a way to address this problem by assigning
descriptions to our tasks, as shown in Listing 2-10.

Listing 2-10. Assigning a Description to a Grunt Task


// example-task-description/Gruntfile.js

module.exports = function(grunt) {

grunt.config('basic-task', {
'message': 'Hello, world.'
});

18

www.it-ebooks.info
Chapter 2 ■ Grunt

grunt.registerTask('basic-task', 'This is an example task.', function() {


grunt.log.writeln(grunt.config('basic-task.message'));
});

grunt.registerTask('default', 'This is the default task.', ['basic-task']);

};

By passing an additional argument to the registerTask() method, Grunt allows us to provide a


description for the task being created. Grunt helpfully provides this information when help is requested from
the command line, as shown in Listing 2-11, which includes an excerpt of the information Grunt provides.

Listing 2-11. Requesting Help from the Command Line


$ grunt --help
...
Available tasks
basic-task This is an example task.
default This is the default task.
...

Asynchronous Tasks
By default, Grunt tasks are expected to run synchronously. As soon as a task’s function returns, it
is considered finished. There will be times, however, when you find yourself interacting with other
asynchronous methods within a task, which must first complete before your task can hand control back over
to Grunt. The solution to this problem is shown in Listing 2-12. Within a task, a call to the async() method
will notify Grunt that it executes asynchronously. The method will return a callback function to be called
when our task has completed. Until this is done, Grunt will hold the execution of any additional tasks.

Listing 2-12. Asynchronous Grunt Task


// example-async/tasks/list-files.js

var glob = require('glob');

module.exports = function(grunt) {

grunt.registerTask('list-files', function() {

/**
* Grunt will wait until we call the `done()` function to indicate that our
* asynchronous task is complete.
*/
var done = this.async();

19

www.it-ebooks.info
Chapter 2 ■ Grunt

glob('*', function(err, files) {


if (err) {
grunt.fail.fatal(err);
}
grunt.log.writeln(files);
done();
});

});

};

Task Dependencies
Complicated Grunt workflows are best thought of as a series of steps that work together to produce a final
result. In such situations, it can often be helpful to specify that a task requires one or more separate tasks to
precede it, as shown in Listing 2-13.

Listing 2-13. Declaring a Task Dependency


// example-task-dependency/tasks/step-two.js

module.exports = function(grunt) {
grunt.registerTask('step-two', function() {
grunt.task.requires('step-one');
});
};

In this example, the step-two task requires that the step-one task run first before it can proceed. Any
attempt to call step-two directly will result in an error, as shown in Listing 2-14.

Listing 2-14. Grunt Reporting an Error When a Task Is Called Before Any Tasks on Which
It Depends Have Run
$ grunt step-two
Running "step-two" task
Warning: Required task "step-one" must be run first. Use --force to continue.

Aborted due to warnings.

Multi-Tasks
In addition to basic tasks, Grunt offers support for what it calls “multi-tasks.” Multi-tasks are easily the most
complicated aspect of Grunt, so if you find yourself confused at first, you’re not alone. After reviewing a few
examples, however, their purpose should start to come into focus—at which point you’ll be well on your way
toward mastering Grunt.
Before we go any further, let’s take a look at a brief example (see Listing 2-15) that shows a Grunt
multi-task, along with its configuration.

20

www.it-ebooks.info
Chapter 2 ■ Grunt

Listing 2-15. Grunt Multi-Task


// example-list-animals/tasks/list-animals.js

module.exports = function(grunt) {

/**
* Our multi-task's configuration object. In this example, 'mammals'
* and 'birds' each represent what Grunt refers to as a 'target.'
*/
grunt.config('list-animals', {
'mammals': {
'animals': ['Cat', 'Zebra', 'Koala', 'Kangaroo']
},
'birds': {
'animals': ['Penguin', 'Sparrow', 'Eagle', 'Parrot']
}
});

grunt.registerMultiTask('list-animals', function() {
grunt.log.writeln('Target:', this.target);
grunt.log.writeln('Data:', this.data);
});

};

Multi-tasks are extremely flexible, in that they are designed to support multiple configurations (referred
to as “targets”) within a single project. The multi-task shown in Listing 2-15 has two targets: mammals and
birds. This task can be run against a specific target as shown in Listing 2-16.

Listing 2-16. Running the Grunt Multi-Task Shown in Listing 2-15 Against a Specific Target
$ grunt list-animals:mammals
Running "list-animals:mammals" (list-animals) task
Target: mammals
Data: { animals: [ 'Cat', 'Zebra', 'Koala', 'Kangaroo' ] }

Done, without errors.

Multi-tasks can also be called without any arguments, in which case they are executed multiple times,
once for each available target. Listing 2-17 shows the result of calling this task without specifying a target.

Listing 2-17. Running the Multi-Task Shown in Listing 2-15 Without Specifying a Target
$ grunt list-animals
Running "list-animals:mammals" (list-animals) task
Target: mammals
Data: { animals: [ 'Cat', 'Zebra', 'Koala', 'Kangaroo' ] }

Running "list-animals:birds" (list-animals) task


Target: birds
Data: { animals: [ 'Penguin', 'Sparrow', 'Eagle', 'Parrot' ] }

21

www.it-ebooks.info
Another Random Scribd Document
with Unrelated Content
coin de la jurte à l'autre. Quelquefois on la met en pénitence, et l'on
est un certain temps sans lui rendre aucune sorte de culte, sans lui
marquer aucun respect; ou quand on est bien piqué contre elle, on
la porte à l'eau pour la noyer.
Les Tunguses ont une façon de prendre les muscs et les daims.
Quand les petits de ces animaux sont égarés, ils ont un cri particulier
pour appeler leurs mères: cette découverte faite par les Tunguses
leur donne la facilité de prendre ces animaux, ce qu'ils font toujours
dans l'été. Ils n'ont qu'à plier un morceau d'écorce de bouleau, avec
lequel ils imitent le cri des jeunes muscs et des petits daims, et leurs
mères accourant à ces cris, ils les tuent sans peine à coups de
flèches.
La manière dont se fait la chasse des zibelines a quelques
circonstances singulières. Il se forme ordinairement une société de
dix à douze chasseurs qui partagent entre eux toutes les zibelines
qu'ils prennent. Avant de partir pour la chasse, ils font vœu d'offrir à
l'église une certaine portion de leurs prises; ils choisissent entre eux
un chef à qui toute la compagnie est tenue d'obéir; ce chef est
appelé peredowschick, c'est-à-dire conducteur, et ils lui portent un si
grand respect qu'ils s'imposent eux-mêmes les lois les plus sévères
pour ne point s'écarter de ses ordres. Quand quelqu'un manque à
l'obéissance qu'il doit au conducteur, celui-ci le réprimande; il est
même en droit de lui donner des coups de bâton, et ce châtiment se
nomme, ainsi que la simple réprimande, une leçon (utschenié).
Outre cette leçon, le réfractaire perd encore toutes les zibelines qu'il
a prises. Il lui est défendu d'être assis en cercle avec les autres
chasseurs pendant leurs repas; il est obligé de se tenir debout et de
faire tout ce que les autres lui commandent. Il faut qu'il allume le
poêle de la chambre noire, qu'il la tienne propre, qu'il coupe du bois,
et enfin qu'il fasse le ménage. Cette punition dure jusqu'à ce que
toute la société lui ait accordé son pardon, qu'il demande
continuellement et debout, tandis que les autres mangent assis.
Dès qu'on a pris une zibeline, il faut la serrer sur-le-champ sans la
regarder; car ils s'imaginent que de parler bien ou mal de la zibeline
qu'on a prise, c'est la gâter. Un ancien chasseur poussait si loin cette
superstition, qu'il disait qu'une des principales causes qui faisaient
manquer la chasse des zibelines, c'était d'avoir envoyé quelques-uns
de ces animaux vivants à Moscou, parce que tout le monde les avait
admirés comme des animaux rares, ce qui n'était point du goût des
zibelines. Une autre raison de leur disette, c'était, selon lui, que le
monde était devenu beaucoup plus mauvais, et qu'il y avait souvent
dans leurs sociétés des chasseurs qui cachaient leurs prises, ce que
les zibelines ne pouvaient encore souffrir.
Les habitants du district de Kirenga et des bords du Léna, hommes
et animaux, comme les bœufs, les vaches, sont sujets aux goîtres.
On croit ici communément que les goîtres sont héréditaires, et que
les enfants naissent avec ces sortes d'excroissances, ou du moins en
apportent le germe; mais ce sentiment n'est pas général: il n'est pas
adopté surtout par ceux qui ont des goîtres et qui cherchent à se
marier.
A l'occasion de quelques déserteurs de notre troupe, qu'avait
effrayés l'expédition au Kamtchatka, et qui nous abandonnèrent,
j'appris une superstition des Sibériens que j'ignorais. Lorsqu'on
ouvrit le sac de voyage d'un de ces déserteurs que l'on avait arrêté,
on y trouva, entre autres choses, un petit paquet rempli de terre. Je
demandai ce que c'était. On me dit que les voyageurs qui passaient
de leur pays dans un autre étaient dans l'usage d'emporter de la
terre ou du sable de leur sol natal, et que partout où ils se trouvaient
ils en mêlaient un peu dans de l'eau qu'ils buvaient sous un ciel
étranger; que cette précaution les préservait de toutes sortes de
maladies, et que son principal effet était de les garantir de celles du
pays. En même temps on m'assura que cette superstition ne venait
pas originairement de Sibérie, mais qu'elle était établie depuis un
temps immémorial parmi les Russes mêmes.
Les Yakoutes supposent deux êtres souverains, l'un cause de tout le
bien, et l'autre du mal. Chacun de ces êtres a sa famille. Plusieurs
diables, selon eux, ont femmes et enfants. Tel ordre de diables nuit
aux bestiaux, tel autre aux hommes faits, tel autre aux enfants, etc.
Certains démons habitent les nuées, et d'autres fort avant dans la
terre. Il en est de même de leurs dieux: les uns ont soin des
bestiaux, les autres procurent une bonne chasse, d'autres protégent
les hommes, etc.; mais ils résident tous fort haut dans les airs.
Un endroit du Léna fort célèbre par une suite de montagnes placées
sur la rive gauche du fleuve, qui forment comme des espèces de
colonnes élevées dans des directions différentes, attire l'attention de
tous les voyageurs. On l'appelle Stolbi. Je fis arrêter notre bâtiment
à deux werstes au-dessous de l'endroit où commence cette
colonnade de montagnes, tant pour les voir de près que pour
examiner la mine de fer qu'on y exploitait depuis l'année précédente
pour la compagnie de Kamtchatka. Ces montagnes colonniformes
font un spectacle aussi singulier que curieux. Depuis leur pied
jusqu'à leur sommet, de grandes pièces de rochers s'élèvent les
unes en forme de colonnes rondes, d'autres comme des cheminées
carrées, d'autres comme de grands murs de pierre, de la hauteur de
dix à quinze brasses: on s'imaginerait voir les ruines d'une grande
ville. Plus on en est éloigné, plus le coup d'œil est beau, parce que
les pièces de rochers, placées les unes derrière les autres, prennent
toutes sortes de formes, selon le point de vue d'où on les regarde.
Les arbres qui se trouvent entre leurs intervalles augmentent encore
la beauté du coup d'œil. Ces montagnes occupent une étendue de
trente-cinq werstes; elles diminuent graduellement, et se perdent
enfin tout à fait.
La pierre dont les colonnes sont formées est en partie sablonneuse
et de toutes sortes de couleurs, en partie d'un marbre rouge
agréablement varié. Enfin, à une certaine distance, ces montagnes
pyramidales ou colonniformes rappellent exactement tout ce qui
compose la perspective des villes: tours, clochers, péristyles, et
autres édifices. Entre les rochers, ainsi figurés en colonnes, on
trouve épars un bon minerai de fer, et l'on voit, au pied de la
montagne où commence la perspective, deux cabanes construites
avec des broussailles en forme de jurte, où les ouvriers se retirent la
nuit et les jours de fête. Je me rendis à cette montagne, dont la
hauteur est d'environ trois quarts de werste, et j'y trouvai tous les
ouvriers travaillant: je n'avais encore vu nulle part exploiter si
lestement une mine.
Notre troupe académique se réunit à Yakoutsk, en septembre. L'hiver
avançait. Le 19 septembre, le Léna commença à charrier de la glace,
qui augmenta tellement de jour en jour jusqu'au 28 du même mois,
que le fleuve en fut entièrement couvert le lendemain: on le passait
partout en traîneau. La glace devint en peu de jours si épaisse,
qu'on pouvait en tirer des morceaux considérables pour l'usage des
habitants; car on fait ici de la glace unie un usage dont on n'a point
d'idée ailleurs: elle sert à calfeutrer les maisons. Pour peu que les
fenêtres d'un logis ne ferment pas avec précision, elles ne sauraient
suffisamment garantir les chambres du froid extérieur. Les caves
mêmes dans lesquelles on garde la boisson, comme bière, hydromel,
vin, etc., ne peuvent pas être à l'abri du grand froid par les moyens
ordinaires, comme de bonnes portes, du fumier de cheval, etc. C'est
la rigueur du froid même qui fournit le moyen le plus sûr d'empêcher
qu'il ne pénètre dans les habitations. On coupe de la glace bien
nette, et dans laquelle il n'y ait point d'ordure; on en taille des
morceaux de l'exacte grandeur des fenêtres et des ouvertures, et on
les y applique par dehors, comme on fait ailleurs de doubles châssis
de verre. Pour qu'ils tiennent, on ne fait qu'y verser de l'eau, qui, en
se gelant, les attache fortement aux ouvertures. Ces vitraux de glace
n'ôtent pas beaucoup de lumière: lorsqu'il y a du soleil, on voit aussi
clair qu'à travers des châssis de verre; et quelque vent qu'il fasse au
dehors, le froid n'entre jamais dans les chambres. Les gens aisés,
dont les maisons ont des fenêtres, appliquent les vitraux de glace
par dedans, et par là ne souffrent point du tout des froides
émanations de la glace. La boisson ne se gèle pas non plus dans les
caves, quand leurs ouvertures ou soupiraux sont garnis de ces sortes
de châssis. Ceux mêmes qui n'ont point d'autres vitraux que ces
fenêtres de glace, s'en trouvent fort bien, pourvu qu'ils aient
l'attention de ne pas trop rester dans les chambres après que le
poêle est fermé: cependant les nationaux ne prennent guère cette
précaution.
La ville de Yakoutsk est située dans une plaine sur la rive gauche du
Léna, qui se jette à deux cents lieues plus loin dans la mer Glaciale.
L'hiver y est ordinairement très-rude; mais les forêts qui sont au-
dessus et au-dessous de la ville fournissent assez de bois.
Quant à la végétation des grains, le climat n'y paraît pas propre. Il
est vrai que le couvent de la basse ville a ensemencé autrefois
quelques terrains d'orge qui, dans certaines années, a mûri; mais
comme elle manquait dans d'autres temps, cette culture est
abandonnée. Je n'ai point entendu dire qu'outre l'orge aucun autre
grain soit parvenu à sa pleine maturité; mais c'est la qualité du
climat, plutôt que celle du sol, qui s'oppose à la maturation des
grains; car le terrain est noir et gras; il s'y trouve même de temps en
temps des champs garnis de bouleaux clair-semés, ce qu'on regarde
en Sibérie comme la marque d'une bonne terre labourable. Après
tout, que peut produire la terre, quelque bonne qu'elle soit,
lorsqu'elle manque de chaleur? Et quelle chaleur peut-elle avoir,
quand à la fin de juin elle est encore gelée à la profondeur de trois
pieds ou même davantage?
Quoique dans les environs de Yakoutsk il y ait encore quelques
montagnes, on y trouve peu ou point de sources, et c'est
vraisemblablement parce que la terre est gelée à une certaine
profondeur.
Le séjour de toutes les personnes réunies à Yakoutsk pour le voyage
de Kamtchatka rendait cette ville fort active, et nous n'y fûmes point
désœuvrés. La brièveté des jours dans un climat rigoureux, sous la
latitude de soixante-deux degrés deux secondes, n'encourageait pas
beaucoup au travail. Il faisait à peine jour à neuf heures du matin.
Quand il s'élevait un certain vent qui chassait une poussière de
neige, on ne pouvait rester sans lumière aux plus belles heures de la
journée, et par un temps serein on voyait déjà les étoiles avant deux
heures après midi. La plupart des habitants profitent de ce temps
oiseux pour dormir: à peine sont-ils levés pour manger qu'ils se
recouchent encore, et quand le jour est tout à fait sombre, souvent
ils ne se réveillent point. Nous étions bien prévenus du danger qu'il y
avait, en s'abandonnant au sommeil, de gagner le scorbut: nous
nous arrangeâmes en conséquence, et nous partagions notre temps
entre le travail et la dissipation, sans en donner beaucoup au
sommeil.
Je m'amusais fort bien d'une sorte de marmottes très-communes
dans le pays, et que les Russes nomment iewraschka. Ce joli petit
animal se trouve dans les champs aux environs de Yakoutsk, et
jusque dans les caves et dans les greniers, aussi bien dans ceux qui
sont creusés sous terre que dans ceux qui sont au haut des
maisons; car il est bon de remarquer que, dans tout le district de
Yakoutsk, il y a autant de greniers à blé sous terre qu'au-dessus,
parce que dans les premiers les grains sont à l'abri de l'humidité et
des insectes. Tout ce qui est sous la surface de la terre, à la
profondeur de deux pieds, y gèle presque en toute saison; ni
l'humidité ni les insectes n'y pénètrent guère. Les marmottes des
champs restent dans des souterrains qu'elles se creusent, et
dorment pendant tout l'hiver; mais celles qui sont friandes de blé et
de légumes sont en mouvement l'hiver et l'été pour chercher partout
leur nourriture. Lorsqu'on prend cet animal et qu'on l'irrite, il mord
très-fort, et pousse un cri sonore comme celui de la marmotte
ordinaire. Quand on lui donne à manger, il se tient assis sur les
pattes de derrière et mange avec celles de devant. Les femelles de
ces animaux mettent bas dans les mois d'avril et de mai; elles ont
depuis cinq jusqu'à huit petits. On trouve en différents endroits de la
Sibérie de véritables marmottes, mais qui diffèrent, selon les lieux,
de grosseur et de couleur. Les Russes et les Tatares les nomment
suroks.
L'hiver de cette année fut très-doux relativement au climat;
cependant on éprouva de temps en temps des froids excessifs. J'en
faillis porter de tristes marques un jour que je courus en traîneau
pendant l'espace d'une demi-lieue avec quelques personnes. Nous
sortions d'auprès d'un poêle bien chaud; nous étions bien garnis de
pelisses; nous n'avions mis que six minutes à faire le trajet: nous
trouvâmes en arrivant une chambre bien chaude, et nous avions
tous le nez gelé.
Les habitants m'assurèrent que le plus grand froid de cet hiver
n'approchait pas de celui qu'ils avaient ressenti dans certaines
années. On raconte même qu'il y eut un hiver où le froid fut si vif,
qu'un gouverneur de province, en allant de sa maison à la
chancellerie, qui n'en était pas éloignée de plus de cinquante pas,
quoiqu'il fût enveloppé dans une longue pelisse, et qu'il eût un
capuchon fourré qui lui couvrait toute la tête, eut les mains, les
pieds et le nez gelés, et qu'on eut beaucoup de peine à le guérir de
cet accident. Pendant l'hiver que nous passâmes à Yakoutsk, le
thermomètre marquait quelquefois soixante-douze degrés au-
dessous de zéro (trente-quatre degrés centigrades). On juge bien
que sous un pareil ciel les hommes sont souvent exposés à avoir des
membres gelés.
Voici les indices du mal et les remèdes qu'on y apporte. Un membre
qui vient d'être gelé n'a plus aucune sensibilité; il n'y reste aucune
trace de rougeur, et il est plus blanc qu'aucun autre endroit du corps.
Pour rétablir la partie gelée, on conseille ordinairement de la frotter
bien fort avec de la neige. Lorsqu'on commence à s'apercevoir que
quelque sensibilité y revient, on continue le frottement; mais au lieu
de neige on se sert d'eau froide. Quand la congélation n'a pas duré
bien longtemps, et n'est arrivée qu'en passant d'une maison à une
autre, le remède le plus prompt est de bien frotter le membre avec
un morceau de laine. Ce moyen est en usage à Yakoutsk, et je l'ai
moi-même éprouvé avec assez de succès; mais quand le membre a
été gelé pendant un temps considérable, les frottements avec la
neige, avec l'eau froide et avec la laine ne servent à rien. Il faut
dans ce cas plonger le membre gelé dans la neige, ensuite dans
l'eau froide, et l'y tenir très-longtemps, après quoi l'on en vient au
frottement. Les Yakoutes, dont les Russes ont adopté la méthode,
couvrent les membres gelés de fiente de vache ou de terre glaise,
ou de ces deux choses mêlées ensemble en même temps. On
prétend que ce remède dissipe peu à peu l'inflammation du membre
gelé, et lui rend la vie: il est encore regardé comme un bon
préservatif. La plupart des Yakoutes, lorsqu'ils sont obligés de faire
un voyage un peu long par un grand froid, enduisent de cette
espèce d'onguent toutes les parties dont on craint la congélation; et
tous assurent que s'ils ne sont pas entièrement garantis par cet
enduit, il ralentit du moins l'effet de la gelée.
La manière de vivre des Yakoutes ne diffère pas beaucoup de celle
des autres nations de Sibérie; mais ils ont un usage dont il n'y a
peut-être point d'exemple chez aucun autre peuple du monde:
lorsqu'une femme yakoute a mis au monde un enfant, la première
personne qui entre dans la jurte donne le nom au nouveau-né.
C'est à Yakoutsk que nos voyageurs devaient trouver toutes les
facilités nécessaires pour se transporter au Kamtchatka; mais,
malgré les ordres du sénat de Saint-Pétersbourg, qui apparemment
avait peu de puissance en raison de son éloignement, la chancellerie
de Yakoutsk ne leur fournit ni bâtiments, ni équipages pour pouvoir
se rendre à Okhotsk, d'où l'on s'embarque sur la mer du
Kamtchatka; ils résolurent donc de reprendre la route de Saint-
Pétersbourg. Considérant, dit le docteur Gmelin, qu'il y avait déjà
quatre années que nous étions partis de Saint-Pétersbourg, tandis
qu'on nous avait fait espérer que notre voyage ne durerait en tout
que cinq ans, nous comprîmes que, quand tout réussirait à notre
gré, quand nous trouverions toutes les facilités possibles pour passer
au Kamtchatka, il y aurait déjà cinq ans d'écoulés, et qu'il fallait
compter encore au moins deux ans pour le retour, outre le temps de
notre séjour dans cette presqu'île. Nous n'avions, d'ailleurs,
nullement envie d'habiter éternellement les contrés sauvages de la
Sibérie. Nous prîmes donc, le professeur Muller et moi, les
arrangements nécessaires pour notre départ de Yakoutsk.
Les glaces de la mer fondent presque toujours dans le même temps
que le Iénisée dégèle à son embouchure; ce qui arrive
communément vers le 12 juin. La mer est bientôt nettoyée, lorsqu'il
souffle des vents de terre qui chassent les glaces. Une circonstance
remarquable, c'est que, même après que les vents de terre n'ont pas
cessé de souffler pendant quinze jours, on retrouve encore de la
glace sur le bord de la mer, quand les vents nord et nord-ouest ont
soufflé seulement pendant vingt-quatre heures, sans même être
violents: ce qui semble indiquer que l'origine de cette glace ne peut
être fort éloignée, et que le froid doit provenir d'une grande île ou
d'un continent, et de la mer Glaciale. Cette dernière conjecture
paraît confirmée par les navigations que les Russes ont poussées à
plusieurs reprises jusqu'au 78e degré de latitude septentrionale,
point d'où les vaisseaux ne pouvaient pas pénétrer plus loin à cause
des glaces.
Si la mer dégèle tard, elle gèle de bonne heure. Vers la fin du mois
d'août, on n'est plus sûr de ne pas trouver la mer glacée. Il ne faut,
avec le calme, qu'un froid ordinaire pour qu'elle soit couverte de
glace en un quart d'heure; mais quand elle est gelée de si bonne
heure, il n'est pas sûr non plus qu'elle reste en cet état jusqu'à
l'hiver. Quoi qu'il en soit, il est certain que la mer ne gèle jamais plus
tard que le premier octobre, et qu'ordinairement elle gèle plus tôt.
Il pleut rarement dans le printemps à Ieniseisk; et pendant l'été le
ciel y est presque toujours serein. Le tonnerre y est fort rare, et l'on
n'y connaît point du tout les éclairs. En automne, il y a des
brouillards continuels, et les murs suintent sans cesse dans les
maisons et dans les cabanes; en hiver, il y a de fréquentes tempêtes.
Depuis le commencement d'octobre jusque vers la fin de décembre,
on voit beaucoup d'aurores boréales, mais qui sont de deux espèces.
Dans l'une, il paraît entre le nord-ouest et l'ouest un arc lumineux
d'où s'élèvent, à une hauteur moyenne, quantité de colonnes
lumineuses; ces colonnes s'étendent vers différents points du ciel,
qui est tout noir au-dessous de l'arc, quoiqu'on aperçoive
quelquefois les étoiles au travers de cette obscurité. Dans l'autre
espèce, il paraît d'abord au nord et au nord-est quelques colonnes
lumineuses qui s'agrandissent peu à peu, et occupent un grand
espace de ciel; ces colonnes s'élancent avec beaucoup de rapidité, et
couvrent enfin tout le ciel jusqu'au zénith, où les rayons viennent se
réunir. C'est comme un vaste pavillon brillant d'or, de rubis et de
saphirs, déployé dans toute l'étendue du ciel. On ne saurait imaginer
un plus beau spectacle; mais quand on voit pour la première fois
cette aurore boréale, on ne peut la regarder sans effroi, parce qu'elle
est accompagnée d'un bruit semblable à celui d'un grand feu
d'artifice. Les animaux mêmes en sont, dit-on, effrayés. Les
chasseurs qui sont à la quête des renards blancs et bleus des
cantons voisins de la mer Glaciale, sont souvent surpris par ces
aurores boréales. Leurs chiens en sont épouvantés, refusent d'aller
plus loin, et restent couchés à terre en tremblant, jusqu'à ce que le
bruit ait cessé; cependant ces effrayants météores sont
ordinairement suivis d'un temps fort serein.
On n'avait depuis longtemps aucune nouvelle du professeur De la
Croyère: les trois professeurs, depuis leur séparation, avaient
presque toujours suivi des directions opposées qui les éloignaient de
plus en plus les uns des autres. On reçut enfin de lui une lettre qui
marquait que vers la fin d'août 1737, il était parti par eau de
Yakoutsk, et qu'il avait eu le bonheur d'atteindre Simowic, située à
plus de douze cents werstes au-dessous de Yakoutsk. Il semblait,
disait-il, que le ciel et la terre fussent conjurés contre lui; qu'ils
eussent suscité tous les éléments pour traverser de toutes les façons
imaginables les entreprises qu'il avait formées dans l'intérêt de la
science, au péril de sa vie. Le ciel avait été presque continuellement
couvert de nuages, et le grand froid avait gâté tous ses instruments
météorologiques; en sorte qu'il ne lui restait plus aucun de ses
meilleurs thermomètres, parce qu'il les avait tous emportés avec lui,
pour n'en pas manquer dans les lieux où il comptait pouvoir
surprendre le froid, pour ainsi dire, à sa source. Il ajoutait que,
voulant savoir jusqu'à quelle profondeur la terre était gelée sous ce
rigoureux climat, il s'était servi de la houe; mais que la terre, pour
éluder ses recherches, avait pris la dureté du marbre; qu'elle ne
s'était laissé pénétrer en aucun endroit, et que les plus forts
instruments de fer s'étaient brisés sous les efforts redoublés des plus
robustes travailleurs; qu'il n'avait pas trouvé l'eau plus docile qu'au
commencement de février. Ayant fait creuser la glace jusqu'à l'eau
courante, pour voir si l'eau dans ces cantons, sans perdre sa fluidité,
était susceptible d'un plus fort degré de froid que dans les pays où la
congélation est au trente-deuxième degré Fahrenheit (quinze degrés
centigrades), il avait suspendu dans ce trou le seul thermomètre qui
lui restait, et que dix à douze minutes après, tout au plus, le
thermomètre était engagé dans trois pouces dix lignes de glace, et si
fortement pris, qu'avec toutes les précautions qu'il mit en usage
pour le détacher de ce ciment glacial, il n'avait pu l'en retirer que par
pièces; que le froid alors était si vif, qu'il ne pouvait tenir sa main
l'espace de dix minutes au grand air sans risquer de l'avoir gelée;
que pendant tout le temps qu'il avait séjourné dans ce canton-là, les
vents avaient soufflé entre nord-ouest et nord-nord-est; qu'on ne
voyait ni ciel ni terre, lorsque le vent venait tout à coup à changer de
direction, et qu'il amenait souvent une si forte poussière de neige,
qu'en la voyant on aurait dit que tout l'air était converti en neige;
que le feu même, dont on pouvait espérer au moins des services, lui
avait quelquefois refusé les secours qu'il en attendait, et qu'il avait
eu souvent les doigts gelés près d'un grand feu; qu'enfin l'air, dans
ces climats glacés, avait été pendant son séjour d'une si mauvaise
qualité, qu'environ la moitié des habitants, quoique indigènes,
avaient péri par des maladies épidémiques.
Après beaucoup de recherches sur la chasse des rennes et sur celle
des renards blancs et bleus, le docteur Gmelin rapporte, sur la foi
des chasseurs, qu'ils s'éloignent souvent de leurs habitations à la
distance de quarante, de cinquante et de cent werstes, pourvu qu'ils
aient quelque espérance de réussir. Ainsi ces sortes de chasses sont
de vrais voyages. Dans l'hiver, où elles sont les plus fréquentes, il
s'élève quelquefois des tempêtes si furieuses, qu'on ne voit pas
devant soi la moindre trace de chemin, et qu'on est forcé de rester
dans l'endroit où l'on se trouve jusqu'à ce que l'ouragan soit passé.
Comme chaque chasseur est pourvu d'une petite tente qu'il porte
partout, pour lui et pour son chien, il la dresse alors et se met à
couvert des injures du temps. Aucun ne s'expose dans ces longues
courses sans avoir des vivres pour quelques jours; et quand la
tempête dure trop longtemps, ils diminuent chaque jour quelque
chose de leur portion pour en prolonger la durée. Ces chasseurs sont
aussi munis chacun d'une boussole, pour pouvoir retrouver leur
chemin quand les ouragans en ont effacé les traces. Quand les
neiges accumulées rendent les chemins impraticables, ils ont une
sorte de chaussure avec laquelle ils glissent sur la neige sans y
enfoncer. La boussole vue par le docteur Gmelin était en bois, et
l'aiguille aimantée marquait assez bien: elle indiquait huit vents
principaux qui avaient chacun leur nom. Les autres vents y étaient
marqués, sans être désignés nommément; les vents intermédiaires
étaient distingués par des lignes ou des points.
A Mangaséa, sur un bras du Iénisée, le soleil était fort chaud, et dès
le 14 juin il n'y avait plus aucune trace de neige, ni dans les rues, ni
dans les champs. L'herbe poussait à vue d'œil. Le 15, on vit fleurir
des violettes jaunes qui ne viennent guère que sur les montagnes de
la Suisse et sur quelques autres aussi élevées. Ici, ces violettes
croissaient en quantité sur un terrain bas entre les buissons. L'herbe,
à la fin du mois de juin, avait un pied, et dans quelques endroits
jusqu'à un pied et demi de hauteur. Depuis le 11, on ne voyait pas
beaucoup de différence entre le jour et la nuit pour la clarté. On
lisait à près de minuit la plus fine écriture, presque aussi bien qu'on
l'aurait lue à midi, par un temps couvert, dans les pays plus
méridionaux. Pendant toute la nuit, le soleil était visible au-dessus
de l'horizon. Vers minuit, à la vérité, lorsqu'on était dans un endroit
bas, on avait de la peine à voir entièrement le disque du soleil; mais
en montant sur la tour, qui n'était pas même fort haute, on le voyait
distinctement tout entier. On pouvait hardiment regarder cet astre
sans en être ébloui: les rayons ne commençaient à se rendre bien
sensibles qu'à plus de minuit passé. Toute la troupe des voyageurs
ne put s'empêcher de célébrer ce magnifique spectacle, qu'aucun
d'entre eux n'avait vu, et que, selon toutes les apparences, ils ne
devaient jamais revoir. On se mit à table dans la rue, le visage
tourné au nord; tout le monde regardait le soleil, sans en détourner
un instant les yeux, et changeait de position à mesure que cet astre
avançait. On jouit de ce rare spectacle jusqu'au moment où les
rayons du soleil, qui prenait insensiblement de la force, devenus trop
vifs, ne pouvaient plus qu'incommoder.
Le docteur Gmelin visita la grande montagne d'aimant dans le pays
des Baskirs. C'est, à proprement parler, une chaîne de montagnes
qui s'étend du nord au sud, à la longueur d'environ trois werstes, et
qui, du côté occidental, est divisée par huit vallons de différentes
profondeurs, qui la coupent en autant de parties séparées. Du côté
oriental est un steppe assez ouvert, dont la partie occidentale est
éloignée d'environ cinq à six werstes du Jaïk; du même côté, et au
pied de la montagne, passe encore un ruisseau sans nom qui, à
deux werstes au-dessous, va se jeter dans le Jaïk. La septième
partie ou section de la montagne, à compter de l'extrémité
septentrionale, est la plus haute de toutes, et sa hauteur
perpendiculaire peut être de quatre-vingts à quatre-vingt-dix
brasses. Celle-ci produit aussi le meilleur aimant, non pas au
sommet, qui est formé d'une pierre blanche tirant sur le jaune, et
participe d'une espèce de jaspe, mais à environ huit brasses au-
dessous. On voit là des pierres du poids de deux mille cinq cents à
trois mille livres, qu'on prendrait de loin pour des pierres de grès, et
qui ont toute la propriété de l'aimant. Quoiqu'elles soient couvertes
de mousses, elles ne laissent pas d'attirer le fer ou l'acier à la
distance de plus d'un pouce. Les faces exposées à l'air ont la plus
forte action magnétique; ceux qui sont enfoncés en terre en ont
beaucoup moins. D'un autre côté, les parties les plus exposées à l'air
et aux vicissitudes du temps sont moins dures, et par conséquent
moins propres à être armées. Une pierre d'aimant de la grandeur
qu'on vient de décrire est composée de quantité de petits aimants,
qui opèrent en différentes directions. Pour les bien travailler, il
faudrait les séparer à la scie, afin que le bloc qui renferme la vertu
de chaque aimant particulier demeurât tout entier; on obtiendrait
vraisemblablement de cette façon des aimants d'une grande
puissance. On taille ici des morceaux au hasard, et il s'en trouve
plusieurs qui ne valent rien du tout, soit parce qu'on abat un
morceau de pierre qui n'a point de vertu magnétique ou qui n'en
renferme qu'une petite parcelle, soit parce que dans un seul
morceau il se trouve deux ou trois aimants réunis. A la vérité, ces
morceaux ont une vertu magnétique; mais comme elle ne converge
pas vers un même point, il n'est pas étonnant que l'effet d'un pareil
aimant soit sujet à bien des variations.
L'aimant de cette montagne, à l'exception de celui qui est exposé à
l'air, est d'une grande dureté, tacheté de noir, et rempli de
tubérosités qui ont de petites parties anguleuses, comme on en voit
souvent à la surface de la pierre sanguine, dont il ne diffère que par
la couleur; mais souvent, au lieu de ces parties anguleuses, on ne
voit qu'une espèce de terre d'ocre. En général les aimants qui ont
ces petites parties anguleuses ont moins de vertu que les autres. La
portion de la montagne où sont les aimants est presque entièrement
composée d'une bonne mine d'acier, qu'on tire par petits morceaux
entre les pierres d'aimant. Toute la section de la montagne la plus
élevée renferme une pareille mine; mais plus elle s'abaisse, moins
elle contient de métal. Plus bas, au-dessous de la montagne
d'aimant, il y a d'autres pierres ferrugineuses, mais qui rendraient
fort peu de fer si l'on voulait les faire fondre. Les morceaux qu'on en
tire ont la couleur du métal, et sont très-lourds. Ils sont inégaux en
dedans, et ont presque l'air de scories, si ce n'est qu'on y trouve
beaucoup de ces parties anguleuses. Ces morceaux ressemblent
assez, à l'extérieur, aux pierres d'aimant; mais ceux qu'on tire à huit
brasses au-dessous du roc n'ont plus aucune vertu. Entre ces
pierres, on trouve d'autres morceaux de roc qui paraissent composés
de très-petites parcelles de fer, dont ils montrent en effet la couleur.
La pierre par elle-même est pesante à la vérité, mais fort molle; les
parcelles, intérieurement, sont comme si elles étaient brûlées, et
elles n'ont que peu ou point de vertu magnétique. On trouve aussi
de loin à loin un minerai brun de fer dans des couches épaisses d'un
pouce, mais il rend peu de métal. La section la plus méridionale, ou
la huitième partie de la montagne, ressemble en tout à la septième,
si ce n'est qu'elle est plus basse. Les aimants de cette dernière
section n'ont pas été trouvés d'une aussi bonne qualité. Toute la
montagne est couverte de plantes et d'herbes, qui sont presque
partout assez hautes. On voit aussi par intervalles, à mi-côte et dans
les vallées, de petits bosquets de bouleaux. Cette montagne, au
reste, outre cet aimant, n'offre qu'un roc ordinaire; seulement en
certains endroits on y rencontre de la pierre à chaux.
(Suivent d'autres détails du voyage, qui n'offrent pas assez d'intérêt
pour être relatés.)
CHAPITRE II

PÉNINSULE DU KAMTCHATKA,
EXPLORÉE DANS LES ANNÉES 1770-1771, PAR LE COMTE
BENIOWSKI.
Voici une description abrégée de cette péninsule d'après les
Mémoires du comte Maurice-Auguste Beniowski, dont nous avons
publié séparément la vie et les aventures.

CONSTITUTION PHYSIQUE DU PAYS

La péninsule de Kamtchatka forme l'extrémité du nord-est de l'Asie;


sa côte occidentale est très-sinueuse, forme différents ports et est
coupée par plusieurs rivières, dont la plus considérable est celle de
Bolsha. Les vaisseaux d'Okhotsk entrent dans cette rivière, ce qu'ils
ne peuvent faire cependant avec sûreté que dans le temps des
marées du printemps, qui montent alors jusqu'à dix pieds. Il est
difficile de remonter cette rivière, à cause de la rapidité du courant
et du grand nombre d'îles qu'elle contient.
Le Kamtchatka, en ouvrant asile à nos navigateurs pendant l'hiver,
les engage à tenter de nouvelles découvertes. A présent ce n'est
qu'un rendez-vous et un entrepôt pour l'échange des riches
fourrures que les chasseurs apportent des îles Kouriles et
Aléoutiennes; mais si l'on jugeait à propos d'établir des colonies
dans ces îles, et d'entretenir un commerce avec la Chine, le Japon, la
Corée, etc., le Kamtchatka deviendrait une source de richesse et de
prospérité pour la Russie.
Cette presqu'île peut servir aussi à établir une communication entre
les deux continents de l'Asie et de l'Amérique. Le seul port commode
sur la côte orientale est la baie d'Avatcha, nommée Racova. Le
gouverneur du Kamtchatka a bâti un fort régulier capable d'en
défendre l'entrée.
Les habitants de la zone torride voient dans le soleil la source du
feu; mais les nations septentrionales la trouvent dans les volcans. Il
y en a plus de vingt dans la presqu'île du Kamtchatka; les plus
célèbres sont à Avatcha, Tolbachz, et près de la rivière de
Kamerolteira. Les mêmes principes qui ont dont donné naissance
aux volcans, ont produit un grand nombre de sources chaudes qui
ont la vertu des eaux minérales. L'eau qui coule de ces sources est
couverte d'une écume noire.
Toutes les tentatives faites pour la production du grain ont été sans
succès, excepté dans des terrains préparés par des engrais. Quoiqu'il
y croisse naturellement assez de bois pour la construction des
huttes, il n'y en a point de propre à la construction des vaisseaux.
On trouva dans toute l'étendue de la province cinq vaches, deux
taureaux, qui étaient nourris avec de l'écorce de bouleau neuf mois
de l'année, car il n'y a de verdure que du mois de juillet au mois de
septembre.
Le climat et la température du Kamtchatka ne sont pas non plus
aussi doux que plusieurs écrivains l'ont prétendu. Un brouillard
continuel, qui couvre tout le pays, produit des affections
scorbutiques et d'autres maladies qui nuisent à la population. La
rigueur du froid est telle, que durant le dernier hiver (1769), on a
trouvé plusieurs soldats gelés dans leurs postes. Le long séjour de la
neige occasionne la cécité, de sorte que les naturels ne passent
guère quarante ans sans devenir aveugles.

PRODUCTIONS
Le Kamtchatka produit des métaux. Près d'Avatcha il y a des mines
d'or, et près de Girova des mines de cuivre. Les montagnes
fournissent du cristal de roche, dont quelques échantillons sont verts
et rouges; les naturels s'en servent pour faire des pointes à leurs
javelines. Les seules espèces d'arbres qui croissent au Kamtchatka
sont une sorte de sapin bâtard, des cèdres, des saules et des
bouleaux; le cèdre porte une graine que les habitants aiment
beaucoup; l'écorce des saules et des bouleaux leur tient lieu de pain.
La seule plante utile est le sarana, qui fleurit et donne du fruit au
mois d'août. Les Kamtchadales en font de grandes provisions, et en
forment avec leur caviar une certaine pâte qu'ils trouvent délicieuse,
mais qui, pour d'autres, n'empêcherait pas de mourir de faim. Outre
le sarana, le gouvernement a fait ramasser une plante nommée
vinoroya, d'où l'on extrait une sorte d'eau-de-vie qui produit un
faible revenu; mais l'usage en est dangereux, car cette plante est un
poison des plus actifs.

ANIMAUX

Le Kamtchatka ne brille pas beaucoup du côté du règne animal. Le


premier rang est dû aux chiens, qui tiennent lieu de chevaux de trait,
et dont la peau, après leur mort, sert de vêtements. Les chiens du
Kamtchatka sont grands, forts, laborieux; on les nourrit avec de
l'opana, composition faite de vieux poisson et d'écorce de bouleau;
mais plus communément ils sont obligés de chercher eux-mêmes
leur nourriture, c'est-à-dire quelques poissons, qu'ils trouvent dans
les rivières produites par les sources chaudes.
Le renard vient après le chien. Sa peau est du plus beau lustre, et
dans la Sibérie il n'y a point de fourrure qui puisse soutenir la
comparaison avec la peau de renard du Kamtchatka.
Le bélier de ce pays est un excellent manger; sa peau est d'un très-
grand prix, et ses cornes sont aussi un objet de commerce; mais
dans ces dernières années le nombre en a beaucoup diminué.
La martre zibeline est très-commune au Kamtchatka; les naturels
sont constamment à la chasse de cet animal, ainsi que les étrangers.
Le nombre des martres apportées l'année dernière (1770) du
Kamtchatka au marché se montait à six mille huit cents. La fourrure
de la marmotte est très-chaude et très-légère.
Les ours sont très-nombreux; leur humeur est assez pacifique, et
jamais ils ne font de mal que pour leur propre défense. Les
chasseurs sont obligés de chasser l'ours pour leur subsistance;
souvent ils reviennent déchirés; mais l'ours tue rarement: il semble
que cet animal épargne la vie de son ennemi, quand celui-ci n'est
plus à craindre. Il n'y a point d'exemple qu'il ait blessé une femme.
Ces animaux sont gras en été, et maigres en hiver.
Le manate ressemble à la vache par la tête. Les femelles ont deux
mamelles, et tiennent leurs petits contre leur sein. Les Français ont
appelé cet animal lamentin, à cause de son cri. Sa peau est noire et
rude, épaisse comme l'écorce d'un chêne, et capable de résister au
tranchant de la hache. Ses dents sont préférées à l'ivoire. Le
Kamtchatka en produit annuellement de deux cent cinquante à trois
cents livres. La chair ressemble à celle du bœuf parvenu à son
entière croissance, et, quand le lamentin est jeune, à celle du veau.
On trouve ici des castors. La peau de cet animal est aussi douce que
le duvet; ses dents sont petites et bien affilées; sa queue, courte,
plate et large, se termine en pointe. On le prend à la ligne, et
quelquefois on le tire sous la glace.
Le lion de mer est de la taille d'un bœuf; son cri est épouvantable;
mais, heureusement pour les navigateurs, c'est un des signes qui
annoncent le voisinage de la terre, pendant les brouillards si
communs en ce pays. Cet animal est timide; on le harponne, ou bien
on le tire à coups de fusils ou de flèches.
Le veau marin se trouve en grande quantité près de toutes les îles et
de tous les promontoires; il ne s'éloigne jamais de la côte, mais il
remonte l'embouchure des rivières pour dévorer le poisson. On se

You might also like