Giter VIP home page Giter VIP logo

fatarrow's Introduction

fatarrow

###An AngularJS application Reference Architecture License Version Build Status Dependency Status

Build AngularJS applications with CoffeeScript - without the ceremony. By the way, you can write JavaScript too.

Table of Contents

Installing

Before running, you must install and configure the following one-time dependencies:

Enter the following in the terminal

Option 1: Using Yeoman Generator (Recommended)

$ npm install -g gulp yo
$ npm install -g generator-fatarrow
$ mkdir my-new-project && cd $_
$ yo fatarrow

Option 2: Clone this repo

$ npm install -g gulp
$ git clone [email protected]:CaryLandholt/fatarrow.git
$ cd fatarrow
$ npm install

Running

Here are some useful commands to get started:

Get all commands and options by typing

$ gulp help

Running with With a fake backend ($httpBackend)

$ gulp

With a real backend (gulp will proxy calls to the backend of your choice)

$ gulp --backend

Build for production

$ gulp --prod --no-serve

Run tests on your build server

$ npm test

Deploy your app

$ npm test
$ gulp --prod --no-serve
# deploy to a path (configuration in /config/locationConfig.coffee)
$ gulp deploy
# deploy to S3 (configurtion in /config/s3Config.coffee)
$ gulp deploy --target s3

Scripting

Your choice of scripting languages.

Styling

Your choice of styling languages.

Templating

Your choice of templating engines.

Structure

  • File extensions supported by fatarrow:
    • Scripts: .coffee, .js, .ls, .ts, .es6
    • Styles: .less, .css, .scss
    • Templates: .html, .haml, .jade

(Note: to keep the example succint, .coffee, .html and .less extensions are used below. However, all of the file extensions listed above can be used, and even can be mix-and-matched.)

The root directory generated for a fatarrow app:

├──  e2e/
├──  config/
├──  src/
│   ├──  components/
│   │   └──  comp/
│   │   │   ├──  test
│   │   │   ├──  └──  comp.spec.coffee
│   │   │   ├──  comp.coffee
│   │   │   └──  comp.html
│   │   │   └──  comp.backend.coffee
│   │   │   └──  comp.less
│   ├──  app/
│   │   ├──  app.coffee
│   │   ├──  appRoutes.coffee
│   │   └──  views.backend.coffee
│   ├──  home/
│   │   ├──  homeController.coffee
│   │   ├──  homeRoutes.coffee
│   │   └──  home.html
│   ├──  img/
│   │   └──  angularjs.jpg
│   └──  index.html
├──  tasks/
├──  bower_components/
├──  nodes_modules/
├──  .bowerrc
├──  .gitignore
├──  bower.json
├──  gulpfile.coffee
├──  package.json

Explanation of the folders:

  • src/app: Angular module for the app. All app level config should go here.
  • src/home: Each feature of the app should go in its own folder. It should contain all scripts, styles, templates and tests within the feature folder.
  • src/components: Reusable components (directives, factories, styles, etc.)
  • e2e: Protractor tests. They should also be separated by features/components.
  • config: Configurtion for gulp tasks broken up by each task.

Features

  • Fake data: Running gulp will include the .backend.coffee files and therefore Angular's $httpBackend will be utilized. This should be used for backendless development.
  • Real data: Running gulp --backend will proxy all backend calls to the backend of your choice. See below for configuration instructions.
  • Production build: Running gulp --prod will produce builds for production. This includes:
    • ngAnnotate : make your angular code minification proof
    • ngClassify : CoffeeScript classes for angular
    • minification : JS, CSS and HTML
    • image minification: images from teh img folder are compressed
    • rev: minified files are rev'ed for browser cache busting
    • templatecache : take all angular templates and include them in the minified scripts
    • deploy: deploy to a path or to AWS S3. see above for commands.
  • Dev Workflow:
    • watch : watch your src folder and rebuild and reload automatically
    • linting : lint .js and .coffee files. style checking and fixing with JSCS
    • test : run e2e (protractor) and unit (karma) tests
    • browserSync : test on multiple devices simultaneously
    • newer: only process changed files
    • HTML5Mode: Angular's html5Mode is supported on the BrowserSync server. Be sure to configure your production web server. HTMO5Mode is turned on by default. See Angular's documentation to turn it off for browser compatibility.
    • plato: perform code visualization, static analysis, and complexity analysis

