2
0
Fork 0
node-ff-assets/README.md

414 lines
15 KiB
Markdown
Raw Normal View History

2015-02-24 11:39:38 +00:00
node-ff-assets
=========
2015-02-27 03:42:14 +00:00
A Node.js library providing automatic site assets aggregation.
2015-02-24 11:39:38 +00:00
## Installation
npm install node-ff-assets --save
2015-02-27 14:41:47 +00:00
## Example Application
2015-03-14 18:12:16 +00:00
There is a fully working express example application in the example folder.
2015-06-28 14:41:57 +00:00
This contains bootstrap and angularjs and ejs templates and results in single html/js/css file.
2015-02-27 14:41:47 +00:00
2015-02-27 03:42:14 +00:00
## Usage
2015-06-28 14:41:57 +00:00
note: www_static/[js/css]/lib are scm version ignored.
### example-assets.json
{
"linkMapping" : {
"/static/module/bootstrap/": "node_modules/bootstrap/dist/",
"/static/module/flot/": "node_modules/flot/",
"/static/": "www_static/"
2015-02-27 03:42:14 +00:00
},
"css": {
"linkTarget": "/static/css/lib/assets.css",
"linkSources": [
"/static/module/bootstrap/css/bootstrap.css"
]
},
"js": {
"linkTarget": "/static/js/lib/assets.js",
"linkSources": [
"/static/js/lib/jquery-2.1.3/jquery.js@http://code.jquery.com/jquery-2.1.3.js",
"/static/module/bootstrap/js/bootstrap.js",
"/static/module/flot/jquery.flot.js",
"/static/module/flot/jquery.flot.resize.js",
"/static/module/flot/jquery.flot.pie.js",
"/static/js/lib/angularjs-1.4.0-b4/angular.js@https://code.angularjs.org/1.4.0-beta.4/angular.js",
"/static/js/lib/angularjs-1.4.0-b4/angular-route.js@https://code.angularjs.org/1.4.0-beta.4/angular-route.js",
"/static/js/lib/angularjs-1.4.0-b4/angular-resource.js@https://code.angularjs.org/1.4.0-beta.4/angular-resource.js",
"/static/js/lib/angularjs-1.4.0-b4/angular-touch.js@https://code.angularjs.org/1.4.0-beta.4/angular-touch.js"
]
2015-02-27 03:42:14 +00:00
}
}
### example.js
var express = require('express');
var async = require('async');
var path = require('path');
2015-03-14 18:12:16 +00:00
var assets = require('node-ff-assets');
2015-02-27 03:42:14 +00:00
function buildAssets(server,callbackDone) {
var singleResult = 'false' !== process.env.DEV_ASSETS_SINGLE_RESULT;
var assetsConfig = require('./example-assets.json');
2015-02-27 03:42:14 +00:00
assets.build({
assets: {
js: {
configCreate: assets.factory.builder.configCreate.fromJSON(assetsConfig,'js'),
2015-02-27 03:42:14 +00:00
configFill: function (config, callback) {
async.series([
assets.factory.lib.async.pushLinkSources(config, '/static/js/', 'www_static/js/'),
assets.factory.lib.async.pushLinkSources(config, '/static/js/controller/', 'www_static/js/controller/'),
],callback);
},
},
css: {
configCreate: assets.factory.builder.configCreate.fromJSON(assetsConfig,'css'),
2015-02-27 03:42:14 +00:00
configFill: function (config, callback) {
async.series([
assets.factory.lib.async.pushLinkSources(config, '/static/css/', 'www_static/css/'),
2015-02-27 03:42:14 +00:00
],callback);
},
},
},
assemblerCreate: assets.factory.builder.assemblerCreate.readFileRegex(),
2015-02-27 03:42:14 +00:00
assemblerFill: function (assembler, callback) {
var serverResultKey = 'ff_assets_'+assembler.config.assetType;
assembler.on ('log', assets.factory.assembler.event.log.console(assembler.config.assetType));
assembler.on ('result', assets.factory.assembler.event.result.objectSet(server,serverResultKey));
assembler.config.linkTargetSingleResult = singleResult;
2015-02-27 03:42:14 +00:00
callback();
},
},callbackDone);
}
function renderPage(server) {
2015-03-14 18:12:16 +00:00
return function (req, res) {
res.render('index', {
pageTitle: 'node-ff-assets example',
pageKeywords: 'node,ff,assets,example,ui',
pageCssFiles: server.get('ff_assets_css'),
pageJsFiles: server.get('ff_assets_js'),
});
};
}
var server = express();
buildAssets(server,function(err) {
if (err) {
throw err;
}
console.info('Server assets done.');
2015-03-14 18:12:16 +00:00
server.get('/example-ui',renderPage(server));
2015-03-14 18:12:16 +00:00
...snip.. config rest of server
});
### index.ejs
<!DOCTYPE html>
<html lang="en" ng-app="exampleUI">
<head>
<title><%= pageTitle %></title>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="keywords" content="<%= pageKeywords %>">
<% if (pageCssFiles.length) { %><% pageCssFiles.forEach(function (cssFile) { %><link rel="stylesheet" href="<%= cssFile %>"><% }) %><% } %>
</head>
<body>
<div id="wrapper">
<div ng-include="'/example-ui/thtml/layout/header'"></div>
<div id="page-wrapper">
<div id="container-fluid">
<div ng-view></div>
</div>
</div>
</div>
<div ng-include="'/example-ui/thtml/layout/footer'"></div>
<% if (pageJsFiles.length) { %><% pageJsFiles.forEach(function (jsFile) { %><script src="<%= jsFile %>"></script><% }) %><% } %>
</body>
</html>
2015-02-27 03:42:14 +00:00
## Config options
2015-02-27 14:41:47 +00:00
The config option of the objects are filled from config templates with defaults.
2015-02-27 03:42:14 +00:00
### Builder Config
Only configCreate if required to set in root and/or in asset.
var template = {
buildOrder: ['css','js'],
configCreate: null,
configFill: factory.builder.configCreate.nop(),
assemblerCreate: factory.builder.assemblerCreate.readFile(),
assemblerFill: factory.builder.configCreate.nop(),
assets: {
js: {
configCreate: null,
configFill: null,
2015-02-27 03:42:14 +00:00
assemblerCreate: null,
assemblerFill: null,
2015-02-27 03:42:14 +00:00
},
css: {
configCreate: null,
configFill: null,
2015-02-27 03:42:14 +00:00
assemblerCreate: null,
assemblerFill: null,
2015-02-27 03:42:14 +00:00
},
},
};
### Assembler Config
required: assetType,linkTarget,linkSources and linkMapping.
var name = 'node-ff-assets';
var downloadTimeout = (1000*10) * 6; // 1min
var downloadMaxSize = (1024*1024) * 10; // 10mb
var template = {
downloadStartDelay: null,
downloadForce: false,
downloadOptions: {
timeout: downloadTimeout,
maxResponseLength: downloadMaxSize,
agent: name+' remote fetcher',
},
linkTargetSingleResult: true,
linkTarget: null,
linkSources: [],
linkMapping: [],
2015-02-27 03:42:14 +00:00
assetType: null,
assetHeader: '/* '+name+': Auto generated. */\n',
assetFooter: '/* '+name+': end */\n',
assetSeperator: '\n/* '+name+': <%= file %> */\n\n',
2015-02-27 03:42:14 +00:00
};
2015-02-27 14:41:47 +00:00
### Assembler Download Force
Sometimes its needed for have forces downloads of a resource.
This can be done by adding an extra @ sign.
2015-02-27 14:49:28 +00:00
linkSources: ['/static/js/lib/dynamic-generated.js@@http://localhost:8080/example-ui/include-js/generateModels'];
2015-02-27 14:41:47 +00:00
note: if using localhost to download use the downloadStartDelay option and start server before building.
2015-02-27 14:41:47 +00:00
The downloadForce option will redownload all resources of asset group.
2015-02-27 03:42:14 +00:00
2015-02-24 14:42:32 +00:00
## Target/Source locations
The asset target file location is a derived value.
2015-02-27 14:49:28 +00:00
Its created by mapping the assemblerConfig.linkTarget in the assemblerConfig.linkMapping keys
2015-02-24 14:42:32 +00:00
to get a prefix for the local file system location.
2015-02-27 14:49:28 +00:00
The same is also true for the assemblerConfig.linkSources list which are url paths
which need to be mapped to the file system files by the assemblerConfig.linkMapping data.
2015-02-24 14:42:32 +00:00
linkTarget: '/static/js/ffa/assets.js',
linkMapping: ['/static/':'www_static/',],
linkSources: ['/static/js/site.js','/static/js/ffa/jquery-2.1.3/jquery.js@http://code.jquery.com/jquery-2.1.3.js'],
2015-02-27 03:42:14 +00:00
Result;
2015-02-24 14:42:32 +00:00
2015-02-27 03:42:14 +00:00
public js file: http://localhost:8080/static/js/site.js
public js file: http://localhost:8080/static/js/ffa/assets.js
public js file: http://localhost:8080/static/js/ffa/jquery-2.1.3/jquery.js
filesystem file: www_static/js/site.js
filesystem file: www_static/js/ffa/assets.js
filesystem file: www_static/js/ffa/jquery-2.1.3/jquery.js
.gitignore line: www_static/js/ffa
2015-02-27 14:41:47 +00:00
if buildConfig.linkTargetSingleResult = true then result
2015-02-27 03:42:14 +00:00
static/js/ffa/assets.js
else
static/js/site.js
static/js/ffa/jquery-2.1.3/jquery.js
2015-02-24 14:42:32 +00:00
2015-02-27 03:42:14 +00:00
## Objects
2015-02-24 11:39:38 +00:00
2015-02-27 03:42:14 +00:00
For some use cases the assets.build(config,callback) is flexable enough.
Then there are two objects which may provide the needed options.
### Object AssetsBuilder
var assets = require('node-ff-assets');
var builderConfig = {...};
// Create builder
var assetsBuilderA = new assets.AssetsBuilder(builderConfig);
2015-02-24 13:10:50 +00:00
2015-02-27 03:42:14 +00:00
// Run all
assetsBuilderB.runAll(function(err) {
//done
});
2015-02-24 13:10:50 +00:00
2015-02-27 03:42:14 +00:00
// Run singles
async.series([
assetsBuilderC.runAsset('css'),
assetsBuilderD.runAsset('js'),
],function(err) {
//done
});
2015-02-24 13:10:50 +00:00
2015-02-27 03:42:14 +00:00
### Object AssetAssembler
var assets = require('node-ff-assets');
var assemblerConfig = {...};
2015-02-24 14:42:32 +00:00
2015-02-27 03:42:14 +00:00
// Create default assembler.
var assetAssemblerA = new assets.AssetAssembler(assemblerConfig);
2015-02-24 14:42:32 +00:00
// Same as default, plain inclusion of content.
2015-02-27 03:42:14 +00:00
var assetAssemblerB = new assets.AssetAssembler(assemblerConfig,assets.factory.assembler.constructor.readFile());
2015-02-24 14:42:32 +00:00
// Filter content based on regexes
var assetAssemblerF = new assets.AssetAssembler(assemblerConfig,assets.factory.assembler.constructor.readFileRegex());
var assetAssemblerH = new assets.AssetAssembler(assemblerConfig,assets.factory.assembler.constructor.readFileRegex(regexData));
2015-02-24 14:42:32 +00:00
// Minify content, with optional Minify config options.
2015-02-27 03:42:14 +00:00
var assetAssemblerC = new assets.AssetAssembler(assemblerConfig,assets.factory.assembler.constructor.readFileMinify());
var assetAssemblerD = new assets.AssetAssembler(assemblerConfig,assets.factory.assembler.constructor.readFileMinify(minifyOptions));
2015-02-24 14:42:32 +00:00
// Third party content modifiers, with readFile function
2015-02-27 03:42:14 +00:00
var assetAssemblerE = new assets.AssetAssembler(buildConfig,function(file,callback) {
2015-02-24 14:42:32 +00:00
// should return file data to callback(err,data);
2015-02-24 13:10:50 +00:00
);
2015-02-27 03:42:14 +00:00
// Registrate events (note: may change a bit)
assetAssemblerA.on('begin', function() { });
assetAssemblerA.on('end', function() { });
2015-06-28 14:41:57 +00:00
assetAssemblerA.on('log', function(logMessage) { });
2015-02-27 03:42:14 +00:00
assetAssemblerA.on('result', function(resultValue) { });
assetAssemblerA.on('file-download-pre', function(remoteUrl) { });
assetAssemblerA.on('file-download-post', function(localFile) { });
assetAssemblerA.on('file-read-pre', function(localFile) { });
assetAssemblerA.on('file-read-post', function(localFile) { });
assetAssemblerA.on('file-write-pre', function(targetFile) { });
assetAssemblerA.on('file-write-post', function(targetFile) { });
2015-02-24 13:10:50 +00:00
// Use build in event functions
2015-02-27 03:42:14 +00:00
assetAssemblerB.on('log', assets.factory.assembler.event.log.console('css'));
assetAssemblerB.on('result', assets.factory.assembler.event.result.objectSet(server,'includeCssFiles'));
2015-02-24 13:10:50 +00:00
// Run builder
2015-02-27 03:42:14 +00:00
assetAssemblerC.run(function(err) {
2015-02-24 14:42:32 +00:00
//done
2015-02-24 13:10:50 +00:00
});
2015-02-27 03:42:14 +00:00
## Example log output
2015-02-24 11:39:38 +00:00
2015-06-28 14:41:57 +00:00
First run with downloads and with DEBUG="*"
ff:assets:assets-builder runAll started. +0ms
ff:assets:assets-builder runAsset started for: css +1ms
ff:assets:assets-builder runAsset started for: js +0ms
ff:assets:assets-builder assemblerCreate from default +2ms
ff:assets:assets-builder assemblerFill from default +0ms
ff:assets:assets-builder runAssembler type: css +0ms
node-ff-assets:css build begin for: /static/css/lib/assets.css
ff:assets:asset-assembler downloadList size: 0 +4ms
ff:assets:asset-assembler readFileList size: 5 +1ms
ff:assets:asset-assembler readFile: node_modules/bootstrap/dist/css/bootstrap.css size: 129940 +4ms
ff:assets:asset-assembler readFile: www_static/css/boot.css size: 1824 +1ms
ff:assets:asset-assembler readFile: www_static/css/flot.css size: 94 +0ms
ff:assets:asset-assembler readFile: www_static/css/panel.css size: 605 +1ms
ff:assets:asset-assembler readFile: www_static/css/style.css size: 448 +0ms
ff:assets:asset-assembler target file: www_static/css/lib/assets.css +0ms
ff:assets:asset-assembler target size: 133244 +0ms
node-ff-assets:css build result size: 1 from: 5
node-ff-assets:css build done in: 10 ms.
ff:assets:assets-builder assemblerCreate from default +1ms
ff:assets:assets-builder assemblerFill from default +0ms
ff:assets:assets-builder runAssembler type: js +0ms
node-ff-assets:js build begin for: /static/js/lib/assets.js
ff:assets:asset-assembler downloadList size: 5 +1ms
ff:assets:asset-assembler readFileList size: 13 +0ms
ff:assets:asset-assembler downloadFile: http://code.jquery.com/jquery-2.1.3.js +0ms
ff:assets:asset-assembler downloadFile: https://code.angularjs.org/1.4.0-beta.4/angular.js +90ms
ff:assets:asset-assembler downloadFile: https://code.angularjs.org/1.4.0-beta.4/angular-route.js +2s
ff:assets:asset-assembler downloadFile: https://code.angularjs.org/1.4.0-beta.4/angular-resource.js +579ms
ff:assets:asset-assembler downloadFile: https://code.angularjs.org/1.4.0-beta.4/angular-touch.js +567ms
ff:assets:asset-assembler readFile: www_static/js/lib/jquery-2.1.3/jquery.js size: 151917 +593ms
ff:assets:asset-assembler readFile: node_modules/bootstrap/dist/js/bootstrap.js size: 49199 +4ms
ff:assets:asset-assembler readFile: node_modules/flot/jquery.flot.js size: 54509 +7ms
ff:assets:asset-assembler readFile: node_modules/flot/jquery.flot.resize.js size: 1439 +1ms
ff:assets:asset-assembler readFile: node_modules/flot/jquery.flot.pie.js size: 13451 +2ms
ff:assets:asset-assembler readFile: www_static/js/lib/angularjs-1.4.0-b4/angular.js size: 297085 +61ms
ff:assets:asset-assembler readFile: www_static/js/lib/angularjs-1.4.0-b4/angular-route.js size: 8360 +5ms
ff:assets:asset-assembler readFile: www_static/js/lib/angularjs-1.4.0-b4/angular-resource.js size: 6847 +1ms
ff:assets:asset-assembler readFile: www_static/js/lib/angularjs-1.4.0-b4/angular-touch.js size: 7568 +2ms
ff:assets:asset-assembler readFile: www_static/js/example-app.js size: 401 +0ms
ff:assets:asset-assembler readFile: www_static/js/controller/page-bar.js size: 205 +0ms
ff:assets:asset-assembler readFile: www_static/js/controller/page-foo.js size: 205 +0ms
ff:assets:asset-assembler readFile: www_static/js/controller/page-index.js size: 207 +1ms
ff:assets:asset-assembler target file: www_static/js/lib/assets.js +0ms
ff:assets:asset-assembler target size: 592332 +0ms
node-ff-assets:js build result size: 1 from: 13
node-ff-assets:js build done in: 3502 ms.
Server assets done.
Server config done.
Server started on port 8080
2015-02-24 11:39:38 +00:00
## Tests
2015-02-27 14:41:47 +00:00
npm test
2015-02-24 11:39:38 +00:00
## Contributing
In lieu of a formal styleguide, take care to maintain the existing coding style.
Add unit tests for any new or changed functionality. Lint and test your code.
## Release History
2015-06-28 14:41:57 +00:00
### 0.2.5
* Switched debug logging to debug library.
* Removed events from AssetsBuilder.
* Removed logLevel from log event in AssetAssembler.
2015-03-14 21:44:25 +00:00
### 0.2.4
* Added json config reader.
* Added readFileRegex data filter.
* Added filename template to seperator.
* Converted example to ejs.
2015-02-27 20:50:19 +00:00
### 0.2.2
* Fixed error to callback
* Fixed 404 error
* Removed error event
* Added log event to builder
* Added builder tests
* Made example jslint pass
2015-02-27 14:41:47 +00:00
### 0.2.1
2015-02-27 14:49:28 +00:00
* Added example application
* Fixed buid callback
* Fixed buildOrder default
* Updated doc
2015-02-24 14:42:32 +00:00
2015-02-27 14:41:47 +00:00
### 0.2.0
2015-02-27 14:49:28 +00:00
* Redone objs
* Added tests
* Made jslint pass
2015-02-24 13:10:50 +00:00
2015-02-27 14:41:47 +00:00
### 0.1.x
2015-02-27 14:49:28 +00:00
* Added objectAdd
2015-02-27 14:41:47 +00:00
* Doc updates
* Initial release