Prebuild Webpack Plugin
Prebuild Webpack Plugin is a utility designed to execute file processing and I/O operations before a webpack build commences. It currently stands at stable version 1.1.1, with a history of steady, active development and releases addressing issues and improving performance. This plugin distinguishes itself by offering dedicated `build` and `watch` hooks that fire before the initial webpack compilation and on subsequent rebuilds, respectively. It supports file matching via minimatch patterns, allowing for targeted pre-processing. A key feature is the ability to explicitly add matched files to webpack's dependency tree and specific handling for complex build environments like Next.js through the `compilationNameFilter` option, enabling users to optimize for client-side or server-side compilations. It is particularly useful for scenarios requiring data transformation or external resource fetching prior to bundling, providing a flexible interface for such tasks.
Common errors
-
TypeError: (0, prebuild_webpack_plugin_1.PrebuildWebpackPlugin) is not a constructor
cause Attempting to import `PrebuildWebpackPlugin` as a named export after v1.0.0, when it became a default export.fixUpdate your import statement to `import PrebuildPlugin from 'prebuild-webpack-plugin';` for ESM or `const PrebuildPlugin = require('prebuild-webpack-plugin');` for CommonJS. -
Error: Cannot find module '@hashicorp/prebuild-webpack-plugin'
cause The package name changed in v1.0.0, but the old scoped package name is still being referenced.fixUpdate your `package.json` to use `prebuild-webpack-plugin` and ensure all import/require statements also use the new package name. -
Files added to the watched directory are not being detected by the 'watch' hook, or 'matchedFiles' in 'build' is missing new entries after adding new files without restarting.
cause By default, the plugin caches the file tree from initial bootup. Newly added files are not automatically detected in subsequent watch runs unless `clearCacheOnUpdate` is enabled.fixFor development workflows where new files are frequently added, set `clearCacheOnUpdate: true` in the plugin options. Be aware of the potential performance impact. For production builds or less dynamic scenarios, restart the webpack process after adding new files.
Warnings
- breaking The npm package name changed from `@hashicorp/prebuild-webpack-plugin` to `prebuild-webpack-plugin`. Projects using the old package name will fail to resolve the module.
- breaking The plugin's export method changed from a named export (`PrebuildWebpackPlugin`) to a default export. Incorrect import statements will lead to errors like `TypeError: PrebuildPlugin is not a constructor`.
- gotcha When using symlinks with the `files` matching option, unusual behavior could occur prior to v1.1.0, specifically regarding how file paths were resolved.
- gotcha Enabling the `clearCacheOnUpdate` option to handle newly added files in watch mode incurs a 'reasonably large performance penalty' because it forces a re-read of the entire file tree on every watch event.
- gotcha In multi-compilation environments like Next.js, the plugin might execute its logic multiple times (e.g., once for the client and once for the server) leading to redundant work.
Install
-
npm install prebuild-webpack-plugin -
yarn add prebuild-webpack-plugin -
pnpm add prebuild-webpack-plugin
Imports
- PrebuildPlugin
import { PrebuildWebpackPlugin } from 'prebuild-webpack-plugin';import PrebuildPlugin from 'prebuild-webpack-plugin';
- PrebuildPlugin (CommonJS)
const { PrebuildWebpackPlugin } = require('@hashicorp/prebuild-webpack-plugin');const PrebuildPlugin = require('prebuild-webpack-plugin');
Quickstart
const PrebuildPlugin = require('prebuild-webpack-plugin');
const path = require('path');
const fs = require('fs/promises');
module.exports = {
// ... webpack config ...
plugins: [
new PrebuildPlugin({
build: async (compiler, compilation, matchedFiles) => {
console.log('Prebuild phase started!');
// Example: Read and log content of matched markdown files
for (const file of matchedFiles) {
const content = await fs.readFile(file, 'utf8');
console.log(`Prebuilt content of ${path.basename(file)}:\n${content.substring(0, 100)}...`);
}
console.log('Prebuild phase completed!');
},
watch: async (compiler, compilation, changedFile) => {
console.log(`File changed in watch mode: ${changedFile}`);
// Example: Process the changed file on each rebuild
if (changedFile.endsWith('.md')) {
const content = await fs.readFile(changedFile, 'utf8');
console.log(`Watch-mode processing for ${path.basename(changedFile)}:\n${content.substring(0, 50)}...`);
}
},
files: {
pattern: '**/*.md',
options: { cwd: path.resolve(__dirname, 'src') },
addFilesAsDependencies: true
},
clearCacheOnUpdate: false
}),
],
};