or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

index.md
tile.json

index.mddocs/

0

# @loadable/babel-plugin

1

2

@loadable/babel-plugin is a Babel plugin that transforms loadable component function calls to enable server-side rendering (SSR) support in React applications. The plugin analyzes dynamic import() statements within loadable() calls and injects additional properties required for SSR, including chunk names, synchronous loading methods, and module resolution functions.

3

4

## Package Information

5

6

- **Package Name**: @loadable/babel-plugin

7

- **Package Type**: npm

8

- **Language**: JavaScript

9

- **Installation**: `npm install --save-dev @loadable/babel-plugin`

10

11

## Core Imports

12

13

```javascript

14

// Babel plugin configuration (in babel.config.js or .babelrc)

15

module.exports = {

16

plugins: ['@loadable/babel-plugin']

17

};

18

```

19

20

For custom import signatures:

21

22

```javascript

23

module.exports = {

24

plugins: [

25

['@loadable/babel-plugin', {

26

signatures: [

27

{ name: 'default', from: '@loadable/component' },

28

{ name: 'loadable', from: 'my-custom-loadable' }

29

]

30

}]

31

]

32

};

33

```

34

35

## Basic Usage

36

37

The plugin transforms loadable component calls automatically during build time:

38

39

```javascript

40

// Input code

41

import loadable from '@loadable/component';

42

43

const AsyncComponent = loadable(() => import('./MyComponent'));

44

45

// Plugin transforms this to include SSR properties

46

const AsyncComponent = loadable({

47

chunkName(props) { return 'MyComponent'; },

48

isReady(props) { /* ... */ },

49

importAsync: () => import('./MyComponent'),

50

requireAsync(props) { /* ... */ },

51

requireSync(props) { /* ... */ },

52

resolve(props) { /* ... */ },

53

resolved: {}

54

});

55

```

56

57

## Architecture

58

59

The plugin operates during Babel's AST transformation phase and consists of:

60

61

- **Main Plugin**: Entry point that configures visitor patterns and transformation logic

62

- **Property Generators**: Modules that create the injected SSR-support methods

63

- **Signature Detection**: Logic to identify loadable function calls based on import patterns

64

- **AST Transformation**: Code that replaces loadable function calls with enhanced objects

65

66

## Capabilities

67

68

### Plugin Configuration

69

70

Configure which import patterns the plugin should transform.

71

72

```javascript { .api }

73

/**

74

* Main Babel plugin export - configured in Babel configuration

75

* @param api - Babel API object containing types and other utilities

76

* @param options - Plugin configuration options

77

* @returns Babel plugin object with visitor methods

78

*/

79

function loadablePlugin(api: object, options: LoadablePluginOptions): BabelPlugin;

80

81

interface LoadablePluginOptions {

82

/** Array of import signature patterns to transform */

83

signatures?: ImportSignature[];

84

}

85

86

interface ImportSignature {

87

/** Import specifier name ('default' for default imports, or named import) */

88

name: string;

89

/** Package name to match for transformation */

90

from: string;

91

}

92

93

interface BabelPlugin {

94

/** Inherits syntax-dynamic-import plugin for import() support */

95

inherits: object;

96

/** AST visitor configuration */

97

visitor: {

98

Program: {

99

enter(programPath: object): void;

100

};

101

};

102

}

103

```

104

105

**Default Configuration:**

106

107

```javascript

108

// Default signatures - transforms @loadable/component imports

109

const DEFAULT_SIGNATURE = [{ name: 'default', from: '@loadable/component' }];

110

```

111

112

### Transformation Targets

113

114

The plugin identifies and transforms these patterns:

115

116

```javascript { .api }

117

// 1. loadable() function calls (based on import signatures)

118

loadable(() => import('./Component'))

119

120

// 2. lazy() function calls (when imported from @loadable/component)

121

import { lazy } from '@loadable/component';

122

lazy(() => import('./Component'))

123

124

// 3. loadable.lib() method calls

125

loadable.lib(() => import('./library'))

126

127

// 4. Functions with #__LOADABLE__ comment - supports multiple function types:

128

/* #__LOADABLE__ */ () => import('./Component') // Arrow function

129

/* #__LOADABLE__ */ function() { return import('./Component') } // Function expression

130

const obj = { /* #__LOADABLE__ */ load() { return import('./Component') } } // Object method

131

```

132

133

### Generated Runtime Methods

134

135

When the plugin transforms a loadable call, it injects these SSR-support methods:

136

137

```javascript { .api }

138

interface LoadableComponentObject {

139

/**

140

* Generates webpack chunk name for the dynamic import

141

* Handles webpack comments and template literals

142

*/

143

chunkName(props: any): string;

144

145

/**

146

* Checks if the module is ready (loaded) for synchronous rendering

147

* Returns true if module is available in webpack module cache

148

*/

149

isReady(props: any): boolean;

150

151

/**

152

* Original async import function - preserves the dynamic import()

153

*/

154

importAsync: () => Promise<any>;

155

156

/**

157

* Async module loading with resolution tracking

158

* Updates resolved state when promise completes

159

*/

160

requireAsync(props: any): Promise<any>;

161

162

/**

163

* Synchronous module loading for SSR

164

* Uses __webpack_require__ or Node.js require based on environment

165

*/

166

requireSync(props: any): any;

167

168

/**

169

* Resolves module ID for the dynamic import

170

* Uses require.resolveWeak or require.resolve based on availability

171

*/

172

resolve(props: any): string;

173

174

/**

175

* Object tracking resolved module states

176

* Maps module IDs to boolean resolution status

177

*/

178

resolved: Record<string, boolean>;

179

}

180

```

181

182

### Webpack Integration

183

184

The plugin handles webpack-specific features for chunk naming and module resolution:

185

186

```javascript { .api }

187

// Webpack comment processing for chunk names

188

import(

189

/* webpackChunkName: "my-chunk" */

190

'./Component'

191

);

192

193

// Template literal support for dynamic chunk names

194

const componentName = 'MyComponent';

195

import(`./components/${componentName}`);

196

```

197

198

**Chunk Name Generation Rules:**

199

200

- Static imports: Uses file path converted to chunk-safe format

201

- Template literals: Preserves dynamic expressions with sanitization

202

- Webpack comments: Respects existing webpackChunkName comments

203

- Path normalization: Removes file extensions and converts special characters to hyphens

204

205

### Error Handling

206

207

The plugin validates usage patterns and throws errors for unsupported configurations:

208

209

```javascript { .api }

210

// Error: Multiple import calls not supported

211

loadable(() => {

212

import('./ComponentA');

213

import('./ComponentB'); // Throws error

214

});

215

```

216

217

**Common Error Messages:**

218

219

- `"loadable: multiple import calls inside loadable() function are not supported"`

220

- Webpack comment parsing errors with compilation context

221

- Template literal processing errors for invalid expressions

222

223

### Environment Detection

224

225

The plugin generates environment-aware code that works in different contexts:

226

227

```javascript { .api }

228

// Browser environment (webpack)

229

if (typeof __webpack_require__ !== 'undefined') {

230

return __webpack_require__(id);

231

}

232

233

// Node.js environment

234

return eval('module.require')(id);

235

236

// Webpack modules check

237

if (typeof __webpack_modules__ !== 'undefined') {

238

return !!(__webpack_modules__[key]);

239

}

240

```

241

242

## Types

243

244

```javascript { .api }

245

// Plugin accepts these configuration options

246

interface LoadablePluginOptions {

247

signatures?: ImportSignature[];

248

}

249

250

interface ImportSignature {

251

name: string; // 'default' | string (named import)

252

from: string; // Package name like '@loadable/component'

253

}

254

255

// Internal transformation context

256

interface TransformContext {

257

path: object; // Babel AST path to the loadable call

258

callPath: object; // Babel AST path to the import() call

259

funcPath: object; // Babel AST path to the function expression

260

}

261

262

// Generated object structure

263

interface GeneratedLoadableObject {

264

chunkName(props: any): string;

265

isReady(props: any): boolean;

266

importAsync: () => Promise<any>;

267

requireAsync(props: any): Promise<any>;

268

requireSync(props: any): any;

269

resolve(props: any): string | number;

270

resolved: Record<string, boolean>;

271

}

272

```