createAppBundleMappings: function(bundleSetConfig, optimizerContext, callback) { ok(bundleSetConfig, '"bundleSetConfig" is required'); ok(typeof callback === 'function', 'callback function is required'); var dependencyRegistry = this.dependencies; var bundleMappings = new BundleMappings(this.config); var asyncTasks = []; bundleSetConfig.forEachBundleConfig(function(bundleConfig) { var bundleName = bundleConfig.name; ok(bundleName, 'Illegal state. Bundle name is required'); asyncTasks.push(function(callback) { bundleBuilder.buildBundle( bundleMappings, dependencyRegistry, bundleConfig, optimizerContext, callback); }); }); return series(asyncTasks, function(err) { if (err) { return callback(err); } return callback(null, bundleMappings); }); },
function (dir, helpers, done) { var main = require(nodePath.join(dir, 'test.js')); var testName = nodePath.basename(dir); var pageName = 'resource-transforms-' + testName; var lassoConfig = main.getLassoConfig && main.getLassoConfig(); if (!lassoConfig) { lassoConfig = { bundlingEnabled: false, fingerprintsEnabled: false }; } if (!lassoConfig.outputDir) { lassoConfig.outputDir = nodePath.join(buildDir, pageName); } if (!lassoConfig.projectRoot) { lassoConfig.projectRoot = dir; } rmdirRecursive(lassoConfig.outputDir); var myLasso = lasso.create(lassoConfig, dir); var inputs = main.getInputs(); var asyncTasks = inputs.map((input, i) => { return (callback) => { var path = input.path; var options = input.options; myLasso.lassoResource(path, options, function(err, result) { if (err) { callback(err); } process.nextTick(() => { try { input.check(result); } catch(e) { return callback(`The inputs at index ${i} failed: ${e.stack}`); } callback(); }); }); }; }); series(asyncTasks, function(err) { if (err) { return done(err); } done(); }); });
return function(callback) { var plugin = use.plugin; var pluginName; if (typeof plugin === 'string') { pluginName = plugin; plugin = builtins[plugin] || require(plugin); } if (!pluginName) { pluginName = plugin.name; } var options = use.options || {}; var patterns = use.paths; if (typeof patterns === 'string') { patterns = [patterns]; } var paths = {}; series(patterns.map(function(pattern) { return function(callback) { glob(pattern, { cwd: basedir}, function (err, files) { if (err) { return callback(err); } for (var i=0, len=files.length; i<len; i++) { var path = files[i]; path = nodePath.join(basedir, path); paths[path] = true; } callback(); }); }; }), function(err) { if (err) { return initDataHolder.reject(err); } Object.keys(paths).forEach(function(path) { var pluginsForPath = pluginsByPath[path] || (pluginsByPath[path] = []); pluginsForPath.push({ plugin: plugin, options: options }); }); callback(); }); };
function globNormalizer(dependency, context, callback) { if (typeof dependency === 'string' && globRegExp.test(dependency)) { var pattern = dependency; var typeSeparator = dependency.indexOf(':'); var type = null; var basedir = context.dirname; var matches = []; if (typeSeparator) { type = dependency.substring(0, typeSeparator).trim(); pattern = dependency.substring(typeSeparator+1); } pattern = pattern.trim(); var patterns = pattern.split(/\s+/); var asyncTasks = patterns.map(function(pattern) { return function(callback) { glob(pattern, { cwd: basedir }, function (err, files) { if (err) { return callback(err); } matches = matches.concat(files); callback(); }); }; }); series(asyncTasks, function(err) { if (err) { return callback(err); } matches = matches.map(function(match) { match = nodePath.join(basedir, match); return type ? type + ':' + match : match; }); callback(null, matches); }); } else { callback(); } }
writeBundles: function(iteratorFunc, onBundleWrittenCallback, lassoContext, callback) { ok(lassoContext, 'lassoContext is required'); ok(callback, 'callback is required'); var _this = this; var work = []; iteratorFunc(function(bundle) { if (bundle.hasContent()) { work.push(function(callback) { _this.writeBundle(bundle, onBundleWrittenCallback, lassoContext, callback); }); } }); series(work, callback); }
function resolveInspectedRequires(inspected, fromDir, fromFile, isBuiltin, options, optimizerContext, callback) { ok(inspected, '"inspected" is required'); equal(typeof fromDir, 'string', '"fromDir" should be a string'); equal(typeof callback, 'function', '"callback" should be a string'); var allRequires = []; var asyncTasks = []; function handleRequire(require) { asyncTasks.push(function(callback) { resolveRequire(require.path, fromDir, fromFile, options, optimizerContext, function(err, resolved) { if (err) { return callback(err); } if (isBuiltin && resolved.builtin !== true) { resolved = extend({}, resolved); resolved.builtin = true; } require.resolved = resolved; allRequires.push(require); callback(); }); }); } inspected.requires.forEach(handleRequire); inspected.asyncBlocks.forEach(function(asyncBlock) { asyncBlock.requires.forEach(handleRequire); }); series(asyncTasks, function(err) { if (err) { return callback(err); } inspected.allRequires = allRequires; callback(null, inspected); }); }
dependencies.normalize(function(err, dependencies) { var asyncTasks = dependencies.map(function(rootDependency) { return function(callback) { rootDependency.init(lassoContext, function(err) { logger.debug('Root init'); if (err) { return callback(err); } var recurseInto = rootDependency._recurseInto || bundleConfig.getRecurseInto(); if (!recurseInto) { if (rootDependency.getDir()) { recurseInto = 'dirtree'; } else { recurseInto = 'all'; } } if (!recurseHandlers[recurseInto]) { throw new Error('Invalid recursion option: ' + recurseInto); } var recurseHandler = recurseHandlers[recurseInto](rootDependency, lassoContext); function shouldIncludeDependency(dependency) { if (dependency === rootDependency || (lassoContext.parentDependency && lassoContext.parentDependency === rootDependency)) { // Always include the root dependency or any child dependencies if the top-level // dependency was a package return true; } return recurseHandler.shouldIncludeDependency(dependency); } function shouldRecurseIntoPackageDependency(dependency) { if (dependency === rootDependency) { // Always recurse into top-level package dependencies return true; } return recurseHandler.shouldRecurseIntoPackageDependency(dependency); } dependencyWalker.walk({ lassoContext: lassoContext, dependency: rootDependency, flags: flags, shouldSkipDependency: function(dependency) { if (bundleMappings.getBundleForDependency(dependency)) { // The dependency has already been added to another bundle return true; } if (dependency.isPackageDependency()) { return !shouldRecurseIntoPackageDependency(dependency); } else if (!dependency.read) { // ignore non-readable dependencies during bundling phase return true; } return false; }, on: { dependency: function(dependency, context) { logger.debug(module.id, 'on dependency: ' + dependency.type); if (dependency.isPackageDependency()) { if (tree) { tree.add(dependency, context.parentDependency); } // We are only interested in non-package dependencies return; } if (shouldIncludeDependency(dependency)) { bundleMappings.addDependencyToBundle( dependency, targetBundleName, context.slot, bundleConfig, lassoContext); if (tree) { tree.add(dependency, context.parentDependency); } } } } }, callback); }); }; }); series(asyncTasks, function(err) { if (err) { return callback(err); } if (tree) { logger.debug('Bundle "' + targetBundleName + '":\n' + tree.toString()); } callback(); }); });
getOptimizerManifestFromOptions(options, pageOptimizer.dependencies, function(err, optimizerManifest) { if (!optimizerManifest) { callback(new Error('Invalid options. "dependencies", "packagePath" or "optimizerManifest" expected. Options: ' + require('util').inspect(options))); } options.optimizerManifest = optimizerManifest; var pluginContext = { context: optimizerContext, config: config, options: options, pageOptimizer: pageOptimizer }; pageOptimizer.emit('beforeOptimizePage', pluginContext); var optimizedPage = new OptimizedPage(); var slotTracker = new SlotTracker(); var writer = optimizerContext.writer; function registerBundle(bundle, async) { var url = bundle.getUrl(optimizerContext); if (url) { optimizedPage.addUrl(url, bundle.getSlot(), bundle.getContentType(), async); } if (!bundle.isExternalResource && bundle.outputFile) { optimizedPage.addFile(bundle.outputFile, bundle.getContentType(), async); } } function onBundleWritten(bundle) { if (logInfoEnabled) { logger.info('Bundle ' + bundle + ' written.'); } registerBundle(bundle, false); } function onAsyncBundleWritten(bundle) { if (logInfoEnabled) { logger.info('Bundle ' + bundle + ' (async) written.'); } registerBundle(bundle, true); } function buildHtmlSlots(pageBundles) { pageBundles.forEachBundle(function(bundle) { var html, url; if (bundle.isInline()) { slotTracker.addInlineCode(bundle.getSlot(), bundle.getContentType(), bundle.getCode(), bundle.getInlinePos(), bundle.isMergeInline()); } else { url = bundle.getUrl(optimizerContext); if (bundle.isJavaScript()) { html = pageOptimizer.getJavaScriptDependencyHtml(url); } else if (bundle.isStyleSheet()) { html = pageOptimizer.getCSSDependencyHtml(url); } else if (!bundle.hasContent()) { // ignore this bundle because contentType is "none" return; } else { throw new Error('Invalid bundle content type: ' + bundle.getContentType()); } slotTracker.addContent(bundle.getSlot(), bundle.getContentType(), html); } }); optimizedPage.setHtmlBySlot(slotTracker.getHtmlBySlot()); } var pageBundles; var prevStartTime = startTime; var asyncTasks = [ function buildPageBundles(callback) { pageOptimizer.buildPageBundles(options, optimizerContext, function(err, _pageBundles) { if (err) { return callback(err); } pageBundles = _pageBundles; callback(); }); }, function writeAsyncBundles(callback) { if (perfLogInfoEnabled) { perfLogger.info('Page bundles built in ' + (Date.now() - prevStartTime) + 'ms'); } prevStartTime = Date.now(); optimizerContext.setPhase('write-async-page-bundles'); // First write out all of the async bundles writer.writeBundles(pageBundles.forEachAsyncBundleIter(), onAsyncBundleWritten, optimizerContext, callback); }, function writeSyncBundles(callback) { if (perfLogInfoEnabled) { perfLogger.info('Async page bundles written in ' + (Date.now() - prevStartTime) + 'ms'); } prevStartTime = Date.now(); optimizerContext.setPhase('write-page-bundles'); // Now write out all of the non-async bundles writer.writeBundles(pageBundles.forEachBundleIter(), onBundleWritten, optimizerContext, callback); } ]; series(asyncTasks, function(err) { if (err) { return callback(err); } if (perfLogInfoEnabled) { perfLogger.info('Page bundles written in ' + (Date.now() - prevStartTime) + 'ms'); } // All of the bundles have now been persisted, now we can // generate all of the HTML for the page buildHtmlSlots(pageBundles); perfLogger.info('Optimized page "' + pageName + '" in ' + (Date.now() - startTime) + 'ms'); if (optimizerContext.cache) { optimizerContext.cache.flushAll(); } callback(null, optimizedPage); }); });
function (dir, done) { var main = require(nodePath.join(dir, 'test.js')); var testName = nodePath.basename(dir); var pageName = 'bundling-' + testName; var lassoConfig = main.getLassoConfig && main.getLassoConfig(); if (!lassoConfig) { lassoConfig = { bundlingEnabled: false, fingerprintsEnabled: false }; } if (!lassoConfig.outputDir) { lassoConfig.outputDir = nodePath.join(buildDir, pageName); } rmdirRecursive(lassoConfig.outputDir); var myLasso = lasso.create(lassoConfig, dir); var inputs; if (main.getInputs) { inputs = main.getInputs(); } else { let lassoOptions = main.getLassoOptions(dir) || {}; let check = main.check; inputs = [ { lassoOptions, check } ]; } var asyncTasks = inputs.map((input) => { return (callback) => { var writerTracker = WriterTracker.create(myLasso.writer); var lassoOptions = input.lassoOptions; var check = input.check; if (!lassoOptions.pageName) { lassoOptions.pageName = pageName; } if (!lassoOptions.from) { lassoOptions.from = dir; } myLasso.lassoPage(lassoOptions) .then((lassoPageResult) => { check(lassoPageResult, writerTracker); lasso.flushAllCaches(callback); }) .catch(callback); }; }); series(asyncTasks, (err) => { if (err) { return done(err); } done(); }); });
writeBundle: function(bundle, onBundleWrittenCallback, lassoContext, callback) { ok(callback, 'callback is required'); if (!bundle.hasContent()) { return callback(); } ok(lassoContext, 'lassoContext is required'); var _this = this; function done(err) { if (err) { err = createError('Error while writing bundle "' + bundle + '" Error: ' + err, err); return callback(err); } bundle.setWritten(true); if (onBundleWrittenCallback) { onBundleWrittenCallback(bundle); } _this.emit('bundleWritten', { bundle: bundle }); logger.info('Bundle ' + bundle + ' written.'); return callback(null, bundle); } if (bundle.isWritten() || bundle.url) { if (logger.isInfoEnabled()) { logger.info('Bundle (' + bundle.getKey() + ') already written. Skipping writing...'); } return done(); } else if ((bundle.inPlaceDeployment === true) && !bundle.isInline()) { var inPlaceUrl = this.getInPlaceUrlForBundle(bundle, lassoContext); if (inPlaceUrl) { if (logger.isInfoEnabled()) { logger.info('In-place deployment enabled for (' + bundle.getKey() + '). Skipping writing...'); } bundle.setUrl(inPlaceUrl); return done(); } } lassoContext = Object.create(lassoContext); lassoContext.bundle = bundle; lassoContext.dependencies = bundle.dependencies; var bundleReader = reader.createBundleReader(bundle, lassoContext); logger.info('Writing bundle ' + bundle + '...'); var asyncTasks = [ function checkBundleUpToDate(callback) { if (bundle.isInline()) { return callback(); } return _this.checkBundleUpToDate(bundle, lassoContext, function(err) { if (err) { return callback(err); } // We make the assumption that the bundle was populated with its URL // and marked as written if it was indeed up-to-date return callback(); }); }, function writeBundle(callback) { if (bundle.isWritten()) { // If the bundle is written then there is nothing to do return callback(); } var completed = false; function handleError(e) { if (!completed) { completed = true; return callback(e); } } if (bundle.isInline()) { bundleReader.readBundleFully(function(err, code) { if (err) { return handleError(err); } logger.info('Code for inline bundle ' + bundle.getLabel() + ' generated.'); bundle.setCode(code); return callback(); }); } else { _this.impl.writeBundle(bundleReader, lassoContext, function(err) { if (err) { return handleError(err); } return callback(); }); } } ]; series(asyncTasks, done); },
getLassoManifestFromOptions(options, theLasso.dependencies, function(err, lassoManifest) { if (!lassoManifest) { callback(new Error('Invalid options. "dependencies", "packagePath" or "lassoManifest" expected. Options: ' + require('util').inspect(options))); } logger.debug('getLassoManifestFromOptions()'); options.lassoManifest = lassoManifest; var pluginContext = { context: lassoContext, config: config, options: options, lasso: theLasso }; // TODO: Deprecate this theLasso.emit('beforeOptimizePage', pluginContext); theLasso.emit('beforeLassoPage', pluginContext); var lassoPageResult = new LassoPageResult(); var slotTracker = new SlotTracker(); var writer = lassoContext.writer; // Inline code fingerprinting is useful for building a Single Page App // that is using a Content Security Policy (CSP) that prevents // untrusted script blocks. By keeping track of inline code // fingerprints, a build tool could provide these as part of the CSP // so that inline code blocks created at build time will be trusted. var fingerprintInlineCode = config.fingerprintInlineCode; var inlineCodeFingerprints; if (fingerprintInlineCode) { inlineCodeFingerprints = []; } function onBundleWritten(bundle) { if (logInfoEnabled) { logger.info('Bundle ' + bundle + ' written.'); } lassoPageResult.registerBundle(bundle, false, lassoContext); } function onAsyncBundleWritten(bundle) { if (logInfoEnabled) { logger.info('Bundle ' + bundle + ' (async) written.'); } lassoPageResult.registerBundle(bundle, true, lassoContext); } function buildHtmlSlots(pageBundles) { pageBundles.forEachBundle(function(bundle) { var html, url; if (bundle.isInline()) { if (fingerprintInlineCode) { var fingerprint = config.fingerprintInlineCode(bundle.getCode()); if (fingerprint) { inlineCodeFingerprints.push(fingerprint); } } slotTracker.addInlineCode(bundle.getSlot(), bundle.getContentType(), bundle.getCode(), bundle.getInlinePos(), bundle.isMergeInline()); } else { url = bundle.getUrl(lassoContext); if (bundle.isJavaScript()) { html = theLasso.getJavaScriptDependencyHtml(url); } else if (bundle.isStyleSheet()) { html = theLasso.getCSSDependencyHtml(url); } else if (!bundle.hasContent()) { // ignore this bundle because contentType is "none" return; } else { throw new Error('Invalid bundle content type: ' + bundle.getContentType()); } slotTracker.addContent(bundle.getSlot(), bundle.getContentType(), html); } }); lassoPageResult.setHtmlBySlot(slotTracker.getHtmlBySlot()); lassoPageResult.setInlineCodeFingerprints(inlineCodeFingerprints); } var pageBundles; var prevStartTime = startTime; var asyncTasks = [ function buildPageBundles(callback) { logger.debug('buildPageBundles BEGIN'); theLasso.buildPageBundles(options, lassoContext, function(err, _pageBundles) { if (err) { return callback(err); } logger.debug('buildPageBundles COMPLETE'); pageBundles = _pageBundles; callback(); }); }, function writeAsyncBundles(callback) { if (perfLogInfoEnabled) { perfLogger.info('Page bundles built in ' + (Date.now() - prevStartTime) + 'ms'); } prevStartTime = Date.now(); lassoContext.setPhase('write-async-page-bundles'); // First write out all of the async bundles writer.writeBundles(pageBundles.forEachAsyncBundleIter(), onAsyncBundleWritten, lassoContext, callback); }, function writeSyncBundles(callback) { if (perfLogInfoEnabled) { perfLogger.info('Async page bundles written in ' + (Date.now() - prevStartTime) + 'ms'); } prevStartTime = Date.now(); lassoContext.setPhase('write-page-bundles'); // Now write out all of the non-async bundles writer.writeBundles(pageBundles.forEachBundleIter(), onBundleWritten, lassoContext, callback); } ]; series(asyncTasks, function(err) { if (err) { return callback(err); } if (perfLogInfoEnabled) { perfLogger.info('Page bundles written in ' + (Date.now() - prevStartTime) + 'ms'); } // All of the bundles have now been persisted, now we can // generate all of the HTML for the page buildHtmlSlots(pageBundles); perfLogger.info('Built page "' + pageName + '" in ' + (Date.now() - startTime) + 'ms'); if (lassoContext.cache) { lassoContext.cache.flushAll(); } callback(null, lassoPageResult); }); });
require('../lib/github').fetchRepos(org, function(err, repos) { if (err) { logger.error('Error fetching GitHub repositories.', err); process.exit(1); return; } var dir = args.dir; var i; var repo; logger.info('Found the following ' + org + ' repositories on GitHub:'); for (i = 0; i < repos.length; i++) { repo = repos[i]; logger.info(repo.name); } logger.info('Cloning or updating raptorjs repositories to ' + dir + '...'); series([ function(callback) { // update git repos if (args['skip-git-update']) { callback(); } else { git.updateRepos(repos, args.dir, logger, function(err) { if (err) { logger.error('Error cloning one or more repos.'); } else { logger.info('All raptorjs repositories cloned or updated successfully.'); } callback(err); }); } }, function(callback) { // remove unneeded modules from node_modules removeUnneeded(repos, args.dir, logger, callback); }, function(callback) { // run npm link if (args['skip-link']) { callback(); } else { // STEP 4: Use "npm link" to link all of the modules for development npm.linkModules(repos, args.dir, logger, function(err) { if (err) { logger.error('Error linking modules.', err); } else { logger.info('All raptorjs modules linked successfully.'); } callback(err); }); } } ], function(err) { if (err) { logger.error('Errors during setup.', err); } else { logger.success('Setup completed successfully.'); } }); });