node-ff-assets ========= A small library providing automatic site assets local/remote aggregation with minify. ## Installation npm install node-ff-assets --save ## Usage // Create config object var buildConfig = { downloadStartDelay: null, downloadForce: false, downloadOptions: { timeout: 10000, maxResponseLength: 10000000, agent: 'node-ff-assets asset fetcher' }, linkTargetSingleResult: process.env.DEV_ASSETS_SINGLE_RESULT || 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/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. buildConfig.linkTargetSingleResult = false; // 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'); // Create builder var NodeFFAssets = require('node-ff-assets'); var assetBuilderA = new NodeFFAssets.ResourceBuilder(buildConfig); var assetBuilderB = new NodeFFAssets.ResourceBuilder(buildConfig,NodeFFAssets.FunctionFactory.Constructor.readFile()); var assetBuilderC = new NodeFFAssets.ResourceBuilder(buildConfig,NodeFFAssets.FunctionFactory.Constructor.readFileMinify()); var assetBuilderD = new NodeFFAssets.ResourceBuilder(buildConfig,NodeFFAssets.FunctionFactory.Constructor.readFileMinify(minifyOptions)); var assetBuilderE = new NodeFFAssets.ResourceBuilder(buildConfig,function(file,callback) { // 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 }); // Run all builders NodeFFAssets.runAll([ assetBuilderA, assetBuilderB, assetBuilderC, ], function(err) { // all done }); // Use result function renderIndex(app) { return function (req, res, next) { res.render('index', { includeCssFiles: app.get('includeCssFiles'), includeJsFiles: app.get('includeJsFiles'), }); } }; app.get('/',renderIndex(app)); index.jade doctype html html(lang='en',ng-app='ffUI') head base(href='/ui') title=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=keywords) each cssFile in includeCssFiles link(rel='stylesheet' href='#{cssFile}') body div(id='wrapper') div(ng-include='\'/ui/include/html/layout/header\'') div(id='page-wrapper') div(id='container-fluid') div(ng-view) div(ng-include='\'/ui/include/html/layout/footer\'') each jsFile in includeJsFiles script(src='#{jsFile}') ## Example simple // 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 }) // Use result as in simple 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 = true || 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/js/lib/foobar/dyna.js@@http://localhost/force-download-on-every-build-for-this-file.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 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 info: Started on port: 8008 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 (TODO) ## 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.1.1 Doc updates * 0.1.0 Initial release