Configuration

(Note: Configuration for the rest of the gulp plug-ins lives in the config folder.)

  • app.coffee
    • APP_NAME: name of the angular module for the app
  • bower.coffee
    • BOWER_COMPONENTS: consume dependencies from bower by specifying dependency name, version, dependency type (scripts, styles, etc.) and a list of files to be consumed (cherry picking files).
  • coffeeLint.coffee: options for linting CoffeeScript. See reference
  • e2e.coffee: options for protractor. See reference.
  • karma.coffee: options for karma. See reference
  • languages.coffee: disable compilers not in use to optimize your build
  • less.coffee: options for the less compiler. See reference
  • locationDeploy.coffee: deploy app to a path
  • plato.coffee: options for plato. See reference
  • s3Deploy.coffee: options to deploy to AWS S3. See reference
  • SCRIPTS: load order for scripts
  • server.coffee: options for browser-sync development server
    • PROXY_CONFIG: proxy backend calls during development with connect-modrewrite. See reference
    • PORT: run app on a specific port (default: 8181)
  • STYLES: load order for styles

Add Bower Component

You need three pieces of information for each Bower component to include in your app.

  1. The Bower component name (e.g. restangular)
  2. The version of the component (e.g. 1.4.0)
  3. The files within the component to include in your app (e.g. restangular.min.js)

The following will include the restangular component, version 1.4.0, and place the dist/restangular.min.js file in the vendor/scripts directory. By default, all Bower components will be placed in the vendor directory.

BOWER_COMPONENTS =
	'restangular': '1.4.0':
		scripts: 'dist/restangular.min.js'

If load order is important, include a reference to the file in the SCRIPTS section.

The following will ensure restangular is loaded prior to app.js.

SCRIPTS =
	'**/angular.min.js'
	'**/restangular.min.js'
	'**/app.js'
	'**/*.js'

For AngularJS components, include a reference to the module within your application. For example:

angular.module('app', ['restangular']);

Contributing

See CONTRIBUTING.md

Changelog

See CHANGELOG.md

License

See LICENSE

fatarrow's People

Contributors

bochenski avatar carylandholt avatar jyounce avatar knalli avatar mniebling avatar moderndegree avatar nach-mehta avatar nmehta6 avatar taejulee avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

fatarrow's Issues

ngClassify should respect APP_NAME

ng-classify should use APP_NAME from config.coffee as it's appName option so that the app works :)

If that sounds right, I'd be happy to submit a PR

Gulp Watch not recreating the vendor folder in dist on Windows

When the gulp watch is listening and you make a change, the recreated dist folder does not contain the 'vendor' folder with external dependencies.

Executed the following steps and this works on a mac but not on windows.

yo fatarrow
gulp

Make a change to html or javascript in src and the browser will reload but the app will not function sine the vendor folder is missing. Going to take a closer look later tonight.

make underscore replacements less ugly in app.coffee

I was able to placate my IDE and linter by changing the app module creation to this

class App extends App
    constructor: ->
        #dependencies
        list = [
            'ngAnimate'
            'ngSanitize'
            'ngTouch'
            'ngMessages'
            'ngResource'
            'angular-loading-bar'
        ]
        if '<%= useBackendless %>' == 'true'
            list.push 'ngMockE2E'

        return list

still ugly, but a better kind of ugly

ability to run tests and fail a build

Running gulp test currently runs karma in a child_process. This does not allow the main process to return the correct exit code so that a build would actually fail on a ci server. I tried a couple of approaches. Both work and would love to send PR on this.

  1. using a flag on the test task (gulp test --ci). Here I can do something like:
spawn   = childProcess.spawn command, ['karma'], {stdio: 'inherit'}

spawn.on 'close', (code, signal) ->
  throw 'tests failed' if code is 1
  1. define a separate task (gulp citest). Here it would look something like:
