From 3f1619b158f2b2abb45a9ff3c7fe63d258159c75 Mon Sep 17 00:00:00 2001 From: Amjad Masad Date: Wed, 12 Aug 2015 11:47:02 -0700 Subject: [PATCH] [react-packager] Rename 'Package' to 'Bundle' Summary: The word Package is overloaded, it may mean npm package, or may mean a collection of bundles. Neither is what we mean. We mean `bundle`. This renames it and modernize some of the Bundler code. --- react-packager/index.js | 13 +- react-packager/src/Bundler/Bundle.js | 307 ++++++++++++++++++ .../__tests__/Bundle-test.js} | 64 ++-- .../__tests__/Bundler-test.js} | 18 +- .../src/{Packager => Bundler}/base64-vlq.js | 0 react-packager/src/Bundler/index.js | 291 +++++++++++++++++ .../DependencyGraph/index.js | 1 - react-packager/src/Packager/Package.js | 300 ----------------- react-packager/src/Packager/index.js | 289 ----------------- .../src/Server/__tests__/Server-test.js | 40 +-- react-packager/src/Server/index.js | 68 ++-- 11 files changed, 702 insertions(+), 689 deletions(-) create mode 100644 react-packager/src/Bundler/Bundle.js rename react-packager/src/{Packager/__tests__/Package-test.js => Bundler/__tests__/Bundle-test.js} (82%) rename react-packager/src/{Packager/__tests__/Packager-test.js => Bundler/__tests__/Bundler-test.js} (94%) rename react-packager/src/{Packager => Bundler}/base64-vlq.js (100%) create mode 100644 react-packager/src/Bundler/index.js delete mode 100644 react-packager/src/Packager/Package.js delete mode 100644 react-packager/src/Packager/index.js diff --git a/react-packager/index.js b/react-packager/index.js index c47d762a..83f31228 100644 --- a/react-packager/index.js +++ b/react-packager/index.js @@ -22,18 +22,23 @@ exports.middleware = function(options) { return server.processRequest.bind(server); }; -exports.buildPackage = function(options, packageOptions) { + +// Renamed "package" to "bundle". But maintain backwards +// compat. +exports.buildPackage = +exports.buildBundle = function(options, bundleOptions) { var server = createServer(options); - return server.buildPackage(packageOptions) + return server.buildBundle(bundleOptions) .then(function(p) { server.end(); return p; }); }; -exports.buildPackageFromUrl = function(options, reqUrl) { +exports.buildPackageFromUrl = +exports.buildBundleFromUrl = function(options, reqUrl) { var server = createServer(options); - return server.buildPackageFromUrl(reqUrl) + return server.buildBundleFromUrl(reqUrl) .then(function(p) { server.end(); return p; diff --git a/react-packager/src/Bundler/Bundle.js b/react-packager/src/Bundler/Bundle.js new file mode 100644 index 00000000..418f7a9e --- /dev/null +++ b/react-packager/src/Bundler/Bundle.js @@ -0,0 +1,307 @@ +/** + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ +'use strict'; + +const _ = require('underscore'); +const base64VLQ = require('./base64-vlq'); +const UglifyJS = require('uglify-js'); +const ModuleTransport = require('../lib/ModuleTransport'); + +const SOURCEMAPPING_URL = '\n\/\/@ sourceMappingURL='; + +class Bundle { + constructor(sourceMapUrl) { + this._finalized = false; + this._modules = []; + this._assets = []; + this._sourceMapUrl = sourceMapUrl; + this._shouldCombineSourceMaps = false; + } + + setMainModuleId(moduleId) { + this._mainModuleId = moduleId; + } + + addModule(module) { + if (!(module instanceof ModuleTransport)) { + throw new Error('Expeceted a ModuleTransport object'); + } + + // If we get a map from the transformer we'll switch to a mode + // were we're combining the source maps as opposed to + if (!this._shouldCombineSourceMaps && module.map != null) { + this._shouldCombineSourceMaps = true; + } + + this._modules.push(module); + } + + getModules() { + return this._modules; + } + + addAsset(asset) { + this._assets.push(asset); + } + + finalize(options) { + options = options || {}; + if (options.runMainModule) { + const runCode = ';require("' + this._mainModuleId + '");'; + this.addModule(new ModuleTransport({ + code: runCode, + virtual: true, + sourceCode: runCode, + sourcePath: 'RunMainModule.js' + })); + } + + Object.freeze(this._modules); + Object.seal(this._modules); + Object.freeze(this._assets); + Object.seal(this._assets); + this._finalized = true; + } + + _assertFinalized() { + if (!this._finalized) { + throw new Error('Bundle needs to be finalized before getting any source'); + } + } + + _getSource() { + if (this._source == null) { + this._source = _.pluck(this._modules, 'code').join('\n'); + } + return this._source; + } + + _getInlineSourceMap() { + if (this._inlineSourceMap == null) { + const sourceMap = this.getSourceMap({excludeSource: true}); + /*eslint-env node*/ + const encoded = new Buffer(JSON.stringify(sourceMap)).toString('base64'); + this._inlineSourceMap = 'data:application/json;base64,' + encoded; + } + return this._inlineSourceMap; + } + + getSource(options) { + this._assertFinalized(); + + options = options || {}; + + if (options.minify) { + return this.getMinifiedSourceAndMap().code; + } + + let source = this._getSource(); + + if (options.inlineSourceMap) { + source += SOURCEMAPPING_URL + this._getInlineSourceMap(); + } else if (this._sourceMapUrl) { + source += SOURCEMAPPING_URL + this._sourceMapUrl; + } + + return source; + } + + getMinifiedSourceAndMap() { + this._assertFinalized(); + + const source = this._getSource(); + try { + return UglifyJS.minify(source, { + fromString: true, + outSourceMap: 'bundle.js', + inSourceMap: this.getSourceMap(), + }); + } catch(e) { + // Sometimes, when somebody is using a new syntax feature that we + // don't yet have transform for, the untransformed line is sent to + // uglify, and it chokes on it. This code tries to print the line + // and the module for easier debugging + let errorMessage = 'Error while minifying JS\n'; + if (e.line) { + errorMessage += 'Transformed code line: "' + + source.split('\n')[e.line - 1] + '"\n'; + } + if (e.pos) { + let fromIndex = source.lastIndexOf('__d(\'', e.pos); + if (fromIndex > -1) { + fromIndex += '__d(\''.length; + const toIndex = source.indexOf('\'', fromIndex); + errorMessage += 'Module name (best guess): ' + + source.substring(fromIndex, toIndex) + '\n'; + } + } + errorMessage += e.toString(); + throw new Error(errorMessage); + } + } + + /** + * I found a neat trick in the sourcemap spec that makes it easy + * to concat sourcemaps. The `sections` field allows us to combine + * the sourcemap easily by adding an offset. Tested on chrome. + * Seems like it's not yet in Firefox but that should be fine for + * now. + */ + _getCombinedSourceMaps(options) { + const result = { + version: 3, + file: 'bundle.js', + sections: [], + }; + + let line = 0; + this._modules.forEach(function(module) { + let map = module.map; + if (module.virtual) { + map = generateSourceMapForVirtualModule(module); + } + + if (options.excludeSource) { + map = _.extend({}, map, {sourcesContent: []}); + } + + result.sections.push({ + offset: { line: line, column: 0 }, + map: map, + }); + line += module.code.split('\n').length; + }); + + return result; + } + + getSourceMap(options) { + this._assertFinalized(); + + options = options || {}; + + if (this._shouldCombineSourceMaps) { + return this._getCombinedSourceMaps(options); + } + + const mappings = this._getMappings(); + const map = { + file: 'bundle.js', + sources: _.pluck(this._modules, 'sourcePath'), + version: 3, + names: [], + mappings: mappings, + sourcesContent: options.excludeSource + ? [] : _.pluck(this._modules, 'sourceCode') + }; + return map; + } + + getAssets() { + return this._assets; + } + + _getMappings() { + const modules = this._modules; + + // The first line mapping in our package is basically the base64vlq code for + // zeros (A). + const firstLine = 'AAAA'; + + // Most other lines in our mappings are all zeros (for module, column etc) + // except for the lineno mappinp: curLineno - prevLineno = 1; Which is C. + const line = 'AACA'; + + const moduleLines = Object.create(null); + let mappings = ''; + for (let i = 0; i < modules.length; i++) { + const module = modules[i]; + const code = module.code; + let lastCharNewLine = false; + moduleLines[module.sourcePath] = 0; + for (let t = 0; t < code.length; t++) { + if (t === 0 && i === 0) { + mappings += firstLine; + } else if (t === 0) { + mappings += 'AC'; + + // This is the only place were we actually don't know the mapping ahead + // of time. When it's a new module (and not the first) the lineno + // mapping is 0 (current) - number of lines in prev module. + mappings += base64VLQ.encode( + 0 - moduleLines[modules[i - 1].sourcePath] + ); + mappings += 'A'; + } else if (lastCharNewLine) { + moduleLines[module.sourcePath]++; + mappings += line; + } + lastCharNewLine = code[t] === '\n'; + if (lastCharNewLine) { + mappings += ';'; + } + } + if (i !== modules.length - 1) { + mappings += ';'; + } + } + return mappings; + } + + getJSModulePaths() { + return this._modules.filter(function(module) { + // Filter out non-js files. Like images etc. + return !module.virtual; + }).map(function(module) { + return module.sourcePath; + }); + } + + getDebugInfo() { + return [ + '

Main Module:

' + this._mainModuleId + '
', + '', + '

Module paths and transformed code:

', + this._modules.map(function(m) { + return '

Path:

' + m.sourcePath + '

Source:

' + + '
'; + }).join('\n'), + ].join('\n'); + } +} + +function generateSourceMapForVirtualModule(module) { + // All lines map 1-to-1 + let mappings = 'AAAA;'; + + for (let i = 1; i < module.code.split('\n').length; i++) { + mappings += 'AACA;'; + } + + return { + version: 3, + sources: [ module.sourcePath ], + names: [], + mappings: mappings, + file: module.sourcePath, + sourcesContent: [ module.sourceCode ], + }; +} + +module.exports = Bundle; diff --git a/react-packager/src/Packager/__tests__/Package-test.js b/react-packager/src/Bundler/__tests__/Bundle-test.js similarity index 82% rename from react-packager/src/Packager/__tests__/Package-test.js rename to react-packager/src/Bundler/__tests__/Bundle-test.js index d43c65c0..74d18924 100644 --- a/react-packager/src/Packager/__tests__/Package-test.js +++ b/react-packager/src/Bundler/__tests__/Bundle-test.js @@ -12,35 +12,35 @@ jest.autoMockOff(); var SourceMapGenerator = require('source-map').SourceMapGenerator; -describe('Package', function() { +describe('Bundle', function() { var ModuleTransport; - var Package; - var ppackage; + var Bundle; + var bundle; beforeEach(function() { - Package = require('../Package'); + Bundle = require('../Bundle'); ModuleTransport = require('../../lib/ModuleTransport'); - ppackage = new Package('test_url'); - ppackage.getSourceMap = jest.genMockFn().mockImpl(function() { + bundle = new Bundle('test_url'); + bundle.getSourceMap = jest.genMockFn().mockImpl(function() { return 'test-source-map'; }); }); - describe('source package', function() { - it('should create a package and get the source', function() { - ppackage.addModule(new ModuleTransport({ + describe('source bundle', function() { + it('should create a bundle and get the source', function() { + bundle.addModule(new ModuleTransport({ code: 'transformed foo;', sourceCode: 'source foo', sourcePath: 'foo path', })); - ppackage.addModule(new ModuleTransport({ + bundle.addModule(new ModuleTransport({ code: 'transformed bar;', sourceCode: 'source bar', sourcePath: 'bar path', })); - ppackage.finalize({}); - expect(ppackage.getSource()).toBe([ + bundle.finalize({}); + expect(bundle.getSource()).toBe([ 'transformed foo;', 'transformed bar;', '\/\/@ sourceMappingURL=test_url' @@ -48,7 +48,7 @@ describe('Package', function() { }); it('should be ok to leave out the source map url', function() { - var p = new Package(); + var p = new Bundle(); p.addModule(new ModuleTransport({ code: 'transformed foo;', sourceCode: 'source foo', @@ -67,22 +67,22 @@ describe('Package', function() { ].join('\n')); }); - it('should create a package and add run module code', function() { - ppackage.addModule(new ModuleTransport({ + it('should create a bundle and add run module code', function() { + bundle.addModule(new ModuleTransport({ code: 'transformed foo;', sourceCode: 'source foo', sourcePath: 'foo path' })); - ppackage.addModule(new ModuleTransport({ + bundle.addModule(new ModuleTransport({ code: 'transformed bar;', sourceCode: 'source bar', sourcePath: 'bar path' })); - ppackage.setMainModuleId('foo'); - ppackage.finalize({runMainModule: true}); - expect(ppackage.getSource()).toBe([ + bundle.setMainModuleId('foo'); + bundle.finalize({runMainModule: true}); + expect(bundle.getSource()).toBe([ 'transformed foo;', 'transformed bar;', ';require("foo");', @@ -100,19 +100,19 @@ describe('Package', function() { return minified; }; - ppackage.addModule(new ModuleTransport({ + bundle.addModule(new ModuleTransport({ code: 'transformed foo;', sourceCode: 'source foo', sourcePath: 'foo path' })); - ppackage.finalize(); - expect(ppackage.getMinifiedSourceAndMap()).toBe(minified); + bundle.finalize(); + expect(bundle.getMinifiedSourceAndMap()).toBe(minified); }); }); - describe('sourcemap package', function() { + describe('sourcemap bundle', function() { it('should create sourcemap', function() { - var p = new Package('test_url'); + var p = new Bundle('test_url'); p.addModule(new ModuleTransport({ code: [ 'transformed foo', @@ -143,11 +143,11 @@ describe('Package', function() { p.setMainModuleId('foo'); p.finalize({runMainModule: true}); var s = p.getSourceMap(); - expect(s).toEqual(genSourceMap(p._modules)); + expect(s).toEqual(genSourceMap(p.getModules())); }); it('should combine sourcemaps', function() { - var p = new Package('test_url'); + var p = new Bundle('test_url'); p.addModule(new ModuleTransport({ code: 'transformed foo;\n', @@ -215,7 +215,7 @@ describe('Package', function() { describe('getAssets()', function() { it('should save and return asset objects', function() { - var p = new Package('test_url'); + var p = new Bundle('test_url'); var asset1 = {}; var asset2 = {}; p.addAsset(asset1); @@ -227,7 +227,7 @@ describe('Package', function() { describe('getJSModulePaths()', function() { it('should return module paths', function() { - var p = new Package('test_url'); + var p = new Bundle('test_url'); p.addModule(new ModuleTransport({ code: 'transformed foo;\n', sourceCode: 'source foo', @@ -248,7 +248,7 @@ describe('Package', function() { function genSourceMap(modules) { var sourceMapGen = new SourceMapGenerator({file: 'bundle.js', version: 3}); - var packageLineNo = 0; + var bundleLineNo = 0; for (var i = 0; i < modules.length; i++) { var module = modules[i]; var transformedCode = module.code; @@ -259,7 +259,7 @@ describe('Package', function() { for (var t = 0; t < transformedCode.length; t++) { if (t === 0 || lastCharNewLine) { sourceMapGen.addMapping({ - generated: {line: packageLineNo + 1, column: 0}, + generated: {line: bundleLineNo + 1, column: 0}, original: {line: transformedLineCount + 1, column: 0}, source: sourcePath }); @@ -267,10 +267,10 @@ describe('Package', function() { lastCharNewLine = transformedCode[t] === '\n'; if (lastCharNewLine) { transformedLineCount++; - packageLineNo++; + bundleLineNo++; } } - packageLineNo++; + bundleLineNo++; sourceMapGen.setSourceContent( sourcePath, sourceCode diff --git a/react-packager/src/Packager/__tests__/Packager-test.js b/react-packager/src/Bundler/__tests__/Bundler-test.js similarity index 94% rename from react-packager/src/Packager/__tests__/Packager-test.js rename to react-packager/src/Bundler/__tests__/Bundler-test.js index 216e9009..a66bc059 100644 --- a/react-packager/src/Packager/__tests__/Packager-test.js +++ b/react-packager/src/Bundler/__tests__/Bundler-test.js @@ -9,7 +9,7 @@ 'use strict'; jest - .setMock('worker-farm', function() { return function() {};}) + .setMock('worker-farm', () => () => undefined) .dontMock('underscore') .dontMock('../../lib/ModuleTransport') .setMock('uglify-js') @@ -19,11 +19,11 @@ jest.mock('fs'); var Promise = require('promise'); -describe('Packager', function() { +describe('Bundler', function() { var getDependencies; var wrapModule; - var Packager; - var packager; + var Bundler; + var bundler; var assetServer; var modules; @@ -37,7 +37,7 @@ describe('Packager', function() { }; }); - Packager = require('../'); + Bundler = require('../'); require('fs').statSync.mockImpl(function() { return { @@ -53,7 +53,7 @@ describe('Packager', function() { getAssetData: jest.genMockFn(), }; - packager = new Packager({ + bundler = new Bundler({ projectRoots: ['/root'], assetServer: assetServer, }); @@ -118,8 +118,8 @@ describe('Packager', function() { }); }); - pit('create a package', function() { - return packager.package('/root/foo.js', true, 'source_map_url') + pit('create a bundle', function() { + return bundler.bundle('/root/foo.js', true, 'source_map_url') .then(function(p) { expect(p.addModule.mock.calls[0][0]).toEqual({ code: 'lol transformed /root/foo.js lol', @@ -204,7 +204,7 @@ describe('Packager', function() { }); pit('gets the list of dependencies', function() { - return packager.getDependencies('/root/foo.js', true) + return bundler.getDependencies('/root/foo.js', true) .then(({dependencies}) => { expect(dependencies).toEqual([ { diff --git a/react-packager/src/Packager/base64-vlq.js b/react-packager/src/Bundler/base64-vlq.js similarity index 100% rename from react-packager/src/Packager/base64-vlq.js rename to react-packager/src/Bundler/base64-vlq.js diff --git a/react-packager/src/Bundler/index.js b/react-packager/src/Bundler/index.js new file mode 100644 index 00000000..e7ea1249 --- /dev/null +++ b/react-packager/src/Bundler/index.js @@ -0,0 +1,291 @@ +/** + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ +'use strict'; + +const assert = require('assert'); +const fs = require('fs'); +const path = require('path'); +const Promise = require('promise'); +const Cache = require('../Cache'); +const Transformer = require('../JSTransformer'); +const DependencyResolver = require('../DependencyResolver'); +const Bundle = require('./Bundle'); +const Activity = require('../Activity'); +const ModuleTransport = require('../lib/ModuleTransport'); +const declareOpts = require('../lib/declareOpts'); +const imageSize = require('image-size'); + +const sizeOf = Promise.denodeify(imageSize); +const readFile = Promise.denodeify(fs.readFile); + +const validateOpts = declareOpts({ + projectRoots: { + type: 'array', + required: true, + }, + blacklistRE: { + type: 'object', // typeof regex is object + }, + moduleFormat: { + type: 'string', + default: 'haste', + }, + polyfillModuleNames: { + type: 'array', + default: [], + }, + cacheVersion: { + type: 'string', + default: '1.0', + }, + resetCache: { + type: 'boolean', + default: false, + }, + transformModulePath: { + type:'string', + required: false, + }, + nonPersistent: { + type: 'boolean', + default: false, + }, + assetRoots: { + type: 'array', + required: false, + }, + assetExts: { + type: 'array', + default: ['png'], + }, + fileWatcher: { + type: 'object', + required: true, + }, + assetServer: { + type: 'object', + required: true, + } +}); + +class Bundler { + + constructor(options) { + const opts = this._opts = validateOpts(options); + + opts.projectRoots.forEach(verifyRootExists); + + this._cache = opts.nonPersistent + ? new DummyCache() + : new Cache({ + resetCache: opts.resetCache, + cacheVersion: opts.cacheVersion, + projectRoots: opts.projectRoots, + transformModulePath: opts.transformModulePath, + }); + + this._resolver = new DependencyResolver({ + projectRoots: opts.projectRoots, + blacklistRE: opts.blacklistRE, + polyfillModuleNames: opts.polyfillModuleNames, + nonPersistent: opts.nonPersistent, + moduleFormat: opts.moduleFormat, + assetRoots: opts.assetRoots, + fileWatcher: opts.fileWatcher, + assetExts: opts.assetExts, + cache: this._cache, + }); + + this._transformer = new Transformer({ + projectRoots: opts.projectRoots, + blacklistRE: opts.blacklistRE, + cache: this._cache, + transformModulePath: opts.transformModulePath, + }); + + this._projectRoots = opts.projectRoots; + this._assetServer = opts.assetServer; + } + + kill() { + this._transformer.kill(); + return this._cache.end(); + } + + bundle(main, runModule, sourceMapUrl, isDev) { + const bundle = new Bundle(sourceMapUrl); + + const transformModule = this._transformModule.bind(this, bundle); + const findEventId = Activity.startEvent('find dependencies'); + let transformEventId; + + return this.getDependencies(main, isDev) + .then(function(result) { + Activity.endEvent(findEventId); + transformEventId = Activity.startEvent('transform'); + + bundle.setMainModuleId(result.mainModuleId); + return Promise.all( + result.dependencies.map(transformModule) + ); + }) + .then(function(transformedModules) { + Activity.endEvent(transformEventId); + + transformedModules.forEach(function(moduleTransport) { + bundle.addModule(moduleTransport); + }); + + bundle.finalize({ runMainModule: runModule }); + return bundle; + }); + } + + invalidateFile(filePath) { + this._transformer.invalidateFile(filePath); + } + + getDependencies(main, isDev) { + return this._resolver.getDependencies(main, { dev: isDev }); + } + + _transformModule(bundle, module) { + let transform; + + if (module.isAsset_DEPRECATED) { + transform = this.generateAssetModule_DEPRECATED(bundle, module); + } else if (module.isAsset) { + transform = this.generateAssetModule(bundle, module); + } else if (module.isJSON) { + transform = generateJSONModule(module); + } else { + transform = this._transformer.loadFileAndTransform( + path.resolve(module.path) + ); + } + + const resolver = this._resolver; + return transform.then( + transformed => resolver.wrapModule(module, transformed.code).then( + code => new ModuleTransport({ + code: code, + map: transformed.map, + sourceCode: transformed.sourceCode, + sourcePath: transformed.sourcePath, + virtual: transformed.virtual, + }) + ) + ); + } + + getGraphDebugInfo() { + return this._resolver.getDebugInfo(); + } + + generateAssetModule_DEPRECATED(bundle, module) { + return sizeOf(module.path).then(function(dimensions) { + const img = { + __packager_asset: true, + isStatic: true, + path: module.path, + uri: module.id.replace(/^[^!]+!/, ''), + width: dimensions.width / module.resolution, + height: dimensions.height / module.resolution, + deprecated: true, + }; + + bundle.addAsset(img); + + const code = 'module.exports = ' + JSON.stringify(img) + ';'; + + return new ModuleTransport({ + code: code, + sourceCode: code, + sourcePath: module.path, + virtual: true, + }); + }); + } + + generateAssetModule(bundle, module) { + const relPath = getPathRelativeToRoot(this._projectRoots, module.path); + + return Promise.all([ + sizeOf(module.path), + this._assetServer.getAssetData(relPath), + ]).then(function(res) { + const dimensions = res[0]; + const assetData = res[1]; + const img = { + __packager_asset: true, + fileSystemLocation: path.dirname(module.path), + httpServerLocation: path.join('/assets', path.dirname(relPath)), + width: dimensions.width / module.resolution, + height: dimensions.height / module.resolution, + scales: assetData.scales, + hash: assetData.hash, + name: assetData.name, + type: assetData.type, + }; + + bundle.addAsset(img); + + const ASSET_TEMPLATE = 'module.exports = require("AssetRegistry").registerAsset(%json);'; + const code = ASSET_TEMPLATE.replace('%json', JSON.stringify(img)); + + return new ModuleTransport({ + code: code, + sourceCode: code, + sourcePath: module.path, + virtual: true, + }); + }); + } +} + +function generateJSONModule(module) { + return readFile(module.path).then(function(data) { + const code = 'module.exports = ' + data.toString('utf8') + ';'; + + return new ModuleTransport({ + code: code, + sourceCode: code, + sourcePath: module.path, + virtual: true, + }); + }); +} + +function getPathRelativeToRoot(roots, absPath) { + for (let i = 0; i < roots.length; i++) { + const relPath = path.relative(roots[i], absPath); + if (relPath[0] !== '.') { + return relPath; + } + } + + throw new Error( + 'Expected root module to be relative to one of the project roots' + ); +} + +function verifyRootExists(root) { + // Verify that the root exists. + assert(fs.statSync(root).isDirectory(), 'Root has to be a valid directory'); +} + +class DummyCache { + get(filepath, field, loaderCb) { + return loaderCb(); + } + + end(){} + invalidate(filepath){} +} +module.exports = Bundler; diff --git a/react-packager/src/DependencyResolver/DependencyGraph/index.js b/react-packager/src/DependencyResolver/DependencyGraph/index.js index 7e718582..d4cced0c 100644 --- a/react-packager/src/DependencyResolver/DependencyGraph/index.js +++ b/react-packager/src/DependencyResolver/DependencyGraph/index.js @@ -13,7 +13,6 @@ const AssetModule_DEPRECATED = require('../AssetModule_DEPRECATED'); const Fastfs = require('../fastfs'); const ModuleCache = require('../ModuleCache'); const Promise = require('promise'); -const _ = require('underscore'); const crawl = require('../crawlers'); const debug = require('debug')('DependencyGraph'); const declareOpts = require('../../lib/declareOpts'); diff --git a/react-packager/src/Packager/Package.js b/react-packager/src/Packager/Package.js deleted file mode 100644 index 6b538946..00000000 --- a/react-packager/src/Packager/Package.js +++ /dev/null @@ -1,300 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ -'use strict'; - -var _ = require('underscore'); -var base64VLQ = require('./base64-vlq'); -var UglifyJS = require('uglify-js'); -var ModuleTransport = require('../lib/ModuleTransport'); - -module.exports = Package; - -var SOURCEMAPPING_URL = '\n\/\/@ sourceMappingURL='; - -function Package(sourceMapUrl) { - this._finalized = false; - this._modules = []; - this._assets = []; - this._sourceMapUrl = sourceMapUrl; - this._shouldCombineSourceMaps = false; -} - -Package.prototype.setMainModuleId = function(moduleId) { - this._mainModuleId = moduleId; -}; - -Package.prototype.addModule = function(module) { - if (!(module instanceof ModuleTransport)) { - throw new Error('Expeceted a ModuleTransport object'); - } - - // If we get a map from the transformer we'll switch to a mode - // were we're combining the source maps as opposed to - if (!this._shouldCombineSourceMaps && module.map != null) { - this._shouldCombineSourceMaps = true; - } - - this._modules.push(module); -}; - -Package.prototype.addAsset = function(asset) { - this._assets.push(asset); -}; - -Package.prototype.finalize = function(options) { - options = options || {}; - if (options.runMainModule) { - var runCode = ';require("' + this._mainModuleId + '");'; - this.addModule(new ModuleTransport({ - code: runCode, - virtual: true, - sourceCode: runCode, - sourcePath: 'RunMainModule.js' - })); - } - - Object.freeze(this._modules); - Object.seal(this._modules); - Object.freeze(this._assets); - Object.seal(this._assets); - this._finalized = true; -}; - -Package.prototype._assertFinalized = function() { - if (!this._finalized) { - throw new Error('Package need to be finalized before getting any source'); - } -}; - -Package.prototype._getSource = function() { - if (this._source == null) { - this._source = _.pluck(this._modules, 'code').join('\n'); - } - return this._source; -}; - -Package.prototype._getInlineSourceMap = function() { - if (this._inlineSourceMap == null) { - var sourceMap = this.getSourceMap({excludeSource: true}); - var encoded = new Buffer(JSON.stringify(sourceMap)).toString('base64'); - this._inlineSourceMap = 'data:application/json;base64,' + encoded; - } - return this._inlineSourceMap; -}; - -Package.prototype.getSource = function(options) { - this._assertFinalized(); - - options = options || {}; - - if (options.minify) { - return this.getMinifiedSourceAndMap().code; - } - - var source = this._getSource(); - - if (options.inlineSourceMap) { - source += SOURCEMAPPING_URL + this._getInlineSourceMap(); - } else if (this._sourceMapUrl) { - source += SOURCEMAPPING_URL + this._sourceMapUrl; - } - - return source; -}; - -Package.prototype.getMinifiedSourceAndMap = function() { - this._assertFinalized(); - - var source = this._getSource(); - try { - return UglifyJS.minify(source, { - fromString: true, - outSourceMap: 'bundle.js', - inSourceMap: this.getSourceMap(), - }); - } catch(e) { - // Sometimes, when somebody is using a new syntax feature that we - // don't yet have transform for, the untransformed line is sent to - // uglify, and it chokes on it. This code tries to print the line - // and the module for easier debugging - var errorMessage = 'Error while minifying JS\n'; - if (e.line) { - errorMessage += 'Transformed code line: "' + - source.split('\n')[e.line - 1] + '"\n'; - } - if (e.pos) { - var fromIndex = source.lastIndexOf('__d(\'', e.pos); - if (fromIndex > -1) { - fromIndex += '__d(\''.length; - var toIndex = source.indexOf('\'', fromIndex); - errorMessage += 'Module name (best guess): ' + - source.substring(fromIndex, toIndex) + '\n'; - } - } - errorMessage += e.toString(); - throw new Error(errorMessage); - } -}; - -/** - * I found a neat trick in the sourcemap spec that makes it easy - * to concat sourcemaps. The `sections` field allows us to combine - * the sourcemap easily by adding an offset. Tested on chrome. - * Seems like it's not yet in Firefox but that should be fine for - * now. - */ -Package.prototype._getCombinedSourceMaps = function(options) { - var result = { - version: 3, - file: 'bundle.js', - sections: [], - }; - - var line = 0; - this._modules.forEach(function(module) { - var map = module.map; - if (module.virtual) { - map = generateSourceMapForVirtualModule(module); - } - - if (options.excludeSource) { - map = _.extend({}, map, {sourcesContent: []}); - } - - result.sections.push({ - offset: { line: line, column: 0 }, - map: map, - }); - line += module.code.split('\n').length; - }); - - return result; -}; - -Package.prototype.getSourceMap = function(options) { - this._assertFinalized(); - - options = options || {}; - - if (this._shouldCombineSourceMaps) { - return this._getCombinedSourceMaps(options); - } - - var mappings = this._getMappings(); - var map = { - file: 'bundle.js', - sources: _.pluck(this._modules, 'sourcePath'), - version: 3, - names: [], - mappings: mappings, - sourcesContent: options.excludeSource - ? [] : _.pluck(this._modules, 'sourceCode') - }; - return map; -}; - -Package.prototype.getAssets = function() { - return this._assets; -}; - -Package.prototype._getMappings = function() { - var modules = this._modules; - - // The first line mapping in our package is basically the base64vlq code for - // zeros (A). - var firstLine = 'AAAA'; - - // Most other lines in our mappings are all zeros (for module, column etc) - // except for the lineno mappinp: curLineno - prevLineno = 1; Which is C. - var line = 'AACA'; - - var moduleLines = Object.create(null); - var mappings = ''; - for (var i = 0; i < modules.length; i++) { - var module = modules[i]; - var code = module.code; - var lastCharNewLine = false; - moduleLines[module.sourcePath] = 0; - for (var t = 0; t < code.length; t++) { - if (t === 0 && i === 0) { - mappings += firstLine; - } else if (t === 0) { - mappings += 'AC'; - - // This is the only place were we actually don't know the mapping ahead - // of time. When it's a new module (and not the first) the lineno - // mapping is 0 (current) - number of lines in prev module. - mappings += base64VLQ.encode( - 0 - moduleLines[modules[i - 1].sourcePath] - ); - mappings += 'A'; - } else if (lastCharNewLine) { - moduleLines[module.sourcePath]++; - mappings += line; - } - lastCharNewLine = code[t] === '\n'; - if (lastCharNewLine) { - mappings += ';'; - } - } - if (i !== modules.length - 1) { - mappings += ';'; - } - } - return mappings; -}; - -Package.prototype.getJSModulePaths = function() { - return this._modules.filter(function(module) { - // Filter out non-js files. Like images etc. - return !module.virtual; - }).map(function(module) { - return module.sourcePath; - }); -}; - -Package.prototype.getDebugInfo = function() { - return [ - '

Main Module:

' + this._mainModuleId + '
', - '', - '

Module paths and transformed code:

', - this._modules.map(function(m) { - return '

Path:

' + m.sourcePath + '

Source:

' + - '
'; - }).join('\n'), - ].join('\n'); -}; - -function generateSourceMapForVirtualModule(module) { - // All lines map 1-to-1 - var mappings = 'AAAA;'; - - for (var i = 1; i < module.code.split('\n').length; i++) { - mappings += 'AACA;'; - } - - return { - version: 3, - sources: [ module.sourcePath ], - names: [], - mappings: mappings, - file: module.sourcePath, - sourcesContent: [ module.sourceCode ], - }; -} diff --git a/react-packager/src/Packager/index.js b/react-packager/src/Packager/index.js deleted file mode 100644 index a718bd26..00000000 --- a/react-packager/src/Packager/index.js +++ /dev/null @@ -1,289 +0,0 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ -'use strict'; - -var assert = require('assert'); -var fs = require('fs'); -var path = require('path'); -var Promise = require('promise'); -var Cache = require('../Cache'); -var Transformer = require('../JSTransformer'); -var DependencyResolver = require('../DependencyResolver'); -var Package = require('./Package'); -var Activity = require('../Activity'); -var ModuleTransport = require('../lib/ModuleTransport'); -var declareOpts = require('../lib/declareOpts'); -var imageSize = require('image-size'); - -var sizeOf = Promise.denodeify(imageSize); -var readFile = Promise.denodeify(fs.readFile); - -var validateOpts = declareOpts({ - projectRoots: { - type: 'array', - required: true, - }, - blacklistRE: { - type: 'object', // typeof regex is object - }, - moduleFormat: { - type: 'string', - default: 'haste', - }, - polyfillModuleNames: { - type: 'array', - default: [], - }, - cacheVersion: { - type: 'string', - default: '1.0', - }, - resetCache: { - type: 'boolean', - default: false, - }, - transformModulePath: { - type:'string', - required: false, - }, - nonPersistent: { - type: 'boolean', - default: false, - }, - assetRoots: { - type: 'array', - required: false, - }, - assetExts: { - type: 'array', - default: ['png'], - }, - fileWatcher: { - type: 'object', - required: true, - }, - assetServer: { - type: 'object', - required: true, - } -}); - -function Packager(options) { - var opts = this._opts = validateOpts(options); - - opts.projectRoots.forEach(verifyRootExists); - - this._cache = opts.nonPersistent - ? new DummyCache() - : new Cache({ - resetCache: opts.resetCache, - cacheVersion: opts.cacheVersion, - projectRoots: opts.projectRoots, - transformModulePath: opts.transformModulePath, - }); - - this._resolver = new DependencyResolver({ - projectRoots: opts.projectRoots, - blacklistRE: opts.blacklistRE, - polyfillModuleNames: opts.polyfillModuleNames, - nonPersistent: opts.nonPersistent, - moduleFormat: opts.moduleFormat, - assetRoots: opts.assetRoots, - fileWatcher: opts.fileWatcher, - assetExts: opts.assetExts, - cache: this._cache, - }); - - this._transformer = new Transformer({ - projectRoots: opts.projectRoots, - blacklistRE: opts.blacklistRE, - cache: this._cache, - transformModulePath: opts.transformModulePath, - }); - - this._projectRoots = opts.projectRoots; - this._assetServer = opts.assetServer; -} - -Packager.prototype.kill = function() { - this._transformer.kill(); - return this._cache.end(); -}; - -Packager.prototype.package = function(main, runModule, sourceMapUrl, isDev) { - var ppackage = new Package(sourceMapUrl); - - var transformModule = this._transformModule.bind(this, ppackage); - var findEventId = Activity.startEvent('find dependencies'); - var transformEventId; - - return this.getDependencies(main, isDev) - .then(function(result) { - Activity.endEvent(findEventId); - transformEventId = Activity.startEvent('transform'); - - ppackage.setMainModuleId(result.mainModuleId); - return Promise.all( - result.dependencies.map(transformModule) - ); - }) - .then(function(transformedModules) { - Activity.endEvent(transformEventId); - - transformedModules.forEach(function(moduleTransport) { - ppackage.addModule(moduleTransport); - }); - - ppackage.finalize({ runMainModule: runModule }); - return ppackage; - }); -}; - -Packager.prototype.invalidateFile = function(filePath) { - this._transformer.invalidateFile(filePath); -}; - -Packager.prototype.getDependencies = function(main, isDev) { - return this._resolver.getDependencies(main, { dev: isDev }); -}; - -Packager.prototype._transformModule = function(ppackage, module) { - var transform; - - if (module.isAsset_DEPRECATED) { - transform = this.generateAssetModule_DEPRECATED(ppackage, module); - } else if (module.isAsset) { - transform = this.generateAssetModule(ppackage, module); - } else if (module.isJSON) { - transform = generateJSONModule(module); - } else { - transform = this._transformer.loadFileAndTransform( - path.resolve(module.path) - ); - } - - var resolver = this._resolver; - return transform.then( - transformed => resolver.wrapModule(module, transformed.code).then( - code => new ModuleTransport({ - code: code, - map: transformed.map, - sourceCode: transformed.sourceCode, - sourcePath: transformed.sourcePath, - virtual: transformed.virtual, - }) - ) - ); -}; - -Packager.prototype.getGraphDebugInfo = function() { - return this._resolver.getDebugInfo(); -}; - -Packager.prototype.generateAssetModule_DEPRECATED = function(ppackage, module) { - return sizeOf(module.path).then(function(dimensions) { - var img = { - __packager_asset: true, - isStatic: true, - path: module.path, - uri: module.id.replace(/^[^!]+!/, ''), - width: dimensions.width / module.resolution, - height: dimensions.height / module.resolution, - deprecated: true, - }; - - ppackage.addAsset(img); - - var code = 'module.exports = ' + JSON.stringify(img) + ';'; - - return new ModuleTransport({ - code: code, - sourceCode: code, - sourcePath: module.path, - virtual: true, - }); - }); -}; - -Packager.prototype.generateAssetModule = function(ppackage, module) { - var relPath = getPathRelativeToRoot(this._projectRoots, module.path); - - return Promise.all([ - sizeOf(module.path), - this._assetServer.getAssetData(relPath), - ]).then(function(res) { - var dimensions = res[0]; - var assetData = res[1]; - var img = { - __packager_asset: true, - fileSystemLocation: path.dirname(module.path), - httpServerLocation: path.join('/assets', path.dirname(relPath)), - width: dimensions.width / module.resolution, - height: dimensions.height / module.resolution, - scales: assetData.scales, - hash: assetData.hash, - name: assetData.name, - type: assetData.type, - }; - - ppackage.addAsset(img); - - var ASSET_TEMPLATE = 'module.exports = require("AssetRegistry").registerAsset(%json);'; - var code = ASSET_TEMPLATE.replace('%json', JSON.stringify(img)); - - return new ModuleTransport({ - code: code, - sourceCode: code, - sourcePath: module.path, - virtual: true, - }); - }); -}; - -function generateJSONModule(module) { - return readFile(module.path).then(function(data) { - var code = 'module.exports = ' + data.toString('utf8') + ';'; - - return new ModuleTransport({ - code: code, - sourceCode: code, - sourcePath: module.path, - virtual: true, - }); - }); -} - -function getPathRelativeToRoot(roots, absPath) { - for (var i = 0; i < roots.length; i++) { - var relPath = path.relative(roots[i], absPath); - if (relPath[0] !== '.') { - return relPath; - } - } - - throw new Error( - 'Expected root module to be relative to one of the project roots' - ); -} - -function verifyRootExists(root) { - // Verify that the root exists. - assert(fs.statSync(root).isDirectory(), 'Root has to be a valid directory'); -} - -class DummyCache { - get(filepath, field, loaderCb) { - return loaderCb(); - } - - end(){} - invalidate(filepath){} -} - -module.exports = Packager; diff --git a/react-packager/src/Server/__tests__/Server-test.js b/react-packager/src/Server/__tests__/Server-test.js index 7d399cb2..5461b89f 100644 --- a/react-packager/src/Server/__tests__/Server-test.js +++ b/react-packager/src/Server/__tests__/Server-test.js @@ -24,7 +24,7 @@ var Promise = require('promise'); describe('processRequest', function() { var server; - var Packager; + var Bundler; var FileWatcher; var options = { @@ -57,10 +57,10 @@ describe('processRequest', function() { var triggerFileChange; beforeEach(function() { - Packager = require('../../Packager'); + Bundler = require('../../Bundler'); FileWatcher = require('../../FileWatcher'); - Packager.prototype.package = jest.genMockFunction().mockImpl(function() { + Bundler.prototype.bundle = jest.genMockFunction().mockImpl(function() { return Promise.resolve({ getSource: function() { return 'this is the source'; @@ -81,7 +81,7 @@ describe('processRequest', function() { return this; }; - Packager.prototype.invalidateFile = invalidatorFunc; + Bundler.prototype.invalidateFile = invalidatorFunc; var Server = require('../'); server = new Server(options); @@ -121,7 +121,7 @@ describe('processRequest', function() { 'index.ios.includeRequire.bundle' ).then(function(response) { expect(response).toEqual('this is the source'); - expect(Packager.prototype.package).toBeCalledWith( + expect(Bundler.prototype.bundle).toBeCalledWith( 'index.ios.js', true, 'index.ios.includeRequire.map', @@ -142,7 +142,7 @@ describe('processRequest', function() { describe('file changes', function() { - pit('invalides files in package when file is updated', function() { + pit('invalides files in bundle when file is updated', function() { return makeRequest( requestHandler, 'mybundle.bundle?runModule=true' @@ -153,9 +153,9 @@ describe('processRequest', function() { }); }); - pit('rebuilds the packages that contain a file when that file is changed', function() { - var packageFunc = jest.genMockFunction(); - packageFunc + pit('rebuilds the bundles that contain a file when that file is changed', function() { + var bundleFunc = jest.genMockFunction(); + bundleFunc .mockReturnValueOnce( Promise.resolve({ getSource: function() { @@ -173,7 +173,7 @@ describe('processRequest', function() { }) ); - Packager.prototype.package = packageFunc; + Bundler.prototype.bundle = bundleFunc; var Server = require('../../Server'); server = new Server(options); @@ -184,13 +184,13 @@ describe('processRequest', function() { return makeRequest(requestHandler, 'mybundle.bundle?runModule=true') .then(function(response) { expect(response).toEqual('this is the first source'); - expect(packageFunc.mock.calls.length).toBe(1); + expect(bundleFunc.mock.calls.length).toBe(1); triggerFileChange('all','path/file.js', options.projectRoots[0]); jest.runAllTimers(); jest.runAllTimers(); }) .then(function() { - expect(packageFunc.mock.calls.length).toBe(2); + expect(bundleFunc.mock.calls.length).toBe(2); return makeRequest(requestHandler, 'mybundle.bundle?runModule=true') .then(function(response) { expect(response).toEqual('this is the rebuilt source'); @@ -259,12 +259,12 @@ describe('processRequest', function() { }); }); - describe('buildPackage(options)', function() { - it('Calls the packager with the correct args', function() { - server.buildPackage({ + describe('buildBundle(options)', function() { + it('Calls the bundler with the correct args', function() { + server.buildBundle({ entryFile: 'foo file' }); - expect(Packager.prototype.package).toBeCalledWith( + expect(Bundler.prototype.bundle).toBeCalledWith( 'foo file', true, undefined, @@ -273,10 +273,10 @@ describe('processRequest', function() { }); }); - describe('buildPackageFromUrl(options)', function() { - it('Calls the packager with the correct args', function() { - server.buildPackageFromUrl('/path/to/foo.bundle?dev=false&runModule=false'); - expect(Packager.prototype.package).toBeCalledWith( + describe('buildBundleFromUrl(options)', function() { + it('Calls the bundler with the correct args', function() { + server.buildBundleFromUrl('/path/to/foo.bundle?dev=false&runModule=false'); + expect(Bundler.prototype.bundle).toBeCalledWith( 'path/to/foo.js', false, '/path/to/foo.map', diff --git a/react-packager/src/Server/index.js b/react-packager/src/Server/index.js index fdeffc65..fcb6e1a9 100644 --- a/react-packager/src/Server/index.js +++ b/react-packager/src/Server/index.js @@ -12,7 +12,7 @@ var url = require('url'); var path = require('path'); var declareOpts = require('../lib/declareOpts'); var FileWatcher = require('../FileWatcher'); -var Packager = require('../Packager'); +var Bundler = require('../Bundler'); var Activity = require('../Activity'); var AssetServer = require('../AssetServer'); var Promise = require('promise'); @@ -68,7 +68,7 @@ function Server(options) { var opts = validateOpts(options); this._projectRoots = opts.projectRoots; - this._packages = Object.create(null); + this._bundles = Object.create(null); this._changeWatchers = []; var assetGlobs = opts.assetExts.map(function(ext) { @@ -105,40 +105,40 @@ function Server(options) { assetExts: opts.assetExts, }); - var packagerOpts = Object.create(opts); - packagerOpts.fileWatcher = this._fileWatcher; - packagerOpts.assetServer = this._assetServer; - this._packager = new Packager(packagerOpts); + var bundlerOpts = Object.create(opts); + bundlerOpts.fileWatcher = this._fileWatcher; + bundlerOpts.assetServer = this._assetServer; + this._bundler = new Bundler(bundlerOpts); var onFileChange = this._onFileChange.bind(this); this._fileWatcher.on('all', onFileChange); var self = this; this._debouncedFileChangeHandler = _.debounce(function(filePath) { - self._rebuildPackages(filePath); + self._rebuildBundles(filePath); self._informChangeWatchers(); }, 50); } Server.prototype._onFileChange = function(type, filepath, root) { var absPath = path.join(root, filepath); - this._packager.invalidateFile(absPath); + this._bundler.invalidateFile(absPath); // Make sure the file watcher event runs through the system before - // we rebuild the packages. + // we rebuild the bundles. this._debouncedFileChangeHandler(absPath); }; -Server.prototype._rebuildPackages = function() { - var buildPackage = this.buildPackage.bind(this); - var packages = this._packages; +Server.prototype._rebuildBundles = function() { + var buildBundle = this.buildBundle.bind(this); + var bundles = this._bundles; - Object.keys(packages).forEach(function(optionsJson) { + Object.keys(bundles).forEach(function(optionsJson) { var options = JSON.parse(optionsJson); // Wait for a previous build (if exists) to finish. - packages[optionsJson] = (packages[optionsJson] || Promise.resolve()).finally(function() { + bundles[optionsJson] = (bundles[optionsJson] || Promise.resolve()).finally(function() { // With finally promise callback we can't change the state of the promise // so we need to reassign the promise. - packages[optionsJson] = buildPackage(options).then(function(p) { + bundles[optionsJson] = buildBundle(options).then(function(p) { // Make a throwaway call to getSource to cache the source string. p.getSource({ inlineSourceMap: options.inlineSourceMap, @@ -147,7 +147,7 @@ Server.prototype._rebuildPackages = function() { return p; }); }); - return packages[optionsJson]; + return bundles[optionsJson]; }); }; @@ -168,11 +168,11 @@ Server.prototype._informChangeWatchers = function() { Server.prototype.end = function() { Promise.all([ this._fileWatcher.end(), - this._packager.kill(), + this._bundler.kill(), ]); }; -var packageOpts = declareOpts({ +var bundleOpts = declareOpts({ sourceMapUrl: { type: 'string', required: false, @@ -199,10 +199,10 @@ var packageOpts = declareOpts({ }, }); -Server.prototype.buildPackage = function(options) { - var opts = packageOpts(options); +Server.prototype.buildBundle = function(options) { + var opts = bundleOpts(options); - return this._packager.package( + return this._bundler.bundle( opts.entryFile, opts.runModule, opts.sourceMapUrl, @@ -210,13 +210,13 @@ Server.prototype.buildPackage = function(options) { ); }; -Server.prototype.buildPackageFromUrl = function(reqUrl) { +Server.prototype.buildBundleFromUrl = function(reqUrl) { var options = getOptionsFromUrl(reqUrl); - return this.buildPackage(options); + return this.buildBundle(options); }; Server.prototype.getDependencies = function(main) { - return this._packager.getDependencies(main); + return this._bundler.getDependencies(main); }; Server.prototype._processDebugRequest = function(reqUrl, res) { @@ -224,13 +224,13 @@ Server.prototype._processDebugRequest = function(reqUrl, res) { var pathname = url.parse(reqUrl).pathname; var parts = pathname.split('/').filter(Boolean); if (parts.length === 1) { - ret += '
Cached Packages
'; + ret += '
Cached Bundles
'; ret += '
Dependency Graph
'; res.end(ret); - } else if (parts[1] === 'packages') { - ret += '

Cached Packages

'; - Promise.all(Object.keys(this._packages).map(function(optionsJson) { - return this._packages[optionsJson].then(function(p) { + } else if (parts[1] === 'bundles') { + ret += '

Cached Bundles

'; + Promise.all(Object.keys(this._bundles).map(function(optionsJson) { + return this._bundles[optionsJson].then(function(p) { ret += '

' + optionsJson + '

'; ret += p.getDebugInfo(); }); @@ -244,7 +244,7 @@ Server.prototype._processDebugRequest = function(reqUrl, res) { ); } else if (parts[1] === 'graph'){ ret += '

Dependency Graph

'; - ret += this._packager.getGraphDebugInfo(); + ret += this._bundler.getGraphDebugInfo(); res.end(ret); } else { res.writeHead('404'); @@ -352,9 +352,9 @@ Server.prototype.processRequest = function(req, res, next) { var startReqEventId = Activity.startEvent('request:' + req.url); var options = getOptionsFromUrl(req.url); var optionsJson = JSON.stringify(options); - var building = this._packages[optionsJson] || this.buildPackage(options); + var building = this._bundles[optionsJson] || this.buildBundle(options); - this._packages[optionsJson] = building; + this._bundles[optionsJson] = building; building.then( function(p) { if (requestType === 'bundle') { @@ -376,7 +376,7 @@ Server.prototype.processRequest = function(req, res, next) { ).done(); }; -Server.prototype._handleError = function(res, packageID, error) { +Server.prototype._handleError = function(res, bundleID, error) { res.writeHead(error.status || 500, { 'Content-Type': 'application/json; charset=UTF-8', }); @@ -390,7 +390,7 @@ Server.prototype._handleError = function(res, packageID, error) { res.end(JSON.stringify(error)); if (error.type === 'NotFoundError') { - delete this._packages[packageID]; + delete this._bundles[bundleID]; } } else { console.error(error.stack || error);