From 44b7972559b7111e5e4b1660d4aff65bb48f3480 Mon Sep 17 00:00:00 2001 From: "W. Trevor King" Date: Thu, 19 Sep 2013 17:20:18 -0700 Subject: [PATCH] posts:node: Add a post on Node and npm --- posts/Node.mdwn | 175 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 175 insertions(+) create mode 100644 posts/Node.mdwn diff --git a/posts/Node.mdwn b/posts/Node.mdwn new file mode 100644 index 0000000..5f719c0 --- /dev/null +++ b/posts/Node.mdwn @@ -0,0 +1,175 @@ +[Node][] is a server-side [JavaScript][] engine (i.e. it executes +JavaScript without using a browser). This means that JavaScript +developers can now develop tools in their native language, so it's not +a surprise that the [Bootstrap][] folks use [Grunt][] for their build +system. I'm new to the whole Node ecosystem, so here are my notes on +how it works. + +Start off by installing [npm][], the Node package manager. On Gentoo, +that's: + + # USE=npm emerge -av net-libs/nodejs + +[Configure npm][npm-config] to make ["global" +installs][npm-folders-prefix] in your personal space: + + # npm config set prefix ~/.local/ + +Install the [Grunt][] command line interface for building +[Bootstrap][]: + + $ npm install -g grunt-cli + +That installs the libraries under `~/.local/lib/node_modules` and +drops symlinks to binaries in `~/.local/bin` (which is [already in my +`PATH`][PATH] thanks to my [[dotfiles]]). + +Clone Boostrap and [install it's +dependencies][bootstrap-dependencies]: + + $ git clone git://github.com/twbs/bootstrap.git + $ cd bootstrap + $ npm install + +This looks in the local [package.json][] to extract a list of +dependencies, and [installs each of them][npm-folders] under +[node_modules][]. Node likes to isolate its packages, so every +dependency for a given package is installed underneath that package. +This leads to some crazy nesting: + + $ find node_modules/ -name graceful-fs + node_modules/grunt/node_modules/glob/node_modules/graceful-fs + node_modules/grunt/node_modules/rimraf/node_modules/graceful-fs + node_modules/grunt-contrib-clean/node_modules/rimraf/node_modules/graceful-fs + node_modules/grunt-contrib-qunit/node_modules/grunt-lib-phantomjs/node_modules/phantomjs/node_modules/rimraf/node_modules/graceful-fs + node_modules/grunt-contrib-watch/node_modules/gaze/node_modules/globule/node_modules/glob/node_modules/graceful-fs + +Sometimes the redundancy is due to different version requirements, but +sometimes the redundancy is just redundant :p. Let's look with [npm +ls][npm-ls]. + + $ npm ls graceful-fs + bootstrap@3.0.0 /home/wking/src/bootstrap + ├─┬ grunt@0.4.1 + │ ├─┬ glob@3.1.21 + │ │ └── graceful-fs@1.2.3 + │ └─┬ rimraf@2.0.3 + │ └── graceful-fs@1.1.14 + ├─┬ grunt-contrib-clean@0.5.0 + │ └─┬ rimraf@2.2.2 + │ └── graceful-fs@2.0.1 + ├─┬ grunt-contrib-qunit@0.2.2 + │ └─┬ grunt-lib-phantomjs@0.3.1 + │ └─┬ phantomjs@1.9.2-1 + │ └─┬ rimraf@2.0.3 + │ └── graceful-fs@1.1.14 + └─┬ grunt-contrib-watch@0.5.3 + └─┬ gaze@0.4.1 + └─┬ globule@0.1.0 + └─┬ glob@3.1.21 + └── graceful-fs@1.2.3 + +Regardless of on-disk duplication, Node [caches modules][caching] so a +given module only loads once. If it really bothers you, you can +[avoid some duplicates by installing duplicated packages higher up in +the local tree][npm-folders-nesting]: + + $ rm -rf node_modules + $ npm install graceful-fs@1.1.14 + $ npm install + $ npm ls graceful-fs + bootstrap@3.0.0 /home/wking/src/bootstrap + ├── graceful-fs@1.1.14 extraneous + ├─┬ grunt@0.4.1 + │ └─┬ glob@3.1.21 + │ └── graceful-fs@1.2.3 + ├─┬ grunt-contrib-clean@0.5.0 + │ └─┬ rimraf@2.2.2 + │ └── graceful-fs@2.0.1 + └─┬ grunt-contrib-watch@0.5.3 + └─┬ gaze@0.4.1 + └─┬ globule@0.1.0 + └─┬ glob@3.1.21 + └── graceful-fs@1.2.3 + +This is probably not worth the trouble. + +Now that we have Grunt and the Bootstrap dependencies, we can build +the distributed libraries: + + $ ~/src/node_modules/.bin/grunt dist + Running "clean:dist" (clean) task + Cleaning dist...OK + + Running "recess:bootstrap" (recess) task + File "dist/css/bootstrap.css" created. + + Running "recess:min" (recess) task + File "dist/css/bootstrap.min.css" created. + Original: 121876 bytes. + Minified: 99741 bytes. + + Running "recess:theme" (recess) task + File "dist/css/bootstrap-theme.css" created. + + Running "recess:theme_min" (recess) task + File "dist/css/bootstrap-theme.min.css" created. + Original: 18956 bytes. + Minified: 17003 bytes. + + Running "copy:fonts" (copy) task + Copied 4 files + + Running "concat:bootstrap" (concat) task + File "dist/js/bootstrap.js" created. + + Running "uglify:bootstrap" (uglify) task + File "dist/js/bootstrap.min.js" created. + Original: 58543 bytes. + Minified: 27811 bytes. + + Done, without errors. + +Wohoo! + +Unfortunately, like all [language-specific][pypi] [packing][gem] +[systems][cpan], npm has trouble installing packages that aren't +written in its native language. This means you get things like: + + $ ~/src/node_modules/.bin/grunt + … + Running "jekyll:docs" (jekyll) task + `jekyll build` was initiated. + + Jekyll output: + Warning: Command failed: /bin/sh: jekyll: command not found + Use --force to continue. + + Aborted due to warnings. + +Once everybody wises up and starts writing packages for [[Gentoo +Prefix|Gentoo_Prefix_overlay]], we can stop worrying about +installation and get back to work developing :p. + +[[!tag tags/programming]] +[[!tag tags/tools]] +[[!tag tags/web]] + +[Node]: http://nodejs.org/ +[JavaScript]: http://en.wikipedia.org/wiki/JavaScript +[Bootstrap]: http://getbootstrap.com/ +[Grunt]: http://gruntjs.com/ +[npm]: https://npmjs.org/ +[npm-folders]: https://npmjs.org/doc/files/npm-folders.html +[npm-folders-prefix]: https://npmjs.org/doc/files/npm-folders.html#prefix-Configuration +[npm-folders-nesting]: https://npmjs.org/doc/files/npm-folders.html#Cycles-Conflicts-and-Folder-Parsimony +[npm-config]: https://npmjs.org/doc/config.html +[PATH]: http://git.tremily.us/?p=dotfiles-public.git;a=blob;f=src/.bash_profile;hb=HEAD +[bootstrap-dependencies]: https://github.com/twbs/bootstrap/blob/master/README.md#install-grunt +[package.json]: https://npmjs.org/doc/json.html +[node_modules]: http://nodejs.org/api/modules.html#modules_loading_from_node_modules_folders +[npm-ls]: https://npmjs.org/doc/cli/npm-ls.html +[caching]: http://nodejs.org/api/modules.html#modules_caching +[pypi]: https://pypi.python.org/pypi +[gem]: http://rubygems.org/ +[cpan]: http://www.cpan.org/ -- 2.26.2