gulp.task 'utest', ['build'], ->
  gulp.start('karma')

I would love to hear your thoughts. Thanks.

PS: My naming is pretty terrible here and I need better task names here :)

Provide an option to gzip compress for prod builds

Add a --gzip option should allow you to compress html, css and js for production builds. This is desirable when web server configuration is not an option (serving from an S3 bucket for instance). It removes the complexity of configuring web servers. It also improves the web server performance slightly.

Run unit tests with 'gulp test' on a CI server

e2e tests do not run properly with gulp test command. They require the browserSync server to be running. Need to change this set up so all tests execute with this command. The process should also exit with the correct error code (if any).

Decorators in separate files and load order in dev

Defining decorators in separate files causes an issue with the load order in the dev mode. It would be awesome to have some convention like *.decorator.js and have gulp load these these at the end.

Make the upgrade process easier

Changes are hard to consume from fatarrow in other projects. It involves a manual task of merging changes. It is especially cumbersome if you have several projects based on this architecture.

One way this can be done is to publish fatarrow to bower or npm. This way, gulpfile.coffee can be donwloaded from bower from an npm postinstall hook for instance.

open app only when backendless

when using 'gulp --backend', the app launches. Since there is no backend, it errors out. I am thinking that some backend is responsible for consuming the static files output by gulp. I have a PR for this if you agree.

Vagrant support

Add a simple Vagrant file for people who want to use it. It should come with node and Java (selenium dependency).

support installing bower packages via github repo revision

right now i can only specify a valid bower package version in config.coffee.

I needed to grab the latest revision instead, but got this error

[16:13:02] Starting 'bower'...
[16:13:08] Tag/branch git://github.com/daneden/animate.css.git#a3cf3e6c88e8318b318f8f69c9468940b8aac079 does not exist
[16:13:08] 'bower' errored after 6.47 s

Make Plato stats available by serving the static files

Plato creates static files which can be served with a static file server to easily view.

Same can be done with coverage files and protractor screen shots.

It would be nice to wire up BrowserSync notifications to display links that take you to these sites.

cannot use bower list command manually in project dir

if I run bower list in the project dir I get output like this:

─▪ bower list
bower check-new     Checking for new versions of the project dependencies..
HourlyNerd#0.1.0 /Users/misha/Work/main-app/app
├── angular not installed
├── angular-animate not installed
├── angular-base64 not installed
....

I think it can be fixed by introducing a .bowerrc file that points bower to where the components go, but the weird thing is that bower_components is the standard name as far as I know, so it should just work.

Also, I suspect that running bower install manually will also not work

Windows paths are file paths

<script src="c:\vendor\angular\scripts\angular.min.js"></script>

Should be

<script src="/vendor/angular/scripts/angular.min.js"></script>

Ability to define bower.json

Gulp build currently deletes the bower.json file and recreates it from config.coffee. It would be nice to be able to define bower.json as is per bower specifications. If the file does exist, the gulp build can use it to install dependencies and pick out files per config.coffee configuration. If it does not exist, it can be created for people who do not wish to define it.

Reason for wanting to do something like this is so that now I can create components by using the fatarrow architecture and publish them to bower. May be there is a better (simpler) way?..

support for bower link

bower link allows testing a component locally before publishing it. This is similar to npm link. Currently, we are blowing away bower_components folder on the firstRun. Change this behavior when no-bower flag is specified.

Code Coverage?

Enhancement: Running gulp --stats, I'd expect to see a coverage folder as well. I currently don't see an option to run karma with coverage.

Add support for babel

i am planning on migrating one of my projects to babel and would be great to see it supported here.

less task has a race condition

When bower link used and the consumed less files change, first copy over less files and then run the less compiler on them. The current apporach of merged streams does not work with this and will cause less import errors.

server doest not start

When running 'gulp' the following error is thrown. It looks like the connect server start task is not completing.

events.js:72
        throw er; // Unhandled 'error' event
              ^
