1. Install Dependencies
> npm install && grunt
2. Run Debug Server
> grunt server
3. Start a Development session (in a new terminal tab)
> grunt develop
This is a very early release which works but lack in documentation.
We are working hard to reach a first stable version, please contribute!
The Workspace is a GruntJS setup which combines a lot of nice existing tools to provide you with a clever project organization and code structure in order to increase productivity.
The Workspace takes heavy inspiration from a framework which is used internally in Mobenga AB, the company I work with.
This repository aim to bring some good concept we use to the OpenSource world!
I really want to credit Mobenga AB and my colleagues Markus, Robert and Tomas for the great job we do together!
A typical Workspace folder structure should be:
package.json
Gruntfile.js
karma.conf.js
src/
index.html
index.js
index.less
assets/
img/
css/
js/
features/
modules/
build/
debug/
release/
You write you app source files in src/
then the building process creates two runnable versions of your app in build/
.
A first debug/
build is filled with uncompressed files, source maps and other testing facilities.
A release/
build contains the optimized and ready to deploy app, concatenation, minification, caching and assets inlining are applied just out of the box.
The Workspace is used to create HTML5 Single Page Applications so you have 3 main entry points for your application:
- index.html
- index.js
- index.less
Into the index.html
file you will find some placeholder comments for both CSS and JS:
<!--[CSS]-->
place you custom style links here
<!--[/CSS]-->
<!--[JS]-->
place your custom script links here
<!--[/JS]-->
Those placeholders are used by the Workspace building process to concatenate and optimize your source files!
In both index.js
and index.less
you will find the /*FEATURES*/
placeholder which is used to automagically include all the features you will create within your application's assets.
A Feature represents a slice of your application and should wrap some responsibilities or should implement a story from your backlog.
It's up to you to understand how to use features the most productive way!
A Feature can contain:
- Javascript logic
- LESS rules
- HTML templates
- static assets
- unit tests
package.json
dependency manifest
A Module is a fully reusable piece of Javascript.
It should implements a single function or a complex library and should be composed by a great amount of little sub-modules just like the NodeJS way.
A Module can contain:
- Javascript logic
- unit tests
package.json
dependency manifest
The Workspace allow to install, require and use any compatible NPM Modules.
Application folder and any Features or Modules should expose a package.json
manifest in which to list some dependencies.
The building process tries to resolve all Features and Modules dependencies before to build the App!
By instance you can easily use jQuery by loading it from NPM:
// from you project's root
npm install jquery --save
then require it from your javascript entry point:
// src/index.js
window.$ = require('jquery');
A feature or a module should also depend on other modules and should contain an internal package.json
where to list such dependencies.
// install/check all features and modules dependencies
grunt install
The command above step into all the project's features and modules and install (via npm install
) all the listed dependencies.
By default Workspace makes available each folder under src/features
and src/modules
as a require compatible namespace so you can run the following command from the window scope:
// "src/modules/module-name" should be referred as:
require('module-name').exportedAPI
You can also expose some sub-modules in order to run:
// use "src/modules/module-name/sub-module.js" as:
require('module-name/sub-module').exportedAPI
To make above code to work you need to export each sub-module declaring it in module's package.json
file:
// module-name/package.json
{
"exports" : [
"sub-module",
"sub-module/sub-sub",
]
}
Use the
"exports" : true
shortcut to expose all sub-modules!
You can also expose a sub-module to the global scope:
// module-name/package.json
{
"globals" : [
"sub-module"
]
}
// somewhere around the code
require('sub-module');
This should be useful for big packages to expose their modules to the global scope (like a framework package).
IMPORTANT!
To pollute the global scope should produce unpredictable outcomes.
Do it very carefully!
When you write a LESS source file you may want to link some static images as backgrounds or to create some FontFace rules:
// map to "src/assets" folder
background: url(assets://img/file.jpg)
// map to a "featureName/assets" folder
background: url(feature://img/file.jpg)
Both
feature://
andassets://
works also for feature's static CSS, but you are encouraged to switch to LessCss to write your stylesheets.
Often you need to write debug code which you wish to be automatically removed from the release version.
Well the Workspace introduces the concept of comment-to-code which is basically Javascript code within comments:
// next line will run everywhere:
console.log('everywhere');
// next line will run only debug build:
/*D console.log('only for debugging eyes'); */
Comment's code is evaluated in the debug build but is stripped out at release time.
You can add specification tests to both src/features
and src/modules
:
// feature-name/specs/test.spec.js
describe('my Feature', function() {
it('should start', function() {
expect(
require('feature-name').start
).to.be.a('function');
});
});
Then you can run all your tests with the Grunt task:
grunt test
You can also start a Continuous Integration environment to quickly run tests when a new build is made:
// terminal 1: start a Karma server instance
grunt start-ci
// terminal 2: run tests after every build
grunt ci
During development you may want to run your web app through a web server in order to better simulate the production environment.
The Workspace comes with a simple Express based server which can be user for both debug and release build:
grunt server
This default configuration run an HTTP Server available at http://localhost:8080
serving your build/debug
folder.
It provides also a full sourcemaps support in order to debug your app to the source files for both Javascript and LESS sources.
You can configure a custom port in the Gruntfile.js
config:
'wks-debug-server' : {
wkd : {
options: {
args: '1234'
}
}
}
When you are ready to test your production ready release you can run the server in release mode which means your build/release
folder is served and no cache prevention are done:
grunt server-release
You can specify your desired port also for the release mode:
'wks-debug-server' : {
wkr : {
options: {
args: '1234'
}
}
}
/**
* Workspace Configuration
*/
'workspace': {
options: {
minifyTemplates: false,
release: {
uglify: {
beautify: true,
compress: false,
mangle: false
},
minifyHtml: false,
inline: {
css: false,
js: false
},
manifest: {
filename: 'appcache',
exclude: [
'/assets/readme.txt', // exclude file path
'/assets/css/images/**' // exclude an entire folder
]
}
},
karma: {
test: {
browsers: [
'PhantomJS',
'Chrome',
'ChromeCanary',
'Firefox',
'Opera'
]
}
}
}
}