grunt-modular-project
v0.5.0
Published
Builds a module/package/feature-based input source-tree into a website
Downloads
18
Readme
grunt-modular-project
Grunt Modular Project is a set of customisable workflow tasks designed for building JS + HTML + CSS modules into a website.
It has AngularJS/single-page-apps primarily in-mind.
The project transforms a source code folder (src
by default) into a web-application that can run in development or production mode.
Getting Started
This plugin requires Grunt ~0.4.5
. The default Karma plugin requires NodeJS 0.12
.
If you haven't used Grunt before, be sure to check out the Getting Started guide, as it explains how to create a Gruntfile as well as install and use Grunt plugins. Once you're familiar with that process, you may install this plugin with this command:
- Install the plugin
npm install grunt-modular-project --save-dev
- Load the plugin inside your
GruntFile.js
, and decide which workflow tasks you want.
grunt.loadNpmTasks('grunt-modular-project');
// Use all of the default tasks
grunt.loadTasks('node_modules/grunt-modular-project/tasks/build');
//grunt.loadTasks('node_modules/grunt-modular-project/tasks/buildLibrary'); // This task is only useful if your project is a component/library project.
grunt.loadTasks('node_modules/grunt-modular-project/tasks/install');
grunt.loadTasks('node_modules/grunt-modular-project/tasks/optimise');
grunt.loadTasks('node_modules/grunt-modular-project/tasks/release');
grunt.loadTasks('node_modules/grunt-modular-project/tasks/serve');
grunt.loadTasks('node_modules/grunt-modular-project/tasks/unitTest');
grunt.loadTasks('node_modules/grunt-modular-project/tasks/verify');
- In your
Gruntfile.js
, add a section namedmoduleProject
to the data object passed intogrunt.initConfig()
, and specify any overrides to the default values.
grunt.initConfig({
modularProject: {
},
});
- Modify your
package.json
file to include the NPM plugin's that your workflow tasks require (refer tonode_modules/grunt-modular-project/package.json
).
// package.json
...
"devDependencies": {
"colors": "^1.0.3",
"compression": "^1.4.1",
"conventional-changelog": "0.0.11",
"grunt": "^0.4.5",
...
}
Example project that uses this plugin
Workflow Tasks
From the command line, the following commands are available:
grunt install
: Installs commit message hooks forgit
to support conventional changeloggrunt dev
: Continuous development (builds debuggable version into/dev
folder, starts server, watches files for changes and reloads)grunt build
: Builds the site into/dist
, ready for distributiongrunt build:serve
: Builds the site into/dist
, and then serves it up via a connect webservergrunt test
: Runs Jasmine unit tests**/unitTest/*.spec.js
in PhantomJS via Karmagrunt test:browser
: Runs unit tests in Chrome (useful for debugging)grunt verify:all/src/test
: Checks all/src/test JS code for linting/syntax/style errorsgrunt release
: Builds the project, checks that all source code is committed and if so, bumps version numbers inpackage.json
andbower.json
(by default), then commits those changes + updatedCHANGELOG.md
with a version tag.grunt release:minor
: As above, but bumps minor versiongrunt release:major
: As above, but bumps major version
###Key features###
- Source code can be (should be) structured into modules
- No need for "global" folders - create a module called
global
oranythingYouLike
instead - Each module can contain:
- HTML files, which are deployed to
/views/{module}
- JS files, which are deployed to
/js/{moduleName}.js
. Note that JS files beginning with "_" will appear first inside the{moduleName}.js
file. /assets
, which contains static assets that are deployed to /assets/{module}. Static assets include images, data files which are needed at run-time./docs
, which contains JS and HTML files for component/project documentation. This content is ignored in the production build./includes
, which contains files that should be included into other files at compile-time. This folder does not get deployed./styles
, which contains CSS/SASS/LESS/Stylus files that are deployed to/css
. The technology you use is up to you (currently uses Stylus)./unittest
, which contains unit tests (currently Jasmine + Karma, but can be easily changed). This folder does not get deployed./partials
, which contains HTML files that are deployed to/views/{module}/partials
- Sub-modules! Yes, you can create modules-within-modules (like Java packages).
- HTML files, which are deployed to
- Code changes trigger re-compilation (when using
grunt dev
) - Support for live-reloading is built-in
- File-revving (cache-busting) and image+CSS+HTML+JS optimization for production builds
- Vendor specific libraries such as jQuery can be downloaded via Bower and used by editing
Gruntfile.js
to make them available to web-pages via the{{vendorScripts}}
template-tag. - Ability to define your own task-wiring from the provided tasks (not locked-in to the default approach)
- Ability to use special template-tags in HTML pages to refer to
{{vendorScripts}}
,{{externalScripts}}
,{{cssFiles}}
and{{appScripts}}
Default Options
The default options are located in modularProject.js
The defaults support the following input folder structure:
- config
- jscs
- .jscsrc
- jshint
- .jshint
- jscs
- src
- index.html
- modules
- myModule1
- _main.js
- other.js
- someHtml.html
- assets
- font
- images
- include
- partials
- *.html
- style
- *.styl
- unitTest
- *.spec.js
- template
- componentTemplate.html
- myModule2
- withSubModule
- assets
- unitTest
- ...
- includes
- ...
- withSubModule
- myModule1
And they produce the following output folder when using grunt dev
:
- dev
- index.html
- assets
- myModule1
- font
- images
- myModule1
- css
- rootFiles and external CSS files
- js
- myModule1.js (contains _main.js THEN all other JS files in the src/modules/module1 folder)
- myModule2.js
- withSubModule
- withSubModule.js
- vendor
- any files specified by
buildHTML.compilableVendorJSFiles
andbuildHTML.nonCompilableVendorJSFiles
- any files specified by
- views
- myModule1
- *.html
- myModule2
- *.html
- withSubModule
- *.html
- myModule1
And they produce the following output folder when using grunt build
:
- dist
- as above except all files are revved & minified & concatenate where applicable, except:
- js
- app.js (all JS files in this folder are concentated and minified into app.js)
Options
input.srcDir
Type: String
Default value: 'src/'
A relative path from the root directory to the source code root directory.
input.modulesDir
Type: String
Default value: 'src/modules/'
A relative path from the root directory to the modules directory. It is expected that underneath this directory are subdirectories representing one-or-more modules, and that these directories can also contain sub-modules.
More to come...
Usage Examples
grunt.initConfig({
// Configuration to be run (and then tested).
modularProject: {
input: {
// Use the defaults
},
output: {
// Use the defaults
},
buildCSS: {
rootSourceFiles: ['**/styles/docs.styl', '**/styles/sampleFormStyle.styl'],
externalCSSFiles: [
'<%= modularProject.bowerDir %>angular-motion/dist/angular-motion.css',
'<%= modularProject.bowerDir %>highlightjs/styles/github.css'
]
},
buildHTML: {
compiledCSSFiles: [
'css/angular-motion.css',
'css/github.css',
'css/docs.css',
'css/sampleFormStyle.css'
],
compilableVendorJSFiles: [
// Order is important - Angular should come first
'<%= modularProject.bowerDir %>angular/angular.js',
'<%= modularProject.bowerDir %>angular-animate/angular-animate.js',
'<%= modularProject.bowerDir %>angular-translate/angular-translate.js',
'<%= modularProject.bowerDir %>angular-translate-loader-static-files/angular-translate-loader-static-files.js',
'<%= modularProject.bowerDir %>angular-scroll/angular-scroll.js',
'<%= modularProject.bowerDir %>angular-strap/dist/angular-strap.js',
'<%= modularProject.bowerDir %>angular-strap/dist/angular-strap.tpl.js'
],
nonCompilableVendorJSFiles: [
'<%= modularProject.bowerDir %>highlightjs/highlight.pack.js'
]
},
// Custom config for building a JS library - used by the mpBuildLibrary task
buildLibrary: {
libFileNamePrefix: 'ng-form-lib',
libSrcFiles: ['**/*.js', '!**/docs.js']
},
release: {
// Modify both the docsConfig.json SRC and the temporary documentation version (in /docs), but only commit the SRC version.
filesToBump: ['package.json', 'bower.json', 'src/modules/docs/assets/config/docsConfig.json', 'docs/assets/docs/config/docsConfig.json'],
filesToCommit: ['package.json', 'bower.json', 'CHANGELOG.md', 'src/modules/docs/assets/config/docsConfig.json'],
tasks: ['releaseDocs']
},
optimise: {
tasks: [
'mpBuildLibrary', // New task
'clean:optimised',
'concurrent:optimisedImages',
'copy:optimised',
'concat:optimised', 'uglify:optimised',
'mpOptimiseHTMLTags', 'targethtml:optimised',
'filerev:optimised', 'useminOptimised',
'htmlmin:optimised', 'usebanner'
'beep:twobits' // Beep at the end
]
},
unitTest: {
testLibraryFiles: [
'<%= modularProject.buildHTML.compilableVendorJSFiles %>',
'<%= modularProject.bowerDir %>angular-mocks/angular-mocks.js'
]
}
}
});
Contributing
See CONTRIBUTING.md