mirror of https://github.com/status-im/metro.git
require implementations: Make module map an array, preset length, if number of modules is known
Summary: For specific cases, Metro will write the number of modules to the bundle. The require implementation can take advantage of that, and construct an array with the target size. Reviewed By: mjesun Differential Revision: D7696290 fbshipit-source-id: a7be74c02960dc089e4d3c1accd7c732b762c8b5
This commit is contained in:
parent
8aa96e6a3e
commit
18507aecc9
|
@ -52,7 +52,12 @@ async function build(options: BuildOptions): Promise<BuildResult> {
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const {entryModules} = graph;
|
const {entryModules} = graph;
|
||||||
const preludeScript = virtualModule(getPreludeCode({isDev: !optimize}));
|
const preludeScript = virtualModule(
|
||||||
|
getPreludeCode({
|
||||||
|
extraVars: {__NUM_MODULES__: graph.modules.length},
|
||||||
|
isDev: !optimize,
|
||||||
|
}),
|
||||||
|
);
|
||||||
const prependedScripts = [preludeScript, ...moduleSystem, ...polyfills];
|
const prependedScripts = [preludeScript, ...moduleSystem, ...polyfills];
|
||||||
return {
|
return {
|
||||||
entryModules,
|
entryModules,
|
||||||
|
|
|
@ -98,9 +98,9 @@ export type Module = {|
|
||||||
|};
|
|};
|
||||||
|
|
||||||
export type PostProcessModules = (
|
export type PostProcessModules = (
|
||||||
modules: Iterable<Module>,
|
modules: $ReadOnlyArray<Module>,
|
||||||
entryPoints: Array<string>,
|
entryPoints: Array<string>,
|
||||||
) => Iterable<Module>;
|
) => $ReadOnlyArray<Module>;
|
||||||
|
|
||||||
export type OutputFn<
|
export type OutputFn<
|
||||||
M: FBSourceMap | MetroSourceMap = FBSourceMap | MetroSourceMap,
|
M: FBSourceMap | MetroSourceMap = FBSourceMap | MetroSourceMap,
|
||||||
|
|
|
@ -1,17 +1,17 @@
|
||||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
exports[`basic_bundle bundles package with polyfills 1`] = `
|
exports[`basic_bundle bundles package with polyfills 1`] = `
|
||||||
"var __DEV__=false,__BUNDLE_START_TIME__=this.nativePerformanceNow?nativePerformanceNow():Date.now(),process=this.process||{};process.env=process.env||{};process.env.NODE_ENV='production';
|
"var __DEV__=false,__BUNDLE_START_TIME__=this.nativePerformanceNow?nativePerformanceNow():Date.now(),process=this.process||{};process.env=process.env||{};process.env.NODE_ENV=\\"production\\";
|
||||||
(function (global) {
|
(function (global) {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var PRINT_REQUIRE_PATHS = false;
|
var PRINT_REQUIRE_PATHS = false;
|
||||||
global.require = metroRequire;
|
global.require = metroRequire;
|
||||||
global.__d = define;
|
global.__d = define;
|
||||||
var modules = Object.create(null);
|
var modules = typeof __NUM_MODULES__ === 'number' ? Array(__NUM_MODULES__ | 0) : Object.create(null);
|
||||||
|
|
||||||
function define(factory, moduleId, dependencyMap) {
|
function define(factory, moduleId, dependencyMap) {
|
||||||
if (moduleId in modules) {
|
if (modules[moduleId] != null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -204,17 +204,17 @@ require(0);"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`basic_bundle bundles package without polyfills 1`] = `
|
exports[`basic_bundle bundles package without polyfills 1`] = `
|
||||||
"var __DEV__=false,__BUNDLE_START_TIME__=this.nativePerformanceNow?nativePerformanceNow():Date.now(),process=this.process||{};process.env=process.env||{};process.env.NODE_ENV='production';
|
"var __DEV__=false,__BUNDLE_START_TIME__=this.nativePerformanceNow?nativePerformanceNow():Date.now(),process=this.process||{};process.env=process.env||{};process.env.NODE_ENV=\\"production\\";
|
||||||
(function (global) {
|
(function (global) {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var PRINT_REQUIRE_PATHS = false;
|
var PRINT_REQUIRE_PATHS = false;
|
||||||
global.require = metroRequire;
|
global.require = metroRequire;
|
||||||
global.__d = define;
|
global.__d = define;
|
||||||
var modules = Object.create(null);
|
var modules = typeof __NUM_MODULES__ === 'number' ? Array(__NUM_MODULES__ | 0) : Object.create(null);
|
||||||
|
|
||||||
function define(factory, moduleId, dependencyMap) {
|
function define(factory, moduleId, dependencyMap) {
|
||||||
if (moduleId in modules) {
|
if (modules[moduleId] != null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,22 +16,44 @@ const vm = require('vm');
|
||||||
|
|
||||||
['development', 'production'].forEach(mode => {
|
['development', 'production'].forEach(mode => {
|
||||||
describe(`${mode} mode`, () => {
|
describe(`${mode} mode`, () => {
|
||||||
|
const isDev = mode === 'development';
|
||||||
|
|
||||||
it('sets up `process.env.NODE_ENV` and `__DEV__`', () => {
|
it('sets up `process.env.NODE_ENV` and `__DEV__`', () => {
|
||||||
const sandbox: $FlowFixMe = {};
|
const sandbox: $FlowFixMe = {};
|
||||||
vm.createContext(sandbox);
|
vm.createContext(sandbox);
|
||||||
vm.runInContext(getPreludeCode({isDev: mode == 'development'}), sandbox);
|
vm.runInContext(getPreludeCode({isDev}), sandbox);
|
||||||
expect(sandbox.process.env.NODE_ENV).toEqual(mode);
|
expect(sandbox.process.env.NODE_ENV).toEqual(mode);
|
||||||
expect(sandbox.__DEV__).toEqual(mode == 'development');
|
expect(sandbox.__DEV__).toEqual(isDev);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('does not override an existing `process.env`', () => {
|
it('does not override an existing `process.env`', () => {
|
||||||
const nextTick = () => {};
|
const nextTick = () => {};
|
||||||
const sandbox: $FlowFixMe = {process: {nextTick, env: {FOOBAR: 123}}};
|
const sandbox: $FlowFixMe = {process: {nextTick, env: {FOOBAR: 123}}};
|
||||||
vm.createContext(sandbox);
|
vm.createContext(sandbox);
|
||||||
vm.runInContext(getPreludeCode({isDev: mode == 'development'}), sandbox);
|
vm.runInContext(getPreludeCode({isDev}), sandbox);
|
||||||
expect(sandbox.process.env.NODE_ENV).toEqual(mode);
|
expect(sandbox.process.env.NODE_ENV).toEqual(mode);
|
||||||
expect(sandbox.process.env.FOOBAR).toEqual(123);
|
expect(sandbox.process.env.FOOBAR).toEqual(123);
|
||||||
expect(sandbox.process.nextTick).toEqual(nextTick);
|
expect(sandbox.process.nextTick).toEqual(nextTick);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('allows to define additional variables', () => {
|
||||||
|
const sandbox: $FlowFixMe = {};
|
||||||
|
const FOO = '1';
|
||||||
|
const BAR = 2;
|
||||||
|
vm.createContext(sandbox);
|
||||||
|
vm.runInContext(getPreludeCode({isDev, extraVars: {FOO, BAR}}), sandbox);
|
||||||
|
expect(sandbox.FOO).toBe(FOO);
|
||||||
|
expect(sandbox.BAR).toBe(BAR);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does not override core variables with additional variables', () => {
|
||||||
|
const sandbox: $FlowFixMe = {};
|
||||||
|
vm.createContext(sandbox);
|
||||||
|
vm.runInContext(
|
||||||
|
getPreludeCode({isDev, extraVars: {__DEV__: 123}}),
|
||||||
|
sandbox,
|
||||||
|
);
|
||||||
|
expect(sandbox.__DEV__).toBe(isDev);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -10,13 +10,36 @@
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
function getPreludeCode({isDev}: {|+isDev: boolean|}): string {
|
function getPreludeCode({
|
||||||
return (
|
extraVars,
|
||||||
`var __DEV__=${String(isDev)},` +
|
isDev,
|
||||||
'__BUNDLE_START_TIME__=this.nativePerformanceNow?nativePerformanceNow():Date.now(),' +
|
}: {|
|
||||||
'process=this.process||{};process.env=process.env||{};' +
|
+extraVars?: {[string]: mixed},
|
||||||
`process.env.NODE_ENV='${isDev ? 'development' : 'production'}';`
|
+isDev: boolean,
|
||||||
);
|
|}): string {
|
||||||
|
const vars = [
|
||||||
|
...formatExtraVars(extraVars),
|
||||||
|
`__DEV__=${String(isDev)}`,
|
||||||
|
'__BUNDLE_START_TIME__=this.nativePerformanceNow?nativePerformanceNow():Date.now()',
|
||||||
|
'process=this.process||{}',
|
||||||
|
];
|
||||||
|
return `var ${vars.join(',')};${processEnv(
|
||||||
|
isDev ? 'development' : 'production',
|
||||||
|
)}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function formatExtraVars(extraVars) {
|
||||||
|
let assignments = [];
|
||||||
|
for (const key in extraVars) {
|
||||||
|
assignments.push(`${key}=${JSON.stringify(extraVars[key])}`);
|
||||||
|
}
|
||||||
|
return assignments;
|
||||||
|
}
|
||||||
|
|
||||||
|
function processEnv(nodeEnv) {
|
||||||
|
return `process.env=process.env||{};process.env.NODE_ENV=${JSON.stringify(
|
||||||
|
nodeEnv,
|
||||||
|
)};`;
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = getPreludeCode;
|
module.exports = getPreludeCode;
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
/* eslint-disable no-bitwise */
|
/* eslint-disable no-bitwise */
|
||||||
|
|
||||||
declare var __DEV__: boolean;
|
declare var __DEV__: boolean;
|
||||||
|
declare var __NUM_MODULES__: mixed;
|
||||||
|
|
||||||
type DependencyMap = Array<ModuleID>;
|
type DependencyMap = Array<ModuleID>;
|
||||||
type Exports = any;
|
type Exports = any;
|
||||||
|
@ -47,7 +48,6 @@ type ModuleDefinition = {|
|
||||||
verboseName?: string,
|
verboseName?: string,
|
||||||
path?: string,
|
path?: string,
|
||||||
|};
|
|};
|
||||||
type ModuleMap = {[key: ModuleID]: ModuleDefinition, __proto__: null};
|
|
||||||
type PatchedModules = {[ModuleID]: boolean};
|
type PatchedModules = {[ModuleID]: boolean};
|
||||||
type RequireFn = (id: ModuleID | VerboseModuleNameForDev) => Exports;
|
type RequireFn = (id: ModuleID | VerboseModuleNameForDev) => Exports;
|
||||||
type VerboseModuleNameForDev = string;
|
type VerboseModuleNameForDev = string;
|
||||||
|
@ -60,7 +60,10 @@ const PRINT_REQUIRE_PATHS = false;
|
||||||
global.require = metroRequire;
|
global.require = metroRequire;
|
||||||
global.__d = define;
|
global.__d = define;
|
||||||
|
|
||||||
const modules: ModuleMap = Object.create(null);
|
const modules =
|
||||||
|
typeof __NUM_MODULES__ === 'number'
|
||||||
|
? (Array(__NUM_MODULES__ | 0): Array<ModuleDefinition>)
|
||||||
|
: (Object.create(null): {[number]: ModuleDefinition, __proto__: null});
|
||||||
if (__DEV__) {
|
if (__DEV__) {
|
||||||
var verboseNamesToModuleIds: {
|
var verboseNamesToModuleIds: {
|
||||||
[key: string]: number,
|
[key: string]: number,
|
||||||
|
@ -73,7 +76,7 @@ function define(
|
||||||
moduleId: number,
|
moduleId: number,
|
||||||
dependencyMap?: DependencyMap,
|
dependencyMap?: DependencyMap,
|
||||||
) {
|
) {
|
||||||
if (moduleId in modules) {
|
if (modules[moduleId] != null) {
|
||||||
if (__DEV__) {
|
if (__DEV__) {
|
||||||
// (We take `inverseDependencies` from `arguments` to avoid an unused
|
// (We take `inverseDependencies` from `arguments` to avoid an unused
|
||||||
// named parameter in `define` in production.
|
// named parameter in `define` in production.
|
||||||
|
|
Loading…
Reference in New Issue