Error: listen EADDRINUSE
  at errnoException (net.js:904:11)
  at Server._listen2 (net.js:1042:14)
  at listen (net.js:1064:10)
  at Server.listen (net.js:1138:5)
  at ConnectApp.server (/Users/nachiketmehta/projects/fatarrow-test/fatarrow/node_modules/gulp-connect/index.js:57:12)
  at new ConnectApp (/Users/nachiketmehta/projects/fatarrow-test/fatarrow/node_modules/gulp-connect/index.js:37:10)
  at Object.module.exports.server (/Users/nachiketmehta/projects/fatarrow-test/fatarrow/node_modules/gulp-connect/index.js:135:12)
  at startServer (/Users/nachiketmehta/projects/fatarrow-test/fatarrow/gulpfile.coffee:242:10)
  at Gulp.gulp.task.options.minifyHtml.empty (/Users/nachiketmehta/projects/fatarrow-test/fatarrow/gulpfile.coffee:1067:2)
  at module.exports (/Users/nachiketmehta/projects/fatarrow-test/fatarrow/node_modules/gulp/node_modules/orchestrator/lib/runTask.js:34:7)
  at Gulp.Orchestrator._runTask (/Users/nachiketmehta/projects/fatarrow-test/fatarrow/node_modules/gulp/node_modules/orchestrator/index.js:273:3)
  at Gulp.Orchestrator._runStep (/Users/nachiketmehta/projects/fatarrow-test/fatarrow/node_modules/gulp/node_modules/orchestrator/index.js:214:10)
  at /Users/nachiketmehta/projects/fatarrow-test/fatarrow/node_modules/gulp/node_modules/orchestrator/index.js:279:18
  at finish (/Users/nachiketmehta/projects/fatarrow-test/fatarrow/node_modules/gulp/node_modules/orchestrator/lib/runTask.js:21:8)
  at /Users/nachiketmehta/projects/fatarrow-test/fatarrow/node_modules/gulp/node_modules/orchestrator/lib/runTask.js:52:4
  at f (/Users/nachiketmehta/projects/fatarrow-test/fatarrow/node_modules/gulp/node_modules/orchestrator/node_modules/end-of-stream/node_modules/once/once.js:16:25)
  at DestroyableTransform.onend (/Users/nachiketmehta/projects/fatarrow-test/fatarrow/node_modules/gulp/node_modules/orchestrator/node_modules/end-of-stream/index.js:31:18)
  at DestroyableTransform.emit (events.js:117:20)
  at /Users/nachiketmehta/projects/fatarrow-test/fatarrow/node_modules/gulp/node_modules/vinyl-fs/node_modules/through2/node_modules/readable-stream/lib/_stream_readable.js:965:16
  at process._tickCallback (node.js:419:13)

Karma config to make templateUrls work for directive unit tests

Karma needs to use the html2js preprocessor to include templates that are being loaded externally. Currently unit testing directives with templateUrl is not possible.

Example: http://newtriks.com/2013/04/26/how-to-test-an-angularjs-directive/

Tested this out on the routes directive included in fatarrow which has a templateUrl. Here is the test.

describe 'routes', ->
    describe 'routes directive', ->
        beforeEach module 'app'

        beforeEach inject (@$compile, $rootScope) ->
            @scope = $rootScope.$new()

        it 'renders html', ->
            markup = """
            <routes>
            # fatarrow
            </routes>
            """

            element    = @$compile(markup)(@scope)
            controller = element.controller()
            html       = element.html()
            expected   = '<h1>fatarrow</h1>'

            expect html
                .toEqual expected

This produces Expected '' to equal <h1>fatarrow</h1> because the template does not exist. The expected html should not be empty.

Cannot access Yargs parameters in gulp Karma Task

Hi Cary,

I am not able to access Yargs parameters from the karma task, as i see it is a different child process than the gulp one.

for example

yargs.options 'test',
default : false
description : 'test'
type : 'boolean'

testArg = getSwitchOption 'test'

gulp.task 'karma', ->
console.log " In Karma :", test

if i give the below command "gulp --test ", i assume it should print "In Karma true", but get a false which i think it does not recognize the yargs.

Is there a way i can access yargs in the karma task ?

Thanks,
Kanchan

is this ready for prime time?

