Webpack plugin for optimizing Perspective.js builds by handling WebAssembly and Web Worker assets
npx @tessl/cli install tessl/npm-finos--perspective-webpack-plugin@3.2.0The @finos/perspective-webpack-plugin is a specialized webpack plugin designed to optimize the build process for applications using Perspective.js, a powerful analytics and data visualization library. The plugin prevents performance degradation by properly handling WebAssembly and Web Worker assets, copying them to the output directory instead of inlining them as base64 strings.
npm install @finos/perspective-webpack-pluginconst PerspectivePlugin = require("@finos/perspective-webpack-plugin");Alternative import (may require configuration):
// Note: This package uses CommonJS exports
const PerspectivePlugin = require("@finos/perspective-webpack-plugin");
import PerspectivePlugin from "@finos/perspective-webpack-plugin"; // May work in some configurations// Primary import method
const PerspectivePlugin = require("@finos/perspective-webpack-plugin");
module.exports = {
entry: "./src/index.js",
output: {
filename: "bundle.js",
path: "dist"
},
plugins: [
new PerspectivePlugin()
]
};With custom options:
const PerspectivePlugin = require("@finos/perspective-webpack-plugin");
module.exports = {
plugins: [
new PerspectivePlugin({
inline: false,
inlineWasm: false,
wasmPath: "./custom/wasm/path",
wasmName: "[name]-[contenthash].wasm"
})
]
};The plugin operates by:
resolve.fallback to disable Node.js polyfills for path and fs modules (required by Emscripten outputs)webpack.NormalModuleReplacementPlugin to redirect Perspective imports to optimized CDN buildsCreates a new instance of the Perspective webpack plugin with configurable options.
/**
* Creates a new PerspectiveWebpackPlugin instance
* @param {Object} options - Plugin configuration options (optional)
* @returns {PerspectiveWebpackPlugin} Plugin instance
*/
constructor(options)Applies the plugin configuration to the webpack compiler. This is the main method called by webpack.
/**
* Applies the plugin to the webpack compiler
* @param {Object} compiler - Webpack compiler instance
* @returns {void}
*/
apply(compiler)All configuration options are optional and have sensible defaults.
/**
* Configuration options for PerspectiveWebpackPlugin
* All options are optional and have sensible defaults
*/
interface PluginOptions {
/**
* General inline mode setting - when true, overrides both inlineWasm and inlineWorker
* (default: false)
*/
inline?: boolean;
/**
* Whether to inline WebAssembly files as base64 strings in the bundle
* When false, .wasm files are copied to output directory as separate assets
* (default: false - recommended for production)
*/
inlineWasm?: boolean;
/**
* Whether to inline worker files in the main bundle
* When false, workers are treated as separate assets
* (default: false)
*/
inlineWorker?: boolean;
/**
* Path to directory containing WebAssembly files
* (default: resolved path to @finos/perspective package directory)
*/
wasmPath?: string;
/**
* Path to perspective-viewer package directory
* (default: resolved path to @finos/perspective-viewer package directory)
*/
viewerPath?: string;
/**
* Path to directory containing worker files
* (default: resolved path to @finos/perspective package directory)
*/
workerPath?: string;
/**
* Output naming pattern for WebAssembly files - supports webpack placeholders
* Common patterns: "[name].wasm", "[name]-[contenthash].wasm"
* (default: "[name].wasm")
*/
wasmName?: string;
/**
* Output naming pattern for worker files - supports webpack placeholders
* Common patterns: "[name].js", "[name]-[contenthash].js"
* (default: "[name].js")
*/
workerName?: string;
}Configuration Examples:
// Minimal configuration (uses all defaults)
new PerspectivePlugin()
// Asset optimization configuration
new PerspectivePlugin({
inline: false,
inlineWasm: false,
wasmName: "[name]-[hash].wasm",
workerName: "[name]-[hash].js"
})
// Custom paths configuration
new PerspectivePlugin({
wasmPath: path.resolve(__dirname, "node_modules/@finos/perspective"),
viewerPath: path.resolve(__dirname, "custom/viewer/path"),
workerPath: path.resolve(__dirname, "workers")
})
// Inline mode configuration (not recommended for production)
new PerspectivePlugin({
inline: true,
inlineWasm: true,
inlineWorker: true
})The plugin automatically disables webpack's Node.js polyfills for modules that Emscripten outputs reference but don't actually use in browser environments:
// Automatically applied by the plugin
resolve: {
fallback: {
path: false,
fs: false
}
}This prevents webpack from bundling unnecessary polyfills and avoids runtime errors when these modules are referenced but not called.
The plugin configures webpack rules for .wasm files based on the inline and inlineWasm options:
inline: false, inlineWasm: false): WebAssembly files use type: "asset/resource" and are copied to the output directory with optional naming patternsinline: true or inlineWasm: true): WebAssembly files use arraybuffer-loader with type: "javascript/auto" to embed as base64 strings in the bundlePerformance Note: Inline mode significantly increases bundle size and is not recommended for production as it can cause performance degradation during initial load.
The plugin automatically replaces Perspective module imports with optimized CDN builds:
@finos/perspective → @finos/perspective/dist/cdn/perspective.js@finos/perspective-viewer → @finos/perspective-viewer/dist/cdn/perspective-viewer.js@finos/perspective-workspace → @finos/perspective-workspace/dist/cdn/perspective-workspace.jsThe plugin modifies webpack configuration by:
resolve.fallback.path = false and resolve.fallback.fs = false to prevent webpack from providing Node.js polyfills that Emscripten doesn't expect in browser environments.wasm files:
type: "asset/resource" to copy WebAssembly files to output directoryarraybuffer-loader with type: "javascript/auto" to embed as base64NormalModuleReplacementPlugin instances to redirect:
@finos/perspective → @finos/perspective/dist/cdn/perspective.js@finos/perspective-viewer → @finos/perspective-viewer/dist/cdn/perspective-viewer.js@finos/perspective-workspace → @finos/perspective-workspace/dist/cdn/perspective-workspace.jsinline or inlineWorker flags are enabledNote: The source code contains a potential issue where worker inline configuration attempts to access rules[rules.length - 1] before ensuring the rules array is populated.
/**
* Main plugin class for webpack integration
* Optimizes Perspective.js builds by handling WebAssembly and Web Worker assets
*
* This plugin prevents performance degradation by ensuring WebAssembly files
* and workers are handled optimally rather than being inlined as base64 strings.
*/
class PerspectiveWebpackPlugin {
/**
* Plugin options merged with defaults
*/
options: PluginOptions;
/**
* Creates a new plugin instance with merged configuration
* @param {PluginOptions} options - Plugin configuration options (optional)
*/
constructor(options?: PluginOptions);
/**
* Applies the plugin configuration to webpack compiler
* Modifies webpack's module rules, resolve fallbacks, and applies module replacements
* @param {Object} compiler - Webpack compiler instance
* @returns {void}
*/
apply(compiler: any): void;
}The plugin requires the following peer dependencies:
@finos/perspective: workspace:^ (or appropriate version)@finos/perspective-viewer: workspace:^ (or appropriate version)webpack: ^5.60.0Internal dependencies (automatically installed):
arraybuffer-loader: ^1.0.2 (for WebAssembly inlining)css-loader: ^6.7.3 (for CSS processing)exports-loader: ^3.1.0 (for module export handling)string-replace-loader: ^3.0.1 (for string replacements)worker-loader: ^3.0.7 (for Web Worker processing)Version Compatibility: This plugin is designed for webpack 5.x and may not be compatible with earlier webpack versions due to its use of type: "asset/resource" and other webpack 5-specific features.