diff --git a/react-packager/src/Bundler/Bundle.js b/react-packager/src/Bundler/Bundle.js
index b5e591c8..04a2e1ae 100644
--- a/react-packager/src/Bundler/Bundle.js
+++ b/react-packager/src/Bundler/Bundle.js
@@ -10,6 +10,7 @@
const _ = require('underscore');
const base64VLQ = require('./base64-vlq');
+const BundleBase = require('./BundleBase');
const UglifyJS = require('uglify-js');
const ModuleTransport = require('../lib/ModuleTransport');
const Activity = require('../Activity');
@@ -24,11 +25,9 @@ const getNameAndCode = ({name, code}) => ({name, code});
const getNameAndMinifiedCode =
({name, code}) => ({name, code: minifyCode(code)});
-class Bundle {
+class Bundle extends BundleBase {
constructor(sourceMapUrl) {
- this._finalized = false;
- this._modules = [];
- this._assets = [];
+ super();
this._sourceMap = false;
this._sourceMapUrl = sourceMapUrl;
this._shouldCombineSourceMaps = false;
@@ -36,58 +35,49 @@ class Bundle {
this._numRequireCalls = 0;
}
- setMainModuleId(moduleId) {
- this._mainModuleId = moduleId;
- }
+ addModule(resolver, response, module, transformed) {
+ return resolver.wrapModule(
+ response,
+ module,
+ transformed.code
+ ).then(({code, name}) => {
+ const moduleTransport = new ModuleTransport({
+ code,
+ name,
+ map: transformed.map,
+ sourceCode: transformed.sourceCode,
+ sourcePath: transformed.sourcePath,
+ virtual: transformed.virtual,
+ });
- 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 && moduleTransport.map != null) {
+ this._shouldCombineSourceMaps = true;
+ }
- // 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;
- }
-
- getMainModuleId() {
- return this._mainModuleId;
+ super.addModule(moduleTransport);
+ });
}
setNumPrependedModules(n) {
this._numPrependedModules = n;
}
- addAsset(asset) {
- this._assets.push(asset);
- }
-
finalize(options) {
options = options || {};
if (options.runMainModule) {
options.runBeforeMainModule.forEach(this._addRequireCall, this);
- this._addRequireCall(this._mainModuleId);
+ this._addRequireCall(super.getMainModuleId());
}
- Object.freeze(this._modules);
- Object.seal(this._modules);
- Object.freeze(this._assets);
- Object.seal(this._assets);
- this._finalized = true;
+ super.finalize();
}
_addRequireCall(moduleId) {
const code = ';require("' + moduleId + '");';
const name = 'require-' + moduleId;
- this.addModule(new ModuleTransport({
+ super.addModule(new ModuleTransport({
name,
code,
virtual: true,
@@ -97,21 +87,6 @@ class Bundle {
this._numRequireCalls += 1;
}
- _assertFinalized() {
- if (!this._finalized) {
- throw new Error('Bundle needs to be finalized before getting any source');
- }
- }
-
- _getSource(dev) {
- if (this._source) {
- return this._source;
- }
-
- this._source = _.pluck(this._modules, 'code').join('\n');
- return this._source;
- }
-
_getInlineSourceMap(dev) {
if (this._inlineSourceMap == null) {
const sourceMap = this.getSourceMap({excludeSource: true, dev});
@@ -123,7 +98,7 @@ class Bundle {
}
getSource(options) {
- this._assertFinalized();
+ super.assertFinalized();
options = options || {};
@@ -131,7 +106,7 @@ class Bundle {
return this.getMinifiedSourceAndMap(options.dev).code;
}
- let source = this._getSource(options.dev);
+ let source = super.getSource();
if (options.inlineSourceMap) {
source += SOURCEMAPPING_URL + this._getInlineSourceMap(options.dev);
@@ -143,7 +118,7 @@ class Bundle {
}
getUnbundle({minify}) {
- const allModules = this._modules.slice();
+ const allModules = super.getModules().slice();
const prependedModules = this._numPrependedModules;
const requireCalls = this._numRequireCalls;
@@ -163,13 +138,13 @@ class Bundle {
}
getMinifiedSourceAndMap(dev) {
- this._assertFinalized();
+ super.assertFinalized();
if (this._minifiedSourceAndMap) {
return this._minifiedSourceAndMap;
}
- let source = this._getSource(dev);
+ let source = this.getSource();
let map = this.getSourceMap();
if (!dev) {
@@ -235,7 +210,7 @@ class Bundle {
};
let line = 0;
- this._modules.forEach(function(module) {
+ super.getModules().forEach(function(module) {
let map = module.map;
if (module.virtual) {
map = generateSourceMapForVirtualModule(module);
@@ -256,7 +231,7 @@ class Bundle {
}
getSourceMap(options) {
- this._assertFinalized();
+ super.assertFinalized();
options = options || {};
@@ -271,22 +246,18 @@ class Bundle {
const mappings = this._getMappings();
const map = {
file: 'bundle.js',
- sources: _.pluck(this._modules, 'sourcePath'),
+ sources: _.pluck(super.getModules(), 'sourcePath'),
version: 3,
names: [],
mappings: mappings,
sourcesContent: options.excludeSource
- ? [] : _.pluck(this._modules, 'sourceCode')
+ ? [] : _.pluck(super.getModules(), 'sourceCode')
};
return map;
}
- getAssets() {
- return this._assets;
- }
-
_getMappings() {
- const modules = this._modules;
+ const modules = super.getModules();
// The first line mapping in our package is basically the base64vlq code for
// zeros (A).
@@ -333,7 +304,7 @@ class Bundle {
}
getJSModulePaths() {
- return this._modules.filter(function(module) {
+ return super.getModules().filter(function(module) {
// Filter out non-js files. Like images etc.
return !module.virtual;
}).map(function(module) {
@@ -343,7 +314,7 @@ class Bundle {
getDebugInfo() {
return [
- '
Main Module:
' + this._mainModuleId + '',
+ 'Main Module:
' + super.getMainModuleId() + '',
'',
' Module paths and transformed code:
',
- this._modules.map(function(m) {
+ super.getModules().map(function(m) {
return ' Path:
' + m.sourcePath + '
Source:
' +
'
' +
_.escape(m.code) + '
';
@@ -369,10 +340,9 @@ class Bundle {
}
return {
- modules: this._modules,
- assets: this._assets,
+ ...super.toJSON(),
sourceMapUrl: this._sourceMapUrl,
- mainModuleId: this._mainModuleId,
+ mainModuleId: super.getMainModuleId(),
numPrependedModules: this._numPrependedModules,
numRequireCalls: this._numRequireCalls,
};
@@ -380,18 +350,12 @@ class Bundle {
static fromJSON(json) {
const bundle = new Bundle(json.sourceMapUrl);
- bundle._mainModuleId = json.mainModuleId;
- bundle._assets = json.assets;
- bundle._modules = json.modules;
+
bundle._sourceMapUrl = json.sourceMapUrl;
bundle._numPrependedModules = json.numPrependedModules;
bundle._numRequireCalls = json.numRequireCalls;
- Object.freeze(bundle._modules);
- Object.seal(bundle._modules);
- Object.freeze(bundle._assets);
- Object.seal(bundle._assets);
- bundle._finalized = true;
+ BundleBase.fromJSON(bundle, json);
return bundle;
}
diff --git a/react-packager/src/Bundler/BundleBase.js b/react-packager/src/Bundler/BundleBase.js
new file mode 100644
index 00000000..635f87e7
--- /dev/null
+++ b/react-packager/src/Bundler/BundleBase.js
@@ -0,0 +1,94 @@
+/**
+ * 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 ModuleTransport = require('../lib/ModuleTransport');
+
+class BundleBase {
+ constructor() {
+ this._finalized = false;
+ this._modules = [];
+ this._assets = [];
+ }
+
+ getMainModuleId() {
+ return this._mainModuleId;
+ }
+
+ setMainModuleId(moduleId) {
+ this._mainModuleId = moduleId;
+ }
+
+ addModule(module) {
+ if (!module instanceof ModuleTransport) {
+ throw new Error('Expeceted a ModuleTransport object');
+ }
+
+ this._modules.push(module);
+ }
+
+ getModules() {
+ return this._modules;
+ }
+
+ getAssets() {
+ return this._assets;
+ }
+
+ addAsset(asset) {
+ this._assets.push(asset);
+ }
+
+ finalize(options) {
+ Object.freeze(this._modules);
+ Object.seal(this._modules);
+ Object.freeze(this._assets);
+ Object.seal(this._assets);
+ this._finalized = true;
+ }
+
+ getSource(options) {
+ this.assertFinalized();
+
+ if (this._source) {
+ return this._source;
+ }
+
+ this._source = _.pluck(this._modules, 'code').join('\n');
+ return this._source;
+ }
+
+ assertFinalized() {
+ if (!this._finalized) {
+ throw new Error('Bundle needs to be finalized before getting any source');
+ }
+ }
+
+ toJSON() {
+ return {
+ modules: this._modules,
+ assets: this._assets,
+ };
+ }
+
+ static fromJSON(bundle, json) {
+ bundle._assets = json.assets;
+ bundle._modules = json.modules;
+ bundle._mainModuleId = json.mainModuleId;
+
+ Object.freeze(bundle._modules);
+ Object.seal(bundle._modules);
+ Object.freeze(bundle._assets);
+ Object.seal(bundle._assets);
+ bundle._finalized = true;
+ }
+}
+
+module.exports = BundleBase;
diff --git a/react-packager/src/Bundler/HMRBundle.js b/react-packager/src/Bundler/HMRBundle.js
new file mode 100644
index 00000000..fa8c95db
--- /dev/null
+++ b/react-packager/src/Bundler/HMRBundle.js
@@ -0,0 +1,47 @@
+/**
+ * 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 BundleBase = require('./BundleBase');
+const ModuleTransport = require('../lib/ModuleTransport');
+
+class HMRBundle extends BundleBase {
+ constructor() {
+ super();
+ }
+
+ addModule(resolver, response, module, transformed) {
+ return resolver.resolveRequires(response,
+ module,
+ transformed.code,
+ ).then(({name, code}) => {
+ code = `
+ __accept(
+ '${name}',
+ function(global, require, module, exports) {
+ ${code}
+ }
+ );
+ `;
+
+ const moduleTransport = new ModuleTransport({
+ code,
+ name,
+ map: transformed.map,
+ sourceCode: transformed.sourceCode,
+ sourcePath: transformed.sourcePath,
+ virtual: transformed.virtual,
+ });
+
+ super.addModule(moduleTransport);
+ });
+ }
+}
+
+module.exports = HMRBundle;
diff --git a/react-packager/src/Bundler/__tests__/Bundle-test.js b/react-packager/src/Bundler/__tests__/Bundle-test.js
index 6dd3d3b7..1180f0a2 100644
--- a/react-packager/src/Bundler/__tests__/Bundle-test.js
+++ b/react-packager/src/Bundler/__tests__/Bundle-test.js
@@ -10,92 +10,106 @@
jest.autoMockOff();
-var SourceMapGenerator = require('source-map').SourceMapGenerator;
+const Bundle = require('../Bundle');
+const ModuleTransport = require('../../lib/ModuleTransport');
+const Promise = require('Promise');
+const SourceMapGenerator = require('source-map').SourceMapGenerator;
+const UglifyJS = require('uglify-js');
-var Bundle = require('../Bundle');
-var ModuleTransport = require('../../lib/ModuleTransport');
-var UglifyJS = require('uglify-js');
-
-describe('Bundle', function() {
+describe('Bundle', () => {
var bundle;
- beforeEach(function() {
+ beforeEach(() => {
bundle = new Bundle('test_url');
- bundle.getSourceMap = jest.genMockFn().mockImpl(function() {
+ bundle.getSourceMap = jest.genMockFn().mockImpl(() => {
return 'test-source-map';
});
});
- 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',
- }));
- bundle.addModule(new ModuleTransport({
- code: 'transformed bar;',
- sourceCode: 'source bar',
- sourcePath: 'bar path',
- }));
-
- bundle.finalize({});
- expect(bundle.getSource({dev: true})).toBe([
- 'transformed foo;',
- 'transformed bar;',
- '\/\/# sourceMappingURL=test_url'
- ].join('\n'));
- });
-
- it('should be ok to leave out the source map url', function() {
- var p = new Bundle();
- p.addModule(new ModuleTransport({
- code: 'transformed foo;',
- sourceCode: 'source foo',
- sourcePath: 'foo path',
- }));
- p.addModule(new ModuleTransport({
- code: 'transformed bar;',
- sourceCode: 'source bar',
- sourcePath: 'bar path',
- }));
-
- p.finalize({});
- expect(p.getSource({dev: true})).toBe([
- 'transformed foo;',
- 'transformed bar;',
- ].join('\n'));
- });
-
- it('should create a bundle and add run module code', function() {
- bundle.addModule(new ModuleTransport({
- code: 'transformed foo;',
- sourceCode: 'source foo',
- sourcePath: 'foo path'
- }));
-
- bundle.addModule(new ModuleTransport({
- code: 'transformed bar;',
- sourceCode: 'source bar',
- sourcePath: 'bar path'
- }));
-
- bundle.setMainModuleId('foo');
- bundle.finalize({
- runBeforeMainModule: ['bar'],
- runMainModule: true,
+ describe('source bundle', () => {
+ pit('should create a bundle and get the source', () => {
+ return Promise.resolve().then(() => {
+ return addModule({
+ bundle,
+ code: 'transformed foo;',
+ sourceCode: 'source foo',
+ sourcePath: 'foo path',
+ });
+ }).then(() => {
+ return addModule({
+ bundle,
+ code: 'transformed bar;',
+ sourceCode: 'source bar',
+ sourcePath: 'bar path',
+ });
+ }).then(() => {
+ bundle.finalize({});
+ expect(bundle.getSource({dev: true})).toBe([
+ 'transformed foo;',
+ 'transformed bar;',
+ '\/\/# sourceMappingURL=test_url'
+ ].join('\n'));
});
- expect(bundle.getSource({dev: true})).toBe([
- 'transformed foo;',
- 'transformed bar;',
- ';require("bar");',
- ';require("foo");',
- '\/\/# sourceMappingURL=test_url',
- ].join('\n'));
});
- it('should get minified source', function() {
- var minified = {
+ pit('should be ok to leave out the source map url', () => {
+ const otherBundle = new Bundle();
+ return Promise.resolve().then(() => {
+ return addModule({
+ bundle: otherBundle,
+ code: 'transformed foo;',
+ sourceCode: 'source foo',
+ sourcePath: 'foo path',
+ });
+ }).then(() => {
+ return addModule({
+ bundle: otherBundle,
+ code: 'transformed bar;',
+ sourceCode: 'source bar',
+ sourcePath: 'bar path',
+ });
+ }).then(() => {
+ otherBundle.finalize({});
+ expect(otherBundle.getSource({dev: true})).toBe([
+ 'transformed foo;',
+ 'transformed bar;',
+ ].join('\n'));
+ });
+ });
+
+ pit('should create a bundle and add run module code', () => {
+ return Promise.resolve().then(() => {
+ return addModule({
+ bundle,
+ code: 'transformed foo;',
+ sourceCode: 'source foo',
+ sourcePath: 'foo path',
+ });
+ }).then(() => {
+ return addModule({
+ bundle,
+ code: 'transformed bar;',
+ sourceCode: 'source bar',
+ sourcePath: 'bar path',
+ });
+ }).then(() => {
+ bundle.setMainModuleId('foo');
+ bundle.finalize({
+ runBeforeMainModule: ['bar'],
+ runMainModule: true,
+ });
+ expect(bundle.getSource({dev: true})).toBe([
+ 'transformed foo;',
+ 'transformed bar;',
+ ';require("bar");',
+ ';require("foo");',
+ '\/\/# sourceMappingURL=test_url',
+ ].join('\n'));
+ });
+ });
+
+ pit('should get minified source', () => {
+ const minified = {
code: 'minified',
map: 'map',
};
@@ -104,141 +118,156 @@ describe('Bundle', function() {
return minified;
};
- bundle.addModule(new ModuleTransport({
- code: 'transformed foo;',
- sourceCode: 'source foo',
- sourcePath: 'foo path'
- }));
- bundle.finalize();
- expect(bundle.getMinifiedSourceAndMap({dev: true})).toBe(minified);
- });
- });
-
- describe('sourcemap bundle', function() {
- it('should create sourcemap', function() {
- var p = new Bundle('test_url');
- p.addModule(new ModuleTransport({
- code: [
- 'transformed foo',
- 'transformed foo',
- 'transformed foo',
- ].join('\n'),
- sourceCode: [
- 'source foo',
- 'source foo',
- 'source foo',
- ].join('\n'),
- sourcePath: 'foo path',
- }));
- p.addModule(new ModuleTransport({
- code: [
- 'transformed bar',
- 'transformed bar',
- 'transformed bar',
- ].join('\n'),
- sourceCode: [
- 'source bar',
- 'source bar',
- 'source bar',
- ].join('\n'),
- sourcePath: 'bar path',
- }));
-
- p.setMainModuleId('foo');
- p.finalize({
- runBeforeMainModule: [],
- runMainModule: true,
- });
- var s = p.getSourceMap({dev: true});
- expect(s).toEqual(genSourceMap(p.getModules()));
- });
-
- it('should combine sourcemaps', function() {
- var p = new Bundle('test_url');
-
- p.addModule(new ModuleTransport({
- code: 'transformed foo;\n',
- map: {name: 'sourcemap foo'},
- sourceCode: 'source foo',
- sourcePath: 'foo path'
- }));
-
- p.addModule(new ModuleTransport({
- code: 'transformed foo;\n',
- map: {name: 'sourcemap bar'},
- sourceCode: 'source foo',
- sourcePath: 'foo path'
- }));
-
- p.addModule(new ModuleTransport({
- code: 'image module;\nimage module;',
- virtual: true,
- sourceCode: 'image module;\nimage module;',
- sourcePath: 'image.png',
- }));
-
- p.setMainModuleId('foo');
- p.finalize({
- runBeforeMainModule: ['InitializeJavaScriptAppEngine'],
- runMainModule: true,
- });
-
- var s = p.getSourceMap({dev: true});
- expect(s).toEqual({
- file: 'bundle.js',
- version: 3,
- sections: [
- { offset: { line: 0, column: 0 }, map: { name: 'sourcemap foo' } },
- { offset: { line: 2, column: 0 }, map: { name: 'sourcemap bar' } },
- {
- offset: {
- column: 0,
- line: 4
- },
- map: {
- file: 'image.png',
- mappings: 'AAAA;AACA;',
- names: [],
- sources: [ 'image.png' ],
- sourcesContent: ['image module;\nimage module;'],
- version: 3,
- }
- },
- {
- offset: {
- column: 0,
- line: 6
- },
- map: {
- file: 'require-InitializeJavaScriptAppEngine.js',
- mappings: 'AAAA;',
- names: [],
- sources: [ 'require-InitializeJavaScriptAppEngine.js' ],
- sourcesContent: [';require("InitializeJavaScriptAppEngine");'],
- version: 3,
- }
- },
- {
- offset: {
- column: 0,
- line: 7
- },
- map: {
- file: 'require-foo.js',
- mappings: 'AAAA;',
- names: [],
- sources: [ 'require-foo.js' ],
- sourcesContent: [';require("foo");'],
- version: 3,
- }
- },
- ],
+ return Promise.resolve().then(() => {
+ return addModule({
+ bundle,
+ code: 'transformed foo;',
+ sourceCode: 'source foo',
+ sourcePath: 'foo path',
+ });
+ }).then(() => {
+ bundle.finalize();
+ expect(bundle.getMinifiedSourceAndMap({dev: true})).toBe(minified);
});
});
});
- describe('getAssets()', function() {
- it('should save and return asset objects', function() {
+ describe('sourcemap bundle', () => {
+ pit('should create sourcemap', () => {
+ const otherBundle = new Bundle('test_url');
+
+ return Promise.resolve().then(() => {
+ return addModule({
+ bundle: otherBundle,
+ code: [
+ 'transformed foo',
+ 'transformed foo',
+ 'transformed foo',
+ ].join('\n'),
+ sourceCode: [
+ 'source foo',
+ 'source foo',
+ 'source foo',
+ ].join('\n'),
+ sourcePath: 'foo path',
+ });
+ }).then(() => {
+ return addModule({
+ bundle: otherBundle,
+ code: [
+ 'transformed bar',
+ 'transformed bar',
+ 'transformed bar',
+ ].join('\n'),
+ sourceCode: [
+ 'source bar',
+ 'source bar',
+ 'source bar',
+ ].join('\n'),
+ sourcePath: 'bar path',
+ });
+ }).then(() => {
+ otherBundle.setMainModuleId('foo');
+ otherBundle.finalize({
+ runBeforeMainModule: [],
+ runMainModule: true,
+ });
+ const sourceMap = otherBundle.getSourceMap({dev: true});
+ expect(sourceMap).toEqual(genSourceMap(otherBundle.getModules()));
+ });
+ });
+
+ pit('should combine sourcemaps', () => {
+ const otherBundle = new Bundle('test_url');
+
+ return Promise.resolve().then(() => {
+ return addModule({
+ bundle: otherBundle,
+ code: 'transformed foo;\n',
+ sourceCode: 'source foo',
+ map: {name: 'sourcemap foo'},
+ sourcePath: 'foo path',
+ });
+ }).then(() => {
+ return addModule({
+ bundle: otherBundle,
+ code: 'transformed bar;\n',
+ sourceCode: 'source bar',
+ map: {name: 'sourcemap bar'},
+ sourcePath: 'bar path',
+ });
+ }).then(() => {
+ return addModule({
+ bundle: otherBundle,
+ code: 'image module;\nimage module;',
+ virtual: true,
+ sourceCode: 'image module;\nimage module;',
+ sourcePath: 'image.png',
+ });
+ }).then(() => {
+ otherBundle.setMainModuleId('foo');
+ otherBundle.finalize({
+ runBeforeMainModule: ['InitializeJavaScriptAppEngine'],
+ runMainModule: true,
+ });
+
+ const sourceMap = otherBundle.getSourceMap({dev: true});
+ expect(sourceMap).toEqual({
+ file: 'bundle.js',
+ version: 3,
+ sections: [
+ { offset: { line: 0, column: 0 }, map: { name: 'sourcemap foo' } },
+ { offset: { line: 2, column: 0 }, map: { name: 'sourcemap bar' } },
+ {
+ offset: {
+ column: 0,
+ line: 4
+ },
+ map: {
+ file: 'image.png',
+ mappings: 'AAAA;AACA;',
+ names: [],
+ sources: [ 'image.png' ],
+ sourcesContent: ['image module;\nimage module;'],
+ version: 3,
+ }
+ },
+ {
+ offset: {
+ column: 0,
+ line: 6
+ },
+ map: {
+ file: 'require-InitializeJavaScriptAppEngine.js',
+ mappings: 'AAAA;',
+ names: [],
+ sources: [ 'require-InitializeJavaScriptAppEngine.js' ],
+ sourcesContent: [';require("InitializeJavaScriptAppEngine");'],
+ version: 3,
+ }
+ },
+ {
+ offset: {
+ column: 0,
+ line: 7
+ },
+ map: {
+ file: 'require-foo.js',
+ mappings: 'AAAA;',
+ names: [],
+ sources: [ 'require-foo.js' ],
+ sourcesContent: [';require("foo");'],
+ version: 3,
+ }
+ },
+ ],
+ });
+ });
+ });
+ });
+
+ describe('getAssets()', () => {
+ it('should save and return asset objects', () => {
var p = new Bundle('test_url');
var asset1 = {};
var asset2 = {};
@@ -249,22 +278,27 @@ describe('Bundle', function() {
});
});
- describe('getJSModulePaths()', function() {
- it('should return module paths', function() {
- var p = new Bundle('test_url');
- p.addModule(new ModuleTransport({
- code: 'transformed foo;\n',
- sourceCode: 'source foo',
- sourcePath: 'foo path'
- }));
- p.addModule(new ModuleTransport({
- code: 'image module;\nimage module;',
- virtual: true,
- sourceCode: 'image module;\nimage module;',
- sourcePath: 'image.png',
- }));
-
- expect(p.getJSModulePaths()).toEqual(['foo path']);
+ describe('getJSModulePaths()', () => {
+ pit('should return module paths', () => {
+ var otherBundle = new Bundle('test_url');
+ return Promise.resolve().then(() => {
+ return addModule({
+ bundle: otherBundle,
+ code: 'transformed foo;\n',
+ sourceCode: 'source foo',
+ sourcePath: 'foo path',
+ });
+ }).then(() => {
+ return addModule({
+ bundle: otherBundle,
+ code: 'image module;\nimage module;',
+ virtual: true,
+ sourceCode: 'image module;\nimage module;',
+ sourcePath: 'image.png',
+ });
+ }).then(() => {
+ expect(otherBundle.getJSModulePaths()).toEqual(['foo path']);
+ });
});
});
});
@@ -302,3 +336,20 @@ function genSourceMap(modules) {
}
return sourceMapGen.toJSON();
}
+
+function resolverFor(code) {
+ return {
+ wrapModule: (response, module, sourceCode) => Promise.resolve(
+ {name: 'name', code}
+ ),
+ };
+}
+
+function addModule({bundle, code, sourceCode, sourcePath, map, virtual}) {
+ return bundle.addModule(
+ resolverFor(code),
+ null,
+ null,
+ {sourceCode, sourcePath, map, virtual}
+ );
+}
diff --git a/react-packager/src/Bundler/__tests__/Bundler-test.js b/react-packager/src/Bundler/__tests__/Bundler-test.js
index ccdc8496..467cf90d 100644
--- a/react-packager/src/Bundler/__tests__/Bundler-test.js
+++ b/react-packager/src/Bundler/__tests__/Bundler-test.js
@@ -161,46 +161,29 @@ describe('Bundler', function() {
runBeforeMainModule: [],
runModule: true,
sourceMapUrl: 'source_map_url',
- }).then(function(p) {
- expect(p.addModule.mock.calls[0][0]).toEqual({
- name: 'foo',
- code: 'lol transformed /root/foo.js lol',
- map: 'sourcemap /root/foo.js',
- sourceCode: 'source /root/foo.js',
- sourcePath: '/root/foo.js',
- });
+ }).then(bundle => {
+ const ithAddedModule = (i) => bundle.addModule.mock.calls[i][2].path;
- expect(p.addModule.mock.calls[1][0]).toEqual({
- name: 'bar',
- code: 'lol transformed /root/bar.js lol',
- map: 'sourcemap /root/bar.js',
- sourceCode: 'source /root/bar.js',
- sourcePath: '/root/bar.js'
- });
+ expect(ithAddedModule(0)).toEqual('/root/foo.js');
+ expect(ithAddedModule(1)).toEqual('/root/bar.js');
+ expect(ithAddedModule(2)).toEqual('/root/img/img.png');
+ expect(ithAddedModule(3)).toEqual('/root/img/new_image.png');
+ expect(ithAddedModule(4)).toEqual('/root/file.json');
- var imgModule_DEPRECATED = {
+ expect(bundle.finalize.mock.calls[0]).toEqual([
+ {runMainModule: true, runBeforeMainModule: []}
+ ]);
+
+ expect(bundle.addAsset.mock.calls).toContain([{
__packager_asset: true,
path: '/root/img/img.png',
uri: 'img',
width: 25,
height: 50,
deprecated: true,
- };
+ }]);
- expect(p.addModule.mock.calls[2][0]).toEqual({
- name: 'image!img',
- code: 'lol module.exports = ' +
- JSON.stringify(imgModule_DEPRECATED) +
- '; lol',
- sourceCode: 'module.exports = ' +
- JSON.stringify(imgModule_DEPRECATED) +
- ';',
- sourcePath: '/root/img/img.png',
- virtual: true,
- map: undefined,
- });
-
- var imgModule = {
+ expect(bundle.addAsset.mock.calls).toContain([{
__packager_asset: true,
fileSystemLocation: '/root/img',
httpServerLocation: '/assets/img',
@@ -215,41 +198,7 @@ describe('Bundler', function() {
hash: 'i am a hash',
name: 'img',
type: 'png',
- };
-
- expect(p.addModule.mock.calls[3][0]).toEqual({
- name: 'new_image.png',
- code: 'lol module.exports = require("AssetRegistry").registerAsset(' +
- JSON.stringify(imgModule) +
- '); lol',
- sourceCode: 'module.exports = require("AssetRegistry").registerAsset(' +
- JSON.stringify(imgModule) +
- ');',
- sourcePath: '/root/img/new_image.png',
- virtual: true,
- map: undefined,
- });
-
- expect(p.addModule.mock.calls[4][0]).toEqual({
- name: 'package/file.json',
- code: 'lol module.exports = {"json":true}; lol',
- sourceCode: 'module.exports = {"json":true};',
- sourcePath: '/root/file.json',
- map: undefined,
- virtual: true,
- });
-
- expect(p.finalize.mock.calls[0]).toEqual([
- {runMainModule: true, runBeforeMainModule: []}
- ]);
-
- expect(p.addAsset.mock.calls).toContain([
- imgModule_DEPRECATED
- ]);
-
- expect(p.addAsset.mock.calls).toContain([
- imgModule
- ]);
+ }]);
// TODO(amasad) This fails with 0 != 5 in OSS
//expect(ProgressBar.prototype.tick.mock.calls.length).toEqual(modules.length);
diff --git a/react-packager/src/Bundler/index.js b/react-packager/src/Bundler/index.js
index ebac145c..1cc28f23 100644
--- a/react-packager/src/Bundler/index.js
+++ b/react-packager/src/Bundler/index.js
@@ -18,6 +18,7 @@ const Cache = require('../DependencyResolver/Cache');
const Transformer = require('../JSTransformer');
const Resolver = require('../Resolver');
const Bundle = require('./Bundle');
+const HMRBundle = require('./HMRBundle');
const PrepackBundle = require('./PrepackBundle');
const Activity = require('../Activity');
const ModuleTransport = require('../lib/ModuleTransport');
@@ -155,31 +156,54 @@ class Bundler {
return this._bundlesLayout.generateLayout(main, isDev);
}
- bundle({
+ bundle(options) {
+ return this._bundle({
+ bundle: new Bundle(options.sourceMapUrl),
+ includeSystemDependencies: true,
+ ...options,
+ });
+ }
+
+ bundleForHMR(options) {
+ return this._bundle({
+ bundle: new HMRBundle(),
+ hot: true,
+ ...options,
+ });
+ }
+
+ _bundle({
+ bundle,
+ modules,
entryFile,
runModule: runMainModule,
runBeforeMainModule,
- sourceMapUrl,
dev: isDev,
+ includeSystemDependencies,
platform,
unbundle: isUnbundle,
hot: hot,
}) {
- // Const cannot have the same name as the method (babel/babel#2834)
- const bbundle = new Bundle(sourceMapUrl);
const findEventId = Activity.startEvent('find dependencies');
let transformEventId;
- const moduleSystem = this._resolver.getModuleSystemDependencies(
- { dev: isDev, platform, isUnbundle }
- );
-
return this.getDependencies(entryFile, isDev, platform).then((response) => {
Activity.endEvent(findEventId);
+ bundle.setMainModuleId(response.mainModuleId);
transformEventId = Activity.startEvent('transform');
- // Prepend the module system polyfill to the top of dependencies
- var dependencies = moduleSystem.concat(response.dependencies);
+ const moduleSystemDeps = includeSystemDependencies
+ ? this._resolver.getModuleSystemDependencies(
+ { dev: isDev, platform, isUnbundle }
+ )
+ : [];
+
+ const modulesToProcess = modules || response.dependencies;
+ const dependencies = moduleSystemDeps.concat(modulesToProcess);
+
+ bundle.setNumPrependedModules && bundle.setNumPrependedModules(
+ response.numPrependedDependencies + moduleSystemDeps.length
+ );
let bar;
if (process.stdout.isTTY) {
@@ -191,34 +215,41 @@ class Bundler {
});
}
- bbundle.setMainModuleId(response.mainModuleId);
- bbundle.setNumPrependedModules(
- response.numPrependedDependencies + moduleSystem.length);
return Promise.all(
dependencies.map(
- module => this._transformModule(
- bbundle,
+ module => {
+ return this._transformModule(
+ bundle,
+ response,
+ module,
+ platform,
+ hot,
+ ).then(transformed => {
+ if (bar) {
+ bar.tick();
+ }
+
+ return {
+ module,
+ transformed,
+ };
+ });
+ }
+ )
+ ).then(transformedModules => Promise.all(
+ transformedModules.map(({module, transformed}) => {
+ return bundle.addModule(
+ this._resolver,
response,
module,
- platform,
- hot,
- ).then(transformed => {
- if (bar) {
- bar.tick();
- }
- return this._wrapTransformedModule(response, module, transformed);
- })
- )
- );
- }).then((transformedModules) => {
+ transformed,
+ );
+ })
+ ));
+ }).then(() => {
Activity.endEvent(transformEventId);
-
- transformedModules.forEach(function(moduleTransport) {
- bbundle.addModule(moduleTransport);
- });
-
- bbundle.finalize({runBeforeMainModule, runMainModule});
- return bbundle;
+ bundle.finalize({runBeforeMainModule, runMainModule});
+ return bundle;
});
}
@@ -284,35 +315,6 @@ class Bundler {
});
}
- bundleForHMR({entryFile, platform, modules}) {
- return this.getDependencies(entryFile, /*isDev*/true, platform)
- .then(response => {
- return Promise.all(
- modules.map(module => {
- return Promise.all([
- module.getName(),
- this._transformModuleForHMR(module, platform),
- ]).then(([moduleName, transformed]) => {
- return this._resolver.resolveRequires(response,
- module,
- transformed.code,
- ).then(({name, code}) => {
- return (`
- __accept(
- '${moduleName}',
- function(global, require, module, exports) {
- ${code}
- }
- );
- `);
- });
- });
- })
- );
- })
- .then(modules => modules.join('\n'));
- }
-
_transformModuleForHMR(module, platform) {
if (module.isAsset()) {
return this._generateAssetObjAndCode(module, platform).then(
@@ -401,23 +403,6 @@ class Bundler {
}
}
- _wrapTransformedModule(response, module, transformed) {
- return this._resolver.wrapModule(
- response,
- module,
- transformed.code
- ).then(
- ({code, name}) => new ModuleTransport({
- code,
- name,
- map: transformed.map,
- sourceCode: transformed.sourceCode,
- sourcePath: transformed.sourcePath,
- virtual: transformed.virtual,
- })
- );
- }
-
getGraphDebugInfo() {
return this._resolver.getDebugInfo();
}