UNPKG

broccoli-ember-preparse

Version:

Broccoli plugin that applies some compile time performance optimizations to an ember build.

146 lines (131 loc) 3.73 kB
'use strict'; /* jshint node:true */ var Filter = require('broccoli-caching-writer'); var RSVP = require('rsvp'); var processEmber = require('./process-ember'); var walkSync = require('walk-sync'); var fs = require('fs'); var path = require('path'); var debug = require('debug')('define-rewriter'); var DEFAULT_HTMLBARS_EAGER = [ 'ember/index', 'ember-htmlbars/system/render-view', 'ember-metal/streams/key-stream' ]; var DEFAULT_GLIMMER_EAGER = [ 'glimmer-reference/index', 'ember-glimmer/components/checkbox', 'ember-glimmer/components/link-to', 'ember-glimmer/components/text_area', 'ember-glimmer/components/text_field', 'ember-glimmer/renderer', 'ember-glimmer/make-bound-helper', 'ember-glimmer/setup-registry', 'ember-glimmer/views/outlet', 'ember-glimmer/templates/outlet', 'ember-glimmer/templates/component', 'ember-glimmer/dom', 'ember/index' ]; function defaultFilter(node) { if (isUMDModule(node)) { debug('removing UMD module:', node.name); return true; } if (isTSLINTModule(node)) { debug('removing TSLINT module:', node.name); return true; } if (isEmptyModule(node)) { debug('removing empty module:', node.name); return true; } return false; } function isUMDModule(node) { var name = node.name; var l = name.length; return l > 4 && name.charCodeAt(l - 4) === 46 && name.indexOf('umd', l - 3) !== -1; } function isEmptyModule(node) { if (node.functionExpression.body.body.length === 0 && node.deps.length === 1 && node.deps[0] === 'exports') { return true } return false; } function isTSLINTModule(node) { var name = node.name; var l = name.length; return l > 7 && name.charCodeAt(l - 7) === 46 && name.indexOf('tslint', l - 6) !== -1; } /** * NOTES * Need to register modules into requirejs._eak_seen with a shape that looks * like the follow: * * (name: string) = { * deps: string[] * callback: Function * } * * enifed */ function DefineRewriter(inputNode, options) { if (options && options.eagerLoad) { if (Array.isArray(options.eagerLoad)) { this.eagerLoad = options.eagerLoad; } else { this.eagerLoad = [ options.eagerLoad ]; } } else { if (options && options.glimmer) { debug('glimmer'); this.eagerLoad = DEFAULT_GLIMMER_EAGER; } else { this.eagerLoad = DEFAULT_HTMLBARS_EAGER; } } if (options && options.filter) { this.moduleFilter = options.filter; } else { this.moduleFilter = defaultFilter; } Filter.call(this, Array.isArray(inputNode) ? inputNode : [ inputNode ], options); } DefineRewriter.prototype = Object.create(Filter.prototype); DefineRewriter.prototype.constructor = DefineRewriter; var EMBER_PATHS = { 'ember.prod.js': true, 'ember.debug.js': true }; DefineRewriter.prototype.processString = function(string, relativePath) { if (EMBER_PATHS[relativePath]) { // If given return processEmber(string, relativePath, this.eagerLoad, this.moduleFilter); } return string; }; DefineRewriter.prototype.build = function() { var root = this.inputPaths[0]; var outRoot = this.outputPath; var entries = walkSync(root); return RSVP.all(entries.map(function(p) { var fullPath = path.join(root, p); var outPath = path.join(outRoot, p); var stats = fs.statSync(fullPath); if (stats.isFile()) { var contents = fs.readFileSync(fullPath, 'utf8'); return RSVP.resolve(this.processString(contents, p)).then(function(output) { fs.writeFileSync(outPath, output); }); } else if (stats.isDirectory()) { fs.mkdirSync(outPath); return RSVP.resolve(); } }.bind(this))); }; module.exports = DefineRewriter;