or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

index.md

index.mddocs/

0

# Static Site Generator Webpack Plugin

1

2

Static Site Generator Webpack Plugin is a minimal, unopinionated static site generator powered by webpack. It enables static site generation by executing a custom render function at build time to generate HTML files for specified paths, supporting both manual path specification and automatic site crawling.

3

4

## Package Information

5

6

- **Package Name**: static-site-generator-webpack-plugin

7

- **Package Type**: npm

8

- **Language**: JavaScript

9

- **Installation**: `npm install --save-dev static-site-generator-webpack-plugin`

10

11

## Core Imports

12

13

```javascript

14

const StaticSiteGeneratorPlugin = require('static-site-generator-webpack-plugin');

15

```

16

17

For ES modules:

18

19

```javascript

20

import StaticSiteGeneratorPlugin from 'static-site-generator-webpack-plugin';

21

```

22

23

## Basic Usage

24

25

```javascript

26

// webpack.config.js

27

const StaticSiteGeneratorPlugin = require('static-site-generator-webpack-plugin');

28

29

module.exports = {

30

entry: './index.js',

31

32

output: {

33

filename: 'index.js',

34

path: 'dist',

35

libraryTarget: 'umd' // Required for Node.js execution

36

},

37

38

plugins: [

39

new StaticSiteGeneratorPlugin({

40

paths: ['/hello/', '/world/'],

41

locals: {

42

greet: 'Hello'

43

}

44

})

45

]

46

};

47

48

// index.js - render function

49

module.exports = function render(locals) {

50

return '<html>' + locals.greet + ' from ' + locals.path + '</html>';

51

};

52

53

// ES module default export pattern

54

export default function render(locals) {

55

return `<html>${locals.greet} from ${locals.path}</html>`;

56

};

57

```

58

59

## Architecture

60

61

The plugin integrates into webpack's compilation process through several key components:

62

63

- **Plugin Constructor**: Configures paths, locals, globals, and crawling behavior

64

- **Webpack Integration**: Hooks into webpack's `thisCompilation` and `optimizeAssets` phases

65

- **Render Function Execution**: Evaluates the compiled entry file as a render function

66

- **Asset Generation**: Creates HTML assets in webpack's output for each rendered path

67

- **Crawling Engine**: Optionally discovers additional paths by parsing HTML for relative links

68

69

## Capabilities

70

71

### Plugin Configuration

72

73

Creates a webpack plugin instance with configuration options for static site generation.

74

75

```javascript { .api }

76

/**

77

* Static Site Generator Webpack Plugin constructor

78

* @param {Object} options - Configuration options

79

*/

80

function StaticSiteGeneratorWebpackPlugin(options);

81

82

interface StaticSiteGeneratorOptions {

83

/** Webpack entry chunk name (defaults to first chunk if not specified) */

84

entry?: string;

85

/** Array of paths OR single path to render (defaults to ['/'] if not provided) */

86

paths?: string[] | string;

87

/** Custom properties merged into locals object passed to render function */

88

locals?: object;

89

/** Object that exists in global scope when executing render function */

90

globals?: object;

91

/** Enables automatic crawling of relative links and iframes */

92

crawl?: boolean;

93

}

94

```

95

96

**Usage Examples:**

97

98

```javascript

99

// Basic configuration with multiple paths

100

new StaticSiteGeneratorPlugin({

101

paths: ['/about/', '/contact/', '/blog/'],

102

locals: {

103

siteName: 'My Website',

104

version: '1.0.0'

105

}

106

});

107

108

// Single path configuration (automatically converted to array)

109

new StaticSiteGeneratorPlugin({

110

paths: '/', // Equivalent to paths: ['/']

111

locals: { data: 'value' }

112

});

113

114

// Crawling mode

115

new StaticSiteGeneratorPlugin({

116

crawl: true,

117

paths: ['/'], // Entry point for crawling

118

locals: { navigation: menuData }

119

});

120

121

// Custom entry point and globals

122

new StaticSiteGeneratorPlugin({

123

entry: 'main',

124

paths: ['/'],

125

globals: { window: {} }, // For browser-dependent libraries

126

locals: { config: appConfig }

127

});

128

```

129

130

### Render Function Requirements

131

132

The entry file must export a render function that accepts locals and returns HTML. The plugin supports three execution patterns:

133

134

```javascript { .api }

135

/** Synchronous render function */

136

function render(locals: RenderLocals): string;

137

138

/** Callback-based render function */

139

function render(locals: RenderLocals, callback: (error: Error | null, html: string) => void): void;

140

141

/** Promise-based render function */

142

function render(locals: RenderLocals): Promise<string>;

143

144

/** Multi-path render function returning object with path-to-HTML mapping */

145

function render(locals: RenderLocals): string | Promise<string> | { [path: string]: string };

146

147

interface RenderLocals {

148

/** The path currently being rendered */

149

path: string;

150

/** Object containing all webpack assets by chunk name */

151

assets: { [chunkName: string]: string };

152

/** Advanced webpack compilation statistics */

153

webpackStats: object;

154

/** Custom properties from plugin configuration */

155

[key: string]: any;

156

}

157

```

158

159

**Usage Examples:**

160

161

