2
0
Fork 0

updated doc

This commit is contained in:
Willem 2015-02-27 04:42:14 +01:00
parent 50f2b83443
commit 258112d928

481
README.md
View file

@ -1,12 +1,178 @@
node-ff-assets node-ff-assets
========= =========
A Node.js library providing automatic site assets aggregation and content modifiers. A Node.js library providing automatic site assets aggregation.
## Installation ## Installation
npm install node-ff-assets --save npm install node-ff-assets --save
## Usage
// note1: www_static/[js/css]/lib is version ignored.
// note2: server routes;
// app.use('/static', express.static(path.join(__dirname,'www_static')));
// app.use('/static/module/flot', express.static(path.join(__dirname,'node_modules/flot/dist')));
// app.use('/static/module/bootstrap', express.static(path.join(__dirname,'node_modules/bootstrap/dist')));
var assets = require('node-ff-assets');
var assetsConfig = {
// Map from uri paths to file systems paths.
linkMapping : {
'/static/module/bootstrap/': 'node_modules/bootstrap/dist/',
'/static/module/flot/': 'node_modules/flot/',
'/static/': 'www_static/',
},
// Site sources in html page.
linkSourcesCss : [
'/static/module/bootstrap/css/bootstrap.css',
],
linkSourcesJs : [
'/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',
],
};
// callback helper to return an assembler config per asset type
function createBuildConfig(type) {
return function(callback) {
// Override rendered result from command line
var singleResult = 'false' != process.env.DEV_ASSETS_SINGLE_RESULT;
if (type == 'css') {
callback(null,{
linkMapping: assetsConfig.linkMapping,
linkTargetSingleResult: singleResult,
linkTarget: '/static/css/lib/assets.css',
linkSources: assetsConfig.linkSourcesCss,
assetType: type,
});
} else {
callback(null, {
linkTargetSingleResult: singleResult,
linkMapping: assetsConfig.linkMapping,
linkTarget: '/static/js/lib/assets.js',
linkSources: assetsConfig.linkSourcesJs,
assetType: type,
});
}
}
}
function buildAssets(server,callbackDone) {
assets.build({
assets: {
js: {
configCreate: createBuildConfig('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: createBuildConfig('css'),
configFill: function (config, callback) {
async.series([
assets.factory.lib.async.pushLinkSources(config, '/static/css/', 'www_static/css/'),
],callback);
},
assemblerCreate: function (assemblerConfig, callback) {
callback(null,new assets.AssetAssembler(assemblerConfig,assets.factory.assembler.constructor.readFileMinify()));
},
},
},
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));
callback();
},
},callbackDone);
}
exports.build = function(server) {
buildAssets(server,function(err) {
if (err) {
throw err;
}
console.log('Server init done.');
// init other stuff...
});
}
## Config options
The config option templates can be found in code;
todo: add link
### 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: '\n/* '+name+': begin */\n\n',
assetFooter: '\n/* '+name+': end */\n\n',
assetSeperator: '\n/* '+name+': next */\n',
};
## Target/Source locations ## Target/Source locations
The asset target file location is a derived value. The asset target file location is a derived value.
@ -18,110 +184,102 @@ A Node.js library providing automatic site assets aggregation and content modifi
linkTarget: '/static/js/ffa/assets.js', linkTarget: '/static/js/ffa/assets.js',
linkMapping: ['/static/':'www_static/',], 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'], linkSources: ['/static/js/site.js','/static/js/ffa/jquery-2.1.3/jquery.js@http://code.jquery.com/jquery-2.1.3.js'],
Gives;
public js file: http://localhost:8080/static/js/site.js Result;
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 render public js file: http://localhost:8080/static/js/site.js
static/js/ffa/assets.js public js file: http://localhost:8080/static/js/ffa/assets.js
else public js file: http://localhost:8080/static/js/ffa/jquery-2.1.3/jquery.js
static/js/site.js filesystem file: www_static/js/site.js
static/js/ffa/jquery-2.1.3/jquery.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 render
static/js/ffa/assets.js
else
static/js/site.js
static/js/ffa/jquery-2.1.3/jquery.js
## Usage ## Objects
// Create config object For some use cases the assets.build(config,callback) is flexable enough.
var buildConfig = { Then there are two objects which may provide the needed options.
downloadStartDelay: null,
downloadForce: false, ### Object AssetsBuilder
downloadOptions: {
timeout: 10000, var assets = require('node-ff-assets');
maxResponseLength: 10000000, var builderConfig = {...};
agent: 'node-ff-assets asset fetcher'
}, // Create builder
var assetsBuilderA = new assets.AssetsBuilder(builderConfig);
linkTargetSingleResult: true,
linkTarget: '/static-uri/js/assets.js',
linkSources: [
'/static/js/lib/jquery-2.1.3/jquery.js@http://code.jquery.com/jquery-2.1.3.js',
'/static/js/lib/foobar/dyna.js@@http://localhost/force-download-on-every-build-for-this-file.js',
'/static/js/site.js'
],
linkMapping: ['/static-uri/':'www_static/',],
assetHeader: '\n/* node-ff-assets: begin */\n\n',
assetFooter: '\n/* node-ff-assets: end */\n\n',
assetSeperator: '\n/* node-ff-assets: next */\n',
}
// Development override, targets still gets build but result is full list of assets. // Run all
buildConfig.linkTargetSingleResult = false; assetsBuilderB.runAll(function(err) {
// Push local js/css files as uri sources into config
NodeFFAssets.pushLinkSourcesSync(buildConfig, '/static-uri/js/', 'www_public/js/');
NodeFFAssets.pushLinkSourcesSync(buildConfig, '/static-uri/js/model/', 'www_public/js/model/');
NodeFFAssets.pushLinkSourcesSync(buildConfig, '/static-uri/js/model/meta', 'www_public/js/model/meta');
// Require library
var NodeFFAssets = require('node-ff-assets');
// Create simpel builder
var assetBuilderA = new NodeFFAssets.ResourceBuilder(buildConfig);
// Same as default, plain inclusion of content.
var assetBuilderB = new NodeFFAssets.ResourceBuilder(buildConfig,NodeFFAssets.FunctionFactory.Constructor.readFile());
// Minify content, with optional Minify config options.
var assetBuilderC = new NodeFFAssets.ResourceBuilder(buildConfig,NodeFFAssets.FunctionFactory.Constructor.readFileMinify());
var assetBuilderD = new NodeFFAssets.ResourceBuilder(buildConfig,NodeFFAssets.FunctionFactory.Constructor.readFileMinify(minifyOptions));
// Third party content modifiers, with readFile function
var assetBuilderE = new NodeFFAssets.ResourceBuilder(buildConfig,function(file,callback) {
// should return file data to callback(err,data);
);
// Hook events
assetBuilderA.on('begin', function() { });
assetBuilderA.on('end', function() { });
assetBuilderA.on('log', function(logLevel, logMessage) { });
assetBuilderA.on('error', function(err) { });
assetBuilderA.on('result', function(resultValue) { });
assetBuilderA.on('file-download-pre', function(remoteUrl) { });
assetBuilderA.on('file-download-post', function(localFile) { });
assetBuilderA.on('file-read-pre', function(localFile) { });
assetBuilderA.on('file-read-post', function(localFile) { });
assetBuilderA.on('file-write-pre', function(targetFile) { });
assetBuilderA.on('file-write-post', function(targetFile) { });
// Use build in event functions
assetBuilderB.on('log', NodeFFAssets.FunctionFactory.Event.log.console('css'));
assetBuilderB.on('result', NodeFFAssets.FunctionFactory.Event.result.objectSet(server,'includeCssFiles'));
// Run builder
assetBuilderC.run(function(err) {
//done //done
}); });
// Run all builders // Run singles
NodeFFAssets.runAll([ async.series([
assetBuilderA, assetsBuilderC.runAsset('css'),
assetBuilderB, assetsBuilderD.runAsset('js'),
assetBuilderC, ],function(err) {
], function(err) { //done
// all done });
});
// Render result
### 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());
// 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('error', function(err) { });
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
});
## Rendering
In these examples I use the server (app/express) object to store the results in for displaying.
Which the index page renderer will get and inject in page context.
function renderIndex(app) { function renderIndex(app) {
return function (req, res, next) { return function (req, res, next) {
res.render('index', { res.render('index', {
includeCssFiles: app.get('includeCssFiles'), includeCssFiles: server.get('ff_assets_css'),
includeJsFiles: app.get('includeJsFiles'), includeJsFiles: server.get('ff_assets_js'),
}); });
} }
}; };
@ -133,11 +291,11 @@ A Node.js library providing automatic site assets aggregation and content modifi
html(lang='en',ng-app='ffUI') html(lang='en',ng-app='ffUI')
head head
base(href='/ui') base(href='/ui')
title=title title='Index'
meta(charset='UTF-8') meta(charset='UTF-8')
meta(http-equiv='X-UA-Compatible' content='IE=edge') meta(http-equiv='X-UA-Compatible' content='IE=edge')
meta(name='viewport' content='width=device-width, initial-scale=1') meta(name='viewport' content='width=device-width, initial-scale=1')
meta(name='keywords' content=keywords) meta(name='keywords' content='keywords')
each cssFile in includeCssFiles each cssFile in includeCssFiles
link(rel='stylesheet' href='#{cssFile}') link(rel='stylesheet' href='#{cssFile}')
body body
@ -150,132 +308,8 @@ A Node.js library providing automatic site assets aggregation and content modifi
each jsFile in includeJsFiles each jsFile in includeJsFiles
script(src='#{jsFile}') script(src='#{jsFile}')
## Example log output
## Example mapping node_modules
Some js libraries can be directly served from node_packages and thus also be
included the node-ff-assets output, but these required there own reverse mapping;
'/static/module/bootstrap/': 'node_modules/bootstrap/dist/',
This will let the parse find the /static/module/bootstrap/css/bootstrap.css resource and
maps it the local file; node_modules/bootstrap/dist/css/bootstrap.css
// note1: www_static/[js/css]/lib is versioned ingored.
// note2: server routes;
// app.use('/static',express.static(path.join(__dirname,'www_static')));
// app.use('/static/module/bootstrap',express.static(path.join(__dirname,'node_modules/bootstrap/dist')));
var NodeFFAssets = require('node-ff-assets');
var buildCss = new NodeFFAssets.ResourceBuilder({
linkMapping: {
'/static/module/bootstrap/': 'node_modules/bootstrap/dist/',
'/static/': 'www_static/',
},
linkTarget: '/static/css/lib/assets.css',
linkSources: [
'/static/module/bootstrap/css/bootstrap.css',
'/static/css/site.css',
],
});
buildCss.on('log', NodeFFAssets.FunctionFactory.Event.log.console('css'));
buildCss.on('result', NodeFFAssets.FunctionFactory.Event.result.objectSet(server,'includeCssFiles'));
buildCss.run(function(err) {
// done
})
// Render result as in usage example.
## Example complex
var LogWinston = require('winston');
var Log = LogWinston.loggers.get('main');
var Mongoose = require('mongoose');
var NodeFFAssets = require('node-ff-assets');
function createBuildConfig(type) {
var singleResult = 'false' != process.env.DEV_ASSETS_SINGLE_RESULT;
var linkMapping = {
'/static/module/bootstrap/': 'node_modules/bootstrap/dist/',
'/static/module/flot/': 'node_modules/flot/',
'/static/': 'www_static/',
}
if (type == 'css') {
return {
linkMapping: linkMapping,
linkTargetSingleResult: singleResult,
linkTarget: '/static/css/lib/assets.css',
linkSources: [
'/static/module/bootstrap/css/bootstrap.css',
],
};
} else {
return {
downloadStartDelay: 200,
linkTargetSingleResult: singleResult,
linkMapping: linkMapping,
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',
],
};
}
}
function createBuildLogger(logType) {
return function(logLevel, logMessage) {
Log.log(logLevel, 'node-ff-assets-'+logType+' '+logMessage);
}
};
function buildAssets(server,callback) {
// Create asset config
var buildJsConfig = createBuildConfig('js');
var buildCssConfig = createBuildConfig('css');
// Extends js/css lists with local folders
NodeFFAssets.pushLinkSourcesSync(buildJsConfig, '/static/js/', 'www_static/js/');
NodeFFAssets.pushLinkSourcesSync(buildJsConfig, '/static/js/controller/', 'www_static/js/controller/');
NodeFFAssets.pushLinkSourcesSync(buildCssConfig, '/static/css/', 'www_static/css/');
// Extend js list with crud entries
var localPort = server.get('server config').options.http.port;
var modelNames = Mongoose.connection.modelNames();
for (i = 0; i < modelNames.length; i++) {
var modelName = modelNames[i];
var assetLink = '/static/js/lib/xcrud/'+modelName+'.js@@http://localhost:'+localPort+'/ui/include/js/controller/'+modelName;
buildJsConfig.linkSources.push(assetLink);
}
// Create builders
var buildJs = new NodeFFAssets.ResourceBuilder(buildJsConfig); // note: Minify fails here on some js.
var buildCss = new NodeFFAssets.ResourceBuilder(buildCssConfig,NodeFFAssets.FunctionFactory.Constructor.readFileMinify());
// Config build events
buildJs.on ('log', createBuildLogger('js'));
buildCss.on('log', createBuildLogger('css'));
buildJs.on ('result', NodeFFAssets.FunctionFactory.Event.result.objectSet(server,'includeJsFiles'));
buildCss.on('result', NodeFFAssets.FunctionFactory.Event.result.objectSet(server,'includeCssFiles'));
// Run builders
NodeFFAssets.runAll([buildCss,buildJs],callback);
}
exports.build = function(server) {
buildAssets(server,function() {
Log.info('Server init done.');
});
}
// Result First run // Result First run
info: node-ff-assets-css build begin for: /static/css/lib/assets.css 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: node_modules/bootstrap/dist/css/bootstrap.css size: 285496
@ -376,6 +410,11 @@ Add unit tests for any new or changed functionality. Lint and test your code.
## Release History ## Release History
* 0.2.0
redone objs
added tests
made jslint pass
* 0.1.2 added objectAdd * 0.1.2 added objectAdd
* 0.1.1 Doc updates * 0.1.1 Doc updates