I am learning angular and stumbled on your ng-classify repo and then here.
This repo looks like a rewrite of AngularFun. You are commiting code, so I installed it.

The directory structure is confusing. The only reason I can think of laying it out like that is that you havent done that part yet. AngularFun's dir structure looks much more comprehensible.

So, am I shooting myself in the foot by using this vs AngularFun ?
It would be great if you could include something in the readme for this project about why you are building 2 reference frameworks :)

bower does not install component when version is upgraded

I am trying to upgrade some of the bower components in my project. I went in the config.coffee and changed the version of them. When I stop and restart gulp, I get an error 'Unable to find suitable version for X', where X is the component.

I also tried the same by getting the latest version of fatarrow. I changed the version of angular from 1.2.25 to 1.2.26. I saw the same behavior.

If I delete 'bower_components' folder and then run bower install, things work fine.

I am not sure what it is about calling bower programmatically that is failing. Have you seen this?

Expand JSHint Predefined Globals

Following should be the complete list of globals

PREDEFINED_GLOBALS = [
    'after'
    'afterEach'
    'angular'
    'before'
    'beforeEach'
    'describe'
    'expect'
    'inject'
    'it'
    'jasmine'
    'module'
    'spyOn'
    'xdescribe'
    'xit'
]

CSS injection

Reloading the browser after CSS change is so 2014 :)

This seems pretty straightforward with BrowserSync.

Question about using a real backend

I am currently when using the --backend flag to exclude angular's $httpBackend. I have modified gulp tasks to drop off the build output to another location where my backend expects it. All this works great. However, I have been thinking about making the connect server that is spun up a proxy server. This way, you could have your api running wherever, and you can code your frontend against it. I wanted to see if you have any thoughts on this. Shouldn't be hard to wire it up, but do you think it belongs on fatarrow?

gulp watch task improvements

We made changes to your watch task in the following ways that greatly speed it up:

  1. Introduced a global firstRun flag that gets set to false in the watch task (which depends on all other tasks).
    When firstRun is false, we don't run the bower task. This is better then the flag to simply turn off bower since you get to run it once during a watch. We also don't clean the dist directory when it is false.
  2. We split up the watch task to watch different components of the app and update them individually. Here is the not-so-elegant code to do this:
gulp.task 'watch', ['build'], ->
    isFirstRun = false # don't cleanup the dist directory

    extensions = []
    .concat EXTENSIONS.VIEWS.COMPILED
    .concat EXTENSIONS.VIEWS.UNCOMPILED

    sources = [].concat ("**/*#{extension}" for extension in extensions)

    gulp
    .watch sources, {cwd: SRC_DIRECTORY, maxListeners: 999}, ['views']
    .on 'error', onError

    extensions = []
    .concat EXTENSIONS.SCRIPTS.COMPILED
    .concat EXTENSIONS.SCRIPTS.UNCOMPILED

    sources = [].concat ("**/*#{extension}" for extension in extensions)

    gulp
    .watch sources, {cwd: SRC_DIRECTORY, maxListeners: 999}, ['scripts']
    .on 'error', onError

    extensions = []
    .concat EXTENSIONS.STYLES.COMPILED
    .concat EXTENSIONS.STYLES.UNCOMPILED

    sources = [].concat ("**/*#{extension}" for extension in extensions)

    gulp
      .watch sources, {cwd: SRC_DIRECTORY, maxListeners: 999}, ['styles']
      .on 'error', onError

    gulp
      .watch 'index.html', {cwd: SRC_DIRECTORY, maxListeners: 999}, ['spa']
      .on 'error', onError

Unrelated to the above suggestion (or maybe related, because of the modifications we made)

I have an issue where the watch task dies intermittently during a clean like this:

[15:29:57] Starting 'clean:working'...

events.js:72
        throw er; // Unhandled 'error' event
              ^
Error: ENOENT, lstat '/Users/misha/Work/main-app/app/bower_components/_/vendor/angular-strap/scripts/dimensions.js'

Ive tried wrapping things in try catch statements but maybe I did it wrong? Either way, a clean shouldnt be to upset if it cant find a file to delete :)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.