diff --git a/packages/metro-bundler/src/Bundler/index.js b/packages/metro-bundler/src/Bundler/index.js index bf33a9fc..6208daa2 100644 --- a/packages/metro-bundler/src/Bundler/index.js +++ b/packages/metro-bundler/src/Bundler/index.js @@ -27,6 +27,7 @@ const path = require('path'); const denodeify = require('denodeify'); const defaults = require('../defaults'); const toLocalPath = require('../node-haste/lib/toLocalPath'); +const createModuleIdFactory = require('../lib/createModuleIdFactory'); const {generateAssetTransformResult, isAssetTypeAnImage} = require('./util'); @@ -287,10 +288,6 @@ class Bundler { ); } - getGetModuleIdFn(): ({path: string}) => number { - return this._getModuleId; - } - _sourceHMRURL(platform: ?string, hmrpath: string) { return this._hmrURL('', platform, 'bundle', hmrpath); } @@ -946,18 +943,6 @@ function verifyRootExists(root) { assert(fs.statSync(root).isDirectory(), 'Root has to be a valid directory'); } -function createModuleIdFactory() { - const fileToIdMap = Object.create(null); - let nextId = 0; - return ({path: modulePath}) => { - if (!(modulePath in fileToIdMap)) { - fileToIdMap[modulePath] = nextId; - nextId += 1; - } - return fileToIdMap[modulePath]; - }; -} - function getMainModule({dependencies, numPrependedDependencies = 0}) { return dependencies[numPrependedDependencies]; } diff --git a/packages/metro-bundler/src/DeltaBundler/DeltaTransformer.js b/packages/metro-bundler/src/DeltaBundler/DeltaTransformer.js index 0c8e6a69..f6b58ec8 100644 --- a/packages/metro-bundler/src/DeltaBundler/DeltaTransformer.js +++ b/packages/metro-bundler/src/DeltaBundler/DeltaTransformer.js @@ -14,6 +14,8 @@ const DeltaCalculator = require('./DeltaCalculator'); +const createModuleIdFactory = require('../lib/createModuleIdFactory'); + const {EventEmitter} = require('events'); import type {RawMapping} from '../Bundler/source-map'; @@ -47,6 +49,8 @@ type Options = {| +polyfillModuleNames: $ReadOnlyArray, |}; +const globalCreateModuleId = createModuleIdFactory(); + /** * This class is in charge of creating the delta bundle with the actual * transformed source code for each of the modified modules. For each modified @@ -88,9 +92,19 @@ class DeltaTransformer extends EventEmitter { this._deltaCalculator = deltaCalculator; this._getPolyfills = options.getPolyfills; this._polyfillModuleNames = options.polyfillModuleNames; - this._getModuleId = this._bundler.getGetModuleIdFn(); this._bundleOptions = bundleOptions; + // Only when isolateModuleIDs is true the Module IDs of this instance are + // sandboxed from the rest. + // Isolating them makes sense when we want to get consistent module IDs + // between different builds of the same bundle (for example when building + // production builds), while coupling them makes sense when we want + // different bundles to share the same ids (on HMR, where we need to patch + // the correct module). + this._getModuleId = this._bundleOptions.isolateModuleIDs + ? createModuleIdFactory() + : globalCreateModuleId; + this._deltaCalculator.on('change', this._onFileChange); } diff --git a/packages/metro-bundler/src/lib/createModuleIdFactory.js b/packages/metro-bundler/src/lib/createModuleIdFactory.js new file mode 100644 index 00000000..82cf7d65 --- /dev/null +++ b/packages/metro-bundler/src/lib/createModuleIdFactory.js @@ -0,0 +1,26 @@ +/** + * 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. + * + * @format + */ + +'use strict'; + +function createModuleIdFactory(): ({path: string}) => number { + const fileToIdMap = new Map(); + let nextId = 0; + return ({path: modulePath}) => { + if (!fileToIdMap.has(modulePath)) { + fileToIdMap.set(modulePath, nextId); + nextId += 1; + } + return fileToIdMap.get(modulePath); + }; +} + +module.exports = createModuleIdFactory;