445 lines
17 KiB
Markdown
445 lines
17 KiB
Markdown
node-ff-assets
|
|
=========
|
|
|
|
A Node.js library providing automatic site assets aggregation.
|
|
|
|
## Installation
|
|
|
|
npm install node-ff-assets --save
|
|
|
|
## Example Application
|
|
|
|
There is a fully working express example application in the example folder.
|
|
This contains bootstrap and angularjs and ejs templates and results in single js and css file.
|
|
|
|
## Usage
|
|
|
|
note: www_static/[js/css]/lib are version ignored.
|
|
|
|
### example-assets.json
|
|
|
|
{
|
|
"linkMapping" : {
|
|
"/static/module/bootstrap/": "node_modules/bootstrap/dist/",
|
|
"/static/module/flot/": "node_modules/flot/",
|
|
"/static/": "www_static/"
|
|
},
|
|
"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"
|
|
]
|
|
}
|
|
}
|
|
|
|
### example.js
|
|
|
|
var express = require('express');
|
|
var async = require('async');
|
|
var path = require('path');
|
|
var assets = require('node-ff-assets');
|
|
|
|
function buildAssets(server,callbackDone) {
|
|
var singleResult = 'false' !== process.env.DEV_ASSETS_SINGLE_RESULT;
|
|
var assetsConfig = require('./example-assets.json');
|
|
assets.build({
|
|
assets: {
|
|
js: {
|
|
configCreate: assets.factory.builder.configCreate.fromJSON(assetsConfig,'js'),
|
|
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'),
|
|
configFill: function (config, callback) {
|
|
async.series([
|
|
assets.factory.lib.async.pushLinkSources(config, '/static/css/', 'www_static/css/'),
|
|
],callback);
|
|
},
|
|
},
|
|
},
|
|
assemblerCreate: assets.factory.builder.assemblerCreate.readFileRegex(),
|
|
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;
|
|
callback();
|
|
},
|
|
},callbackDone);
|
|
}
|
|
|
|
function renderPage(server) {
|
|
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.');
|
|
|
|
server.get('/example-ui',renderPage(server));
|
|
|
|
...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>
|
|
|
|
|
|
## Config options
|
|
|
|
The config option of the objects are filled from config templates with defaults.
|
|
|
|
### 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,
|
|
assemblerCreate: null,
|
|
assemblerFill: null,
|
|
},
|
|
css: {
|
|
configCreate: null,
|
|
configFill: null,
|
|
assemblerCreate: null,
|
|
assemblerFill: null,
|
|
},
|
|
},
|
|
};
|
|
|
|
### 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: [],
|
|
|
|
assetType: null,
|
|
assetHeader: '/* '+name+': Auto generated. */\n',
|
|
assetFooter: '/* '+name+': end */\n',
|
|
assetSeperator: '\n/* '+name+': <%= file %> */\n\n',
|
|
};
|
|
|
|
### Assembler Download Force
|
|
|
|
Sometimes its needed for have forces downloads of a resource.
|
|
This can be done by adding an extra @ sign.
|
|
|
|
linkSources: ['/static/js/lib/dynamic-generated.js@@http://localhost:8080/example-ui/include-js/generateModels'];
|
|
|
|
note: if using localhost to download use the downloadStartDelay option and start server before building.
|
|
|
|
The downloadForce option will redownload all resources of asset group.
|
|
|
|
|
|
## Target/Source locations
|
|
|
|
The asset target file location is a derived value.
|
|
|
|
Its created by mapping the assemblerConfig.linkTarget in the assemblerConfig.linkMapping keys
|
|
to get a prefix for the local file system location.
|
|
|
|
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.
|
|
|
|
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'],
|
|
|
|
Result;
|
|
|
|
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
|
|
|
|
if buildConfig.linkTargetSingleResult = true then result
|
|
static/js/ffa/assets.js
|
|
else
|
|
static/js/site.js
|
|
static/js/ffa/jquery-2.1.3/jquery.js
|
|
|
|
## Objects
|
|
|
|
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);
|
|
|
|
// Run all
|
|
assetsBuilderB.runAll(function(err) {
|
|
//done
|
|
});
|
|
|
|
// Run singles
|
|
async.series([
|
|
assetsBuilderC.runAsset('css'),
|
|
assetsBuilderD.runAsset('js'),
|
|
],function(err) {
|
|
//done
|
|
});
|
|
|
|
|
|
### Object AssetAssembler
|
|
|
|
var assets = require('node-ff-assets');
|
|
var assemblerConfig = {...};
|
|
|
|
// Create default assembler.
|
|
var assetAssemblerA = new assets.AssetAssembler(assemblerConfig);
|
|
|
|
// Same as default, plain inclusion of content.
|
|
var assetAssemblerB = new assets.AssetAssembler(assemblerConfig,assets.factory.assembler.constructor.readFile());
|
|
|
|
// 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));
|
|
|
|
// Minify content, with optional Minify config options.
|
|
var assetAssemblerC = new assets.AssetAssembler(assemblerConfig,assets.factory.assembler.constructor.readFileMinify());
|
|
var assetAssemblerD = new assets.AssetAssembler(assemblerConfig,assets.factory.assembler.constructor.readFileMinify(minifyOptions));
|
|
|
|
// Third party content modifiers, with readFile function
|
|
var assetAssemblerE = new assets.AssetAssembler(buildConfig,function(file,callback) {
|
|
// should return file data to callback(err,data);
|
|
);
|
|
|
|
// Registrate events (note: may change a bit)
|
|
assetAssemblerA.on('begin', function() { });
|
|
assetAssemblerA.on('end', function() { });
|
|
assetAssemblerA.on('log', function(logLevel, logMessage) { });
|
|
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) { });
|
|
|
|
// Use build in event functions
|
|
assetAssemblerB.on('log', assets.factory.assembler.event.log.console('css'));
|
|
assetAssemblerB.on('result', assets.factory.assembler.event.result.objectSet(server,'includeCssFiles'));
|
|
|
|
// Run builder
|
|
assetAssemblerC.run(function(err) {
|
|
//done
|
|
});
|
|
|
|
## Example log output
|
|
|
|
// Result First run
|
|
info: node-ff-assets-css build begin for: /static/css/lib/assets.css
|
|
debug: node-ff-assets-css readFile: node_modules/bootstrap/dist/css/bootstrap.css size: 285496
|
|
debug: node-ff-assets-css readFile: www_static/css/boot.css size: 1606
|
|
debug: node-ff-assets-css readFile: www_static/css/flot.css size: 82
|
|
debug: node-ff-assets-css readFile: www_static/css/panel.css size: 545
|
|
debug: node-ff-assets-css readFile: www_static/css/style.css size: 10419
|
|
debug: node-ff-assets-css target size: 298318
|
|
info: node-ff-assets-css build result size: 1 from: 5
|
|
info: node-ff-assets-css build done in: 33 ms.
|
|
info: node-ff-assets-js build begin for: /static/js/lib/assets.js
|
|
debug: node-ff-assets-js downloadFile: http://code.jquery.com/jquery-2.1.3.js
|
|
debug: node-ff-assets-js downloadFile: https://code.angularjs.org/1.4.0-beta.4/angular.js
|
|
debug: node-ff-assets-js downloadFile: https://code.angularjs.org/1.4.0-beta.4/angular-route.js
|
|
debug: node-ff-assets-js downloadFile: https://code.angularjs.org/1.4.0-beta.4/angular-resource.js
|
|
debug: node-ff-assets-js downloadFile: https://code.angularjs.org/1.4.0-beta.4/angular-touch.js
|
|
debug: node-ff-assets-js downloadFile: http://localhost:8008/ui/include/js/controller/test1
|
|
GET /ui/include/js/controller/test1 200 7.931 ms - -
|
|
debug: node-ff-assets-js downloadFile: http://localhost:8008/ui/include/js/controller/test2
|
|
GET /ui/include/js/controller/test2 200 5.215 ms - -
|
|
debug: node-ff-assets-js downloadFile: http://localhost:8008/ui/include/js/controller/test3
|
|
GET /ui/include/js/controller/test3 200 1.583 ms - -
|
|
debug: node-ff-assets-js readFile: www_static/js/lib/jquery-2.1.3/jquery.js size: 247387
|
|
debug: node-ff-assets-js readFile: node_modules/bootstrap/dist/js/bootstrap.js size: 66732
|
|
debug: node-ff-assets-js readFile: node_modules/flot/jquery.flot.js size: 110008
|
|
debug: node-ff-assets-js readFile: node_modules/flot/jquery.flot.resize.js size: 2504
|
|
debug: node-ff-assets-js readFile: node_modules/flot/jquery.flot.pie.js size: 23405
|
|
debug: node-ff-assets-js readFile: www_static/js/lib/angularjs-1.4.0-b4/angular.js size: 988198
|
|
debug: node-ff-assets-js readFile: www_static/js/lib/angularjs-1.4.0-b4/angular-route.js size: 35796
|
|
debug: node-ff-assets-js readFile: www_static/js/lib/angularjs-1.4.0-b4/angular-resource.js size: 26780
|
|
debug: node-ff-assets-js readFile: www_static/js/lib/angularjs-1.4.0-b4/angular-touch.js size: 22887
|
|
debug: node-ff-assets-js readFile: www_static/js/app-directives.js size: 185
|
|
debug: node-ff-assets-js readFile: www_static/js/app-filters.js size: 202
|
|
debug: node-ff-assets-js readFile: www_static/js/app-services.js size: 80
|
|
debug: node-ff-assets-js readFile: www_static/js/app.js size: 766
|
|
debug: node-ff-assets-js readFile: www_static/js/controller/page-about.js size: 364
|
|
debug: node-ff-assets-js readFile: www_static/js/controller/page-foobar.js size: 361
|
|
debug: node-ff-assets-js readFile: www_static/js/controller/page-index.js size: 351
|
|
debug: node-ff-assets-js readFile: www_static/js/controller/page-help.js size: 376
|
|
debug: node-ff-assets-js readFile: www_static/js/lib/xcrud/test1.js size: 2010
|
|
debug: node-ff-assets-js readFile: www_static/js/lib/xcrud/test2.js size: 2138
|
|
debug: node-ff-assets-js readFile: www_static/js/lib/xcrud/test3.js size: 2218
|
|
debug: node-ff-assets-js target size: 1540945
|
|
info: node-ff-assets-js build result size: 1 from: 24
|
|
info: node-ff-assets-js build done in: 3497 ms.
|
|
info: Server init done.
|
|
|
|
// Result Next runs
|
|
info: node-ff-assets-css build begin for: /static/css/lib/assets.css
|
|
debug: node-ff-assets-css readFile: node_modules/bootstrap/dist/css/bootstrap.css size: 285496
|
|
debug: node-ff-assets-css readFile: www_static/css/boot.css size: 1606
|
|
debug: node-ff-assets-css readFile: www_static/css/flot.css size: 82
|
|
debug: node-ff-assets-css readFile: www_static/css/panel.css size: 545
|
|
debug: node-ff-assets-css readFile: www_static/css/style.css size: 10419
|
|
debug: node-ff-assets-css target size: 298318
|
|
info: node-ff-assets-css build result size: 1 from: 5
|
|
info: node-ff-assets-css build done in: 36 ms.
|
|
info: node-ff-assets-js build begin for: /static/js/lib/assets.js
|
|
debug: node-ff-assets-js downloadFile: http://localhost:8008/ui/include/js/controller/test1
|
|
GET /ui/include/js/controller/test1 200 7.931 ms - -
|
|
debug: node-ff-assets-js downloadFile: http://localhost:8008/ui/include/js/controller/test2
|
|
GET /ui/include/js/controller/test2 200 5.215 ms - -
|
|
debug: node-ff-assets-js downloadFile: http://localhost:8008/ui/include/js/controller/test3
|
|
GET /ui/include/js/controller/test3 200 1.583 ms - -
|
|
debug: node-ff-assets-js readFile: www_static/js/lib/jquery-2.1.3/jquery.js size: 247387
|
|
debug: node-ff-assets-js readFile: node_modules/bootstrap/dist/js/bootstrap.js size: 66732
|
|
debug: node-ff-assets-js readFile: node_modules/flot/jquery.flot.js size: 110008
|
|
debug: node-ff-assets-js readFile: node_modules/flot/jquery.flot.resize.js size: 2504
|
|
debug: node-ff-assets-js readFile: node_modules/flot/jquery.flot.pie.js size: 23405
|
|
debug: node-ff-assets-js readFile: www_static/js/lib/angularjs-1.4.0-b4/angular.js size: 988198
|
|
debug: node-ff-assets-js readFile: www_static/js/lib/angularjs-1.4.0-b4/angular-route.js size: 35796
|
|
debug: node-ff-assets-js readFile: www_static/js/lib/angularjs-1.4.0-b4/angular-resource.js size: 26780
|
|
debug: node-ff-assets-js readFile: www_static/js/lib/angularjs-1.4.0-b4/angular-touch.js size: 22887
|
|
debug: node-ff-assets-js readFile: www_static/js/app-directives.js size: 185
|
|
debug: node-ff-assets-js readFile: www_static/js/app-filters.js size: 202
|
|
debug: node-ff-assets-js readFile: www_static/js/app-services.js size: 80
|
|
debug: node-ff-assets-js readFile: www_static/js/app.js size: 766
|
|
debug: node-ff-assets-js readFile: www_static/js/controller/page-about.js size: 364
|
|
debug: node-ff-assets-js readFile: www_static/js/controller/page-foobar.js size: 361
|
|
debug: node-ff-assets-js readFile: www_static/js/controller/page-index.js size: 351
|
|
debug: node-ff-assets-js readFile: www_static/js/controller/page-help.js size: 376
|
|
debug: node-ff-assets-js readFile: www_static/js/lib/xcrud/test1.js size: 2010
|
|
debug: node-ff-assets-js readFile: www_static/js/lib/xcrud/test2.js size: 2138
|
|
debug: node-ff-assets-js readFile: www_static/js/lib/xcrud/test3.js size: 2218
|
|
debug: node-ff-assets-js target size: 1540945
|
|
info: node-ff-assets-js build result size: 1 from: 24
|
|
info: node-ff-assets-js build done in: 105 ms.
|
|
info: Server init done.
|
|
|
|
## Tests
|
|
|
|
npm test
|
|
|
|
## 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
|
|
|
|
### 0.2.3
|
|
* Added json config reader.
|
|
* Added readFileRegex data filter.
|
|
* Added filename template to seperator.
|
|
* Converted example to ejs.
|
|
|
|
### 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
|
|
|
|
### 0.2.1
|
|
* Added example application
|
|
* Fixed buid callback
|
|
* Fixed buildOrder default
|
|
* Updated doc
|
|
|
|
### 0.2.0
|
|
* Redone objs
|
|
* Added tests
|
|
* Made jslint pass
|
|
|
|
### 0.1.x
|
|
* Added objectAdd
|
|
* Doc updates
|
|
* Initial release
|