UNPKG

8.8 kBMarkdownView Raw
1# moonboots
2
3A set of conventions and tools for building, bundling and serving single page apps with node.js and express.js.
4
5The bulk of the awesome bundling of CommonJS modules for client use is done using [browserify](http://browserify.org/).
6
7This just gives us a structured way to include non-CommonJS libraries, work in development mode and agressively cache built JS and CSS files for production.
8
9
10## What it does
11
121. Saves us from re-inventing this process for each app.
131. Let's a developer focus on building a great clientside experience, not boiler plate.
141. Let's you use CommonJS modules to structure your clientside code.
151. Manages clientside files during development so you can just write code.
161. Compiles/minifies/serves uniquely named JS files (and CSS files optionally) containing your application with really aggressive caching (since the name will change if the app does).
171. Plays nicely with [express.js](http://expressjs.com)
18
19
20## Why?
21
221. Because single page apps are different. You're shipping an application to be run on the browser instead of running an application to ship a view to the browser.
231. Engineering a good client-side app requires a good set of conventions and structure for organizing your code.
241. Effeciently building/sending a client-side app to the browser is a tricky problem. It's easy to build convoluted solutions. We want something a bit simpler to use.
25
26
27## How to use it
28
29You grab your moonboots and pass it a config. Then tell express which urls to serve your single page app at.
30
31That's it.
32
33```js
34var express = require('express'),
35 Moonboots = require('./index.js'),
36 app = express();
37
38// configure our app
39var clientApp = new Moonboots({
40 main: __dirname + '/sample/app/app.js',
41 developmentMode: false,
42 libraries: [
43 __dirname + '/sample/libraries/jquery.js'
44 ],
45 stylesheets: [
46 __dirname + '/styles.css'
47 ],
48 server: app
49});
50
51// if we want to prime the user's cache with the
52// application files. The login page is a great place
53// to do this. We can retrieve the name of the
54// JS file for the current app, by calling module's
55// jsFileName() function.
56app.get('/login', function (req, res) {
57 // then in our login page we can lazy load the application to
58 // prime the user's cache while they're typing in their username/password
59 res.render('login', {appFileName: clientApp.jsFileName()});
60});
61
62// We also just need to specify the routes at which we want to serve this clientside app.
63// This is important for supporting "deep linking" into a single page app. The server
64// has to know what urls to let the browser app handle.
65app.get('*', clientApp.html());
66
67// start listening for http requests
68app.listen(3000);
69
70
71```
72
73
74## Options
75
76Available options that can be passed to Moonboots:
77
78- `main` (required, filepath) - The main entry point of your client app. Browserify uses this build out your dependency tree.
79- `server` (optional, connect or express app, default: null) - Highly recommend using this. This way moonboots worries about serving your JS for you in the appropriate format given your other settings.
80`developmentMode` (optional, boolean, default: false) - In development mode the JS is recompiled each time it's requested by the browser and it's not minified. Very important this isn't left this way for production.
81- `libraries` (optional, array of file paths, default: []) - An array of paths of JS files to concatenate and include before any CommonJS bundled code. This is useful for stuff like jQuery and jQuery plugins. Note that they will be included in the order specified. So if you're including a jQuery plugin, you'd better be sure that jQuery is listed first.
82- `stylesheets` (optional, array of file paths, default: []) - An array of CSS files to concatenate
83- `jsFileName` (optional, string, default: app) - the name of the JS file that will be built
84- `cssFileName` (optional, string, default: styles) - the name of the CSS file that will be built
85- `templateFile` (optinal, filepath, default: bundled template): __dirname + '/sample/app.html',
86- `cachePeriod` (optional, miliseconds to cache JS file, default: one year in MS)
87- `browerify` (optional, object, default: {}) - options to pass directly into browserify's `bundle` methods, as detailed [here](https://github.com/substack/node-browserify#bbundleopts-cb). Additional options are:
88 - `browserify.transforms` (optional, list, default: []) - list of transforms to apply to the browserify bundle, see [here](https://github.com/substack/node-browserify#btransformtr) for more details.
89- `modulesDir` (optional, directory path, default: '') - directory path of modules to be directly requirable (without using relative require paths). For example if you've got some helper modules that are not on npm but you still want to be able to require directly by name, you can include them here. So you can, for example, put a modified version of backbone in here and still just `require('backbone')`.
90- `beforeBuildJS` (optional, function, default: nothing) - function to run before building the browserify bundle during development. This is useful for stuff like compiling clientside templates that need to be included in the bundle. If you specify a callback moonboots will wait for you to call it. If not, it will be run synchrnously (by the magic of Function.prototype.length).
91- `beforeBuildCSS` (optional, function, default: nothing) - function to run before concatenating your CSS files during development. This is useful for stuff like generating your CSS files from a preprocessor. If you specify a callback moonboots will wait for you to call it. If not, it will be run synchrnously (by the magic of Function.prototype.length).
92- `sourceMaps` (optional, boolean, default: false) - set to true to enable sourcemaps (will only work if developmentMode is also true).
93- `resourcePrefix` (optional, string, default: '/') - specify what dirname should be prefixed when generating template file. If you're serving the whole app statically you may need relative paths. So just passing resourcePrefix: '' would make the template render with `<script src="app.js"></script>` instead of `<script src="/app.js"></script>`.
94- `minify` (optional, boolean, default: true) An option for whether to minify JS and CSS when not in `developmentMode`.
95
96## About Source Maps
97
98Sourcemaps let you send the actual code to the browser along with a mapping to the individual module files. This makes it easier to debug, since you can get relevant line numbers that correspond to your actual source within your modules instead of the built bundle source.
99
100## Methods
101
102**moonboots.html()** - returns connect request handler that will server the appropriate HTML file with the correct JS file name based on current settings.
103
104**moonboots.js()** - returns connect-compatible request handler that serves the JS file based on settings. If you use the `server` option, this will just be done for you. But you can also do it yourself using this method.
105
106**moonboots.css()** - returns connect-compatible request handler that serves the CSS file based on settings. If you use the `server` option, this will just be done for you. But you can also do it yourself using this method.
107
108**moonboots.jsFileName()** - returns string of the current js filename based on current config. Useful if you want to render your own base html template or if you want to know what the filename is to prime someone's cache while on a login page, etc.
109
110**moonboots.cssFileName()** - returns string of the current css filename based on current config. Useful if you want to render your own base html template or if you want to know what the filename is to prime someone's cache while on a login page, etc.
111
112**moonboots.sourceCode(cb(err, source))** - returns acutal JS source code. Useful if you're using moonboots in dev, but want to put output file somewhere else, for example on a CDN as part of a build process.
113
114**moonboots.cssSource(cb(err, source))** - returns acutal CSS. Useful if you're using moonboots in dev, but want to put output file somewhere else, for example on a CDN as part of a build process.
115
116**moonboots.build(directory, cb)** - builds your `index.html` file and a `.js` and `.css` files to the folder specified.
117
118**moonboots.getTemplate()** - returns a string of the template file with js and css file names replaced
119
120
121## Full example
122
123For a working example, run `node server.js` file and it'll server the `sample` directory.
124
125## Changelog
126
127**1.2.3**
128
129 - Make bundles have a consistent hash
130
131**1.0.0**
132
133 - Make CSS build/prepare steps follow same as JS
134 - Async css methods
135
136**0.7.0**
137
138 - Support for browserify transforms (thanks @latentflip)
139 - Write syntax errors to browser in dev mode (thanks @lukekarrys)
140
141## License
142
143MIT