```javascript

162

// Synchronous rendering

163

module.exports = function render(locals) {

164

return `<html><body><h1>Welcome to ${locals.path}</h1></body></html>`;

165

};

166

167

// Async rendering with callbacks

168

module.exports = function render(locals, callback) {

169

setTimeout(() => {

170

const html = generatePage(locals.path, locals.data);

171

callback(null, html);

172

}, 100);

173

};

174

175

// Promise-based rendering

176

module.exports = function render(locals) {

177

return fetchPageData(locals.path)

178

.then(data => renderTemplate(data))

179

.then(html => html);

180

};

181

182

// Multi-path rendering

183

module.exports = function render(locals) {

184

return {

185

'/': '<html>Home Page</html>',

186

'/about': '<html>About Page</html>',

187

'/contact': '<html>Contact Page</html>'

188

};

189

};

190

191

// Using assets in render function

192

module.exports = function render(locals) {

193

const jsFiles = Object.values(locals.assets).filter(file => file.endsWith('.js'));

194

const cssFiles = Object.values(locals.assets).filter(file => file.endsWith('.css'));

195

196

return `

197

<html>

198

<head>

199

${cssFiles.map(css => `<link rel="stylesheet" href="${css}">`).join('\\n')}

200

</head>

201

<body>

202

<h1>Page: ${locals.path}</h1>

203

${jsFiles.map(js => `<script src="${js}"></script>`).join('\\n')}

204

</body>

205

</html>

206

`;

207

};

208

209

// Note: Asset paths in locals.assets automatically include webpack's

210

// output.publicPath if configured, so no manual path resolution needed

211

```

212

213

### Crawling Mode

214

215

Automatic discovery of additional paths by parsing HTML for relative links and iframe sources.

216

217

When `crawl: true` is enabled, the plugin:

218

1. Renders the initial paths specified in configuration

219

2. Parses generated HTML for `<a href="...">` and `<iframe src="...">` tags

220

3. Extracts relative URLs (excluding external links and protocol-relative URLs)

221

4. Recursively renders discovered paths until no new paths are found

222

223

**Crawling Rules:**

224

- Only follows relative paths (not absolute URLs or external links)

225

- Converts `/path` to `/path/index.html` if no file extension

226

- Ignores protocol-relative URLs (`//example.com`)

227

- Ignores URLs with protocols (`http://`, `https://`, `ftp://`)

228

- Processes both root-relative (`/about`) and document-relative (`../contact`) links

229

230

```javascript

231

// Enable crawling with entry points

232

new StaticSiteGeneratorPlugin({

233

crawl: true,

234

paths: ['/', '/blog/'], // Multiple crawl entry points

235

locals: { siteData: data }

236

});

237

```

238

239

### Custom File Names

240

241

Generate custom file names by providing paths ending in `.html`.

242

243

```javascript { .api }

244

// Configuration for custom file names

245

new StaticSiteGeneratorPlugin({

246

paths: [

247

'/index.html',

248

'/news.html',

249

'/about.html'

250

]

251

});

252

```

253

254

**Note:** Custom file names may break compatibility with client-side routing if using frameworks like React Router.

255

256

### Legacy Constructor Arguments

257

258

Support for legacy constructor signature with positional arguments.

259

260

```javascript { .api }

261

/**

262

* Legacy constructor signature (deprecated)

263

* @param {string} entry - Entry chunk name

264

* @param {string[]} paths - Paths to render

265

* @param {object} locals - Local variables

266

* @param {object} globals - Global variables

267

*/

268

function StaticSiteGeneratorWebpackPlugin(entry, paths, locals, globals);

269

```

270

271

**Usage Example:**

272

273

```javascript

274

// Legacy usage (deprecated)

275

new StaticSiteGeneratorPlugin(

276

'main', // entry

277

['/'], // paths

278

{ data: 'value' }, // locals

279

{ window: {} } // globals

280

);

281

```

282

283

## Error Handling

284

285

The plugin handles several error conditions:

286

287

- **Missing Entry File**: Throws error if specified entry chunk is not found in webpack assets

288

- **Invalid Render Function**: Throws error if entry file export is not a function

289

- **Render Function Errors**: Captures render function exceptions and adds them to webpack's compilation errors

290

- **Asset Generation Errors**: Handles errors during HTML asset creation

291

292

Common error messages:

293

- `Source file not found: "entryName"` - Entry chunk not found in webpack output

294

- `Export from "entryName" must be a function that returns an HTML string. Is output.libraryTarget in the configuration set to "umd"?` - Entry file doesn't export a function or webpack output configuration is incorrect

295

- Render function stack traces are preserved in compilation.errors

296

297

## Webpack Integration Requirements

298

299

- **Output Configuration**: Must set `output.libraryTarget` to `'umd'` or `'commonjs'` for Node.js execution

300

- **Compilation Phase**: Plugin executes during webpack's `optimize-assets` phase

301

- **Asset Generation**: Creates new assets in webpack's compilation.assets object

302

- **Compatibility**: Supports both webpack 3.x/4.x (legacy plugin API) and webpack 5.x (hooks API) with automatic detection

303

304

```javascript

305

// Required webpack configuration

306

module.exports = {

307

output: {

308

libraryTarget: 'umd' // Essential for Node.js execution

309

},

310

plugins: [

311

new StaticSiteGeneratorPlugin(options)

312

]

313

};

314

```