-
Notifications
You must be signed in to change notification settings - Fork 120
Application and File Structure
The main application is defined in config/application.coffee
and defaults to this:
class App extends Tower.Application
@configure ->
@use "favicon", Tower.publicPath + "/favicon.ico"
@use "static", Tower.publicPath, maxAge: Tower.publicCacheDuration
@use "profiler" if Tower.env != "production"
@use "logger"
@use "query"
@use "cookieParser", Tower.session.secret
@use "session", Tower.session.key
@use "bodyParser"
@use "csrf"
@use "methodOverride", "_method"
@use Tower.Middleware.Agent
@use Tower.Middleware.Location
@use Tower.Middleware.Router
The configure
function is used to configure the application.
-
favicon
points to the icon file displayed in the browser address bar. -
static
is used to set where public (static) files reside and define their cache duration on the client. -
profiler
is by default configured to only used only when the app is not in production mode (environment).
You can of course extend the configure function with your own application configuration logic as needed.
The client application is defined exactly like the server application, they just tend to require different middleware and slightly different configuration.
Internally Tower.js knows when a file was changed. So when you refresh http://localhost:3000, it passes through the Tower.Middleware.Dependencies
which re-requires any file that has changed. This makes development uber fast, and prevents you from having to restart the server whenever a file changes (i.e. nodemon). I mean, you can use nodemon if you want, it's a great project. But you don't need to.
Tower by default comes with the following environments:
- development
- test
- production
Additional environments can be defined if needed (such as staging).
# config/locales/en.coffee
module.exports =
hello: "world"
forms:
titles:
signup: "Signup"
pages:
titles:
home: "Welcome to %{site}"
posts:
comments:
none: "No comments"
one: "1 comment"
other: "%{count} comments"
messages:
past:
none: "You never had any messages"
one: "You had 1 message"
other: "You had %{count} messages"
present:
one: "You have 1 message"
future:
one: "You might have 1 message"
Tower also has some more internal locale files for system generated text such as dates and times etc. You can provide your own locale files for these as well (see the Tower src code and look for /locale folders).
The package.json
file is standard to all Node.js modules using NPM (which implements the CommonJS package format specification).
Without going into too much detail, here's what you need to know about each.
The package.json
file is a JSON description of your project. This is the default package.json
for a generated Tower.js app:
{
"name": "my-app",
"version": "0.0.1",
"description": "Some one-liner description of your project.",
"homepage": "http://github.com/username/my-app",
"main": "./server.js",
"author": "Your Name <your@email.com>",
"keywords": [
"node"
],
"maintainers": [{
"name": "Your Name",
"email": "your@email.com"
}],
"contributors": [
],
"licenses": [
{
"type": "MIT",
"url": "http://mths.be/mit"
}
],
"bugs": {
"url": "http://github.com/username/my-app/issues"
},
"repository": {
"type": "git",
"url": "http://github.com/username/my-app.git"
},
"engines": {
"node": ">= 0.4.0"
},
"dependencies": {
"tower": ">= 0.3.0"
},
"devDependencies": {
"coffee-script": ">= 1.1.3",
"stylus": ">= 0.17.0",
"uglify-js": ">= 1.1.1",
"design.io": ">= 0.1.0"
}
}
For all node modules that you'll need in both development and production environments, put them into dependencies
. Anything that you just need for development (like uglify-js
for javascript compression), put that into devDependencies
.
To install just production dependencies, run this command from your project root:
npm install --production
You can also do this by setting NODE_ENV
to production
.
To install both dependencies
and devDependencies
, run this command:
npm install
Note: When you push your app to Heroku, it's compiled to a "slug". This makes it easy to clone and scale your app. The ideal is to minimize the size of that slug so it's faster to clone. The two biggest ways to do this are 1) minimize the number of images/pdfs/assets in your project (put them on S3 or something), and 2) minimize the number of modules you use in production. So if you only need gzipping to compile your assets for production, put that into your devDependencies
.
Most of you are probably familiar with NPM, but here's just a quick list of helpful commands to streamline your development workflow.
More on NPM here: http://npmjs.org/doc.
The first thing to do when you create a Tower project (or you git clone
any node module from GitHub) is to cd
into the project root and install the dependencies:
npm install
You can install a published npm module like this:
npm install coffee-script jade stylus
You can also install local modules:
npm install /Users/username/git/node/my-module
But when you're developing a module locally, it's a pain to constantly have to remove and reinstall it into the app that's using it. That's where npm link
comes in.
The npm link
command creates a symlink to a local node module that links it to the global npm module directory on your hard drive. First step is to link my-module
to the global directory:
$ cd /Users/username/git/node/my-module
$ npm link
/usr/local/lib/node_modules/my-module -> /Users/username/git/node/my-module
Then in any local project that's using it, run:
$ npm link my-module
./node_modules/my-module -> /usr/local/lib/node_modules/my-module -> /Users/username/git/node/my-module
I love npm link
, it makes development so much easier.
To publish a module to the npm index, run:
npm publish
Sometimes you want to run some code before/after your module is installed. Do this by defining npm scripts
in your package.json
(http://npmjs.org/doc/scripts.html).
Here's a package.json
that installs a RubyGem after the node module is installed:
{
...
"scripts": {
"install": "gem install nokogiri"
}
}
Run custom scripts like this:
npm run-script docs
Tower uses grunt's Gruntfile
to:
- Automatically compile assets when they are added, saved, or removed. See the Tower Asset Pipeline
- Automatically restart the server in development mode when you modify a file
- Push compiled CSS and JavaScripts to the browser as you're developing without refreshing the browser!
- Automatically run tests across browsers, platforms, and devices as your developing.
- Give you space to add more
watch
tasks to streamline workflow
.
|-- app
| |-- client
| | |-- stylesheets
| |-- controllers
| | |-- admin
| | | |-- postsController.coffee
| | | `-- usersController.coffee
| | |-- commentsController.coffee
| | |-- postsController.coffee
| | |-- sessionsController.coffee
| | `-- usersController.coffee
| |-- models
| | |-- comment.coffee
| | |-- post.coffee
| | `-- user.coffee
| |-- views
| | |-- admin
| | | `-- posts
| | | |-- _form.coffee
| | | |-- edit.coffee
| | | |-- index.coffee
| | | |-- new.coffee
| | | |-- show.coffee
| | |-- layouts
| | | `-- application.coffee
| | |-- shared
| | `-- posts
| | |-- index.coffee
| | `-- show.coffee
| `-- helpers
| |-- admin
| | |-- postsHelper.coffee
| | `-- usersHelper.coffee
| `-- postsHelper.coffee
`-- config
| |-- application.coffee
| |-- assets.coffee
| |-- bootstrap.coffee
| |-- databases.coffee
| |-- preinitializers
| |-- initializers
| |-- environments
| |-- development.coffee
| |-- production.coffee
| `-- test.coffee
| |-- locale
| `-- en.coffee
| |-- routes.coffee
`-- test
| |-- config.coffee
| |-- models
| | |-- postTest.coffee
| | |-- userTest.coffee
| `-- acceptance
| |-- loginTest.coffee
| |-- signupTest.coffee
| `-- postsTest.coffee
Dotfiles are for the most part just hidden files that different platforms use to store configuration data about your project.
In Tower.js, there's 3 by default:
-
.gitignore
Tells git the files and directories it should ignore. -
.npmignore
Tells npm what to ignore when your module is published. -
.slugignore
Tells Heroku what to ignore about your project.