or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

async-loading.mdhmr-client.mdindex.mdrequire-polyfill.md

async-loading.mddocs/

0

# Asynchronous Module Loading

1

2

Core functionality for loading modules asynchronously with bundle splitting support. This system enables dynamic imports and code splitting in Metro bundles, allowing for lazy loading of application features and optimized bundle sizes.

3

4

## Capabilities

5

6

### asyncRequire Function

7

8

Loads a module asynchronously, with support for bundle splitting and dynamic loading.

9

10

```javascript { .api }

11

/**

12

* Asynchronously loads a module with bundle splitting support

13

* @param moduleID - Numeric identifier of the module to load

14

* @param paths - Mapping of module IDs to bundle paths for lazy loading

15

* @param moduleName - Optional module name for debugging (unused in implementation)

16

* @returns Promise resolving to the loaded module

17

*/

18

function asyncRequire(

19

moduleID: number,

20

paths: ?DependencyMapPaths,

21

moduleName?: string

22

): Promise<any>;

23

24

type DependencyMapPaths = ?$ReadOnly<{[moduleID: number | string]: mixed}>;

25

```

26

27

**Usage Examples:**

28

29

```javascript

30

const asyncRequire = require("metro-runtime/modules/asyncRequire");

31

32

// Load a feature module dynamically

33

const loadDashboard = async () => {

34

const dashboardModule = await asyncRequire(

35

123, // module ID assigned by Metro

36

{ 123: "/bundles/dashboard.bundle.js" }, // bundle path mapping

37

"dashboard" // optional name for debugging

38

);

39

return dashboardModule.default;

40

};

41

42

// Load multiple modules

43

const loadModules = async () => {

44

const [analytics, utils] = await Promise.all([

45

asyncRequire(200, { 200: "/bundles/analytics.js" }),

46

asyncRequire(201, { 201: "/bundles/utils.js" })

47

]);

48

return { analytics, utils };

49

};

50

```

51

52

### unstable_importMaybeSync Method

53

54

Synchronous version of asyncRequire that can still return a promise if the module requires bundle loading.

55

56

```javascript { .api }

57

/**

58

* Loads a module synchronously if available, asynchronously if bundle loading required

59

* @param moduleID - Numeric identifier of the module to load

60

* @param paths - Mapping of module IDs to bundle paths

61

* @returns Either the loaded module directly, or a Promise resolving to it

62

*/

63

asyncRequire.unstable_importMaybeSync = function(

64

moduleID: number,

65

paths: ?DependencyMapPaths

66

): Promise<any> | any;

67

```

68

69

**Usage Examples:**

70

71

```javascript

72

// Import that may be sync or async depending on bundle availability

73

const maybeLoadModule = (moduleId, paths) => {

74

const result = asyncRequire.unstable_importMaybeSync(moduleId, paths);

75

76

if (result instanceof Promise) {

77

// Module requires bundle loading

78

return result.then(module => {

79

console.log("Module loaded asynchronously");

80

return module;

81

});

82

} else {

83

// Module was already available

84

console.log("Module loaded synchronously");

85

return result;

86

}

87

};

88

```

89

90

### prefetch Method

91

92

Pre-loads a bundle without executing the module, useful for optimizing perceived performance.

93

94

```javascript { .api }

95

/**

96

* Pre-loads a bundle without executing the module

97

* @param moduleID - Numeric identifier of the module to prefetch

98

* @param paths - Mapping of module IDs to bundle paths

99

* @param moduleName - Optional module name for debugging (unused)

100

*/

101

asyncRequire.prefetch = function(

102

moduleID: number,

103

paths: ?DependencyMapPaths,

104

moduleName?: string

105

): void;

106

```

107

108

**Usage Examples:**

109

110

```javascript

111

// Prefetch modules that might be needed soon

112

const prefetchFeatures = () => {

113

const bundlePaths = {

114

100: "/bundles/settings.js",

115

101: "/bundles/profile.js",

116

102: "/bundles/notifications.js"

117

};

118

119

// Prefetch all feature bundles

120

asyncRequire.prefetch(100, bundlePaths, "settings");

121

asyncRequire.prefetch(101, bundlePaths, "profile");

122

asyncRequire.prefetch(102, bundlePaths, "notifications");

123

};

124

125

// Prefetch on user interaction

126

button.addEventListener("click", () => {

127

// Start loading the module before user needs it

128

asyncRequire.prefetch(150, { 150: "/bundles/heavy-feature.js" });

129

});

130

```

131

132

## Bundle Loading Mechanics

133

134

The async loading system works by:

135

136

1. **Module ID Resolution**: Each module is assigned a numeric ID by Metro bundler

137

2. **Path Mapping**: The `paths` parameter maps module IDs to their bundle URLs

138

3. **Global Bundle Loader**: Uses `global[__METRO_GLOBAL_PREFIX__ + '__loadBundleAsync']` to load bundles

139

4. **Fallback to Sync**: If no bundle loading is required, falls back to synchronous `require.importAll`

140

141

## Bundle Path Configuration

142

143

Bundle paths in the `paths` parameter should be configured based on your deployment:

144

145

```javascript

146

// Development configuration

147

const devPaths = {

148

42: "http://localhost:8081/bundles/feature.bundle.js"

149

};

150

151

// Production configuration

152

const prodPaths = {

153

42: "https://cdn.example.com/bundles/feature.bundle.js"

154

};

155

156

// React Native configuration

157

const nativePaths = {

158

42: "./bundles/feature.bundle"

159

};

160

```

161

162

## Error Handling

163

164

Bundle loading errors are handled gracefully:

165

166

```javascript

167

const safeAsyncRequire = async (moduleId, paths) => {

168

try {

169

const module = await asyncRequire(moduleId, paths);

170

return module;

171

} catch (error) {

172

console.error(`Failed to load module ${moduleId}:`, error);

173

// Return fallback or default implementation

174

return null;

175

}

176

};

177

```

178

179

## Integration with Metro Bundler

180

181

Metro Runtime's async loading system is designed to work seamlessly with Metro bundler's code splitting:

182

183

- Module IDs are assigned automatically during bundling

184

- Bundle paths are generated based on Metro's splitting configuration

185

- The system handles both web and React Native deployment scenarios

186

- Supports both development and production bundle loading strategies