or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

tessl/npm-webpack-virtual-modules

Webpack plugin for dynamically generating in-memory virtual modules

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/webpack-virtual-modules@0.6.x

To install, run

npx @tessl/cli install tessl/npm-webpack-virtual-modules@0.6.0

index.mddocs/

Webpack Virtual Modules

Webpack Virtual Modules is a plugin that enables dynamical generation of in-memory virtual modules for JavaScript builds created with webpack. When virtual modules are created, all parent virtual directories that lead to the module filename are automatically created too. This plugin supports webpack's watch mode, meaning any write to a virtual module is seen by webpack as if a real file stored on disk has changed.

Package Information

  • Package Name: webpack-virtual-modules
  • Package Type: npm
  • Language: TypeScript
  • Installation: npm install webpack-virtual-modules --save-dev

Core Imports

const VirtualModulesPlugin = require("webpack-virtual-modules");

For TypeScript with proper typing:

import VirtualModulesPlugin = require("webpack-virtual-modules");
import { Compiler } from "webpack";

// VirtualStats class is also available
const { VirtualStats } = VirtualModulesPlugin;

// Or with CommonJS require  
const VirtualModulesPlugin = require("webpack-virtual-modules");
const { Compiler } = require("webpack"); // For type reference only

Basic Usage

Static Virtual Modules

Define virtual modules at webpack configuration time:

const VirtualModulesPlugin = require("webpack-virtual-modules");

const virtualModules = new VirtualModulesPlugin({
  'node_modules/module-foo.js': 'module.exports = { foo: "foo" };',
  'node_modules/module-bar.js': 'module.exports = { bar: "bar" };'
});

// webpack.config.js
module.exports = {
  plugins: [virtualModules],
  // ...other config
};

// Use in your code
const moduleFoo = require('module-foo');
console.log(moduleFoo.foo);

Dynamic Virtual Modules

Create and modify virtual modules during the build process:

const VirtualModulesPlugin = require("webpack-virtual-modules");
const webpack = require("webpack");

const virtualModules = new VirtualModulesPlugin();

const compiler = webpack({
  plugins: [virtualModules],
  // ...other config
});

// Create virtual modules dynamically
compiler.hooks.compilation.tap('MyPlugin', function(compilation) {
  virtualModules.writeModule('dynamic-module.js', `
    module.exports = {
      timestamp: ${Date.now()},
      message: "Generated at build time"
    };
  `);
});

Architecture

Webpack Virtual Modules works by:

  1. Filesystem Integration: Hooks into webpack's input filesystem to provide virtual file access
  2. Memory Storage: Maintains virtual files entirely in memory without touching the actual filesystem
  3. Watch Mode Support: Integrates with webpack's file watching to trigger recompilation when virtual modules change
  4. Directory Creation: Automatically creates parent virtual directories for any virtual module path
  5. Version Compatibility: Supports webpack versions 3, 4, and 5 with internal version detection

Capabilities

Plugin Constructor

Creates a new VirtualModulesPlugin instance with optional static modules.

/**
 * Creates a webpack plugin for virtual modules
 * @param modules - Optional object mapping file paths to module contents
 */
constructor(modules?: Record<string, string>)

interface VirtualModulesPlugin {
  new (modules?: Record<string, string>): VirtualModulesPlugin;
}

Usage Example:

// Empty plugin for dynamic modules only
const virtualModules = new VirtualModulesPlugin();

// Plugin with static modules
const virtualModules = new VirtualModulesPlugin({
  'src/config.js': 'export const API_URL = "https://api.example.com";',
  'src/version.js': `export const VERSION = "${process.env.npm_package_version}";`
});

Plugin Apply Method

Webpack plugin interface method that attaches necessary hooks to the webpack compiler.

/**
 * Attaches the plugin to a webpack compiler
 * @param compiler - The webpack compiler instance
 */
apply(compiler: Compiler): void

Write Module

Writes or updates a virtual module dynamically during the build process.

/**
 * Writes or updates a virtual module
 * @param filePath - Path to virtual module (relative to webpack context)
 * @param contents - String content of the virtual module
 * @throws Error if plugin not initialized with webpack compiler
 */
writeModule(filePath: string, contents: string): void

Usage Examples:

// Write a simple module
virtualModules.writeModule('utils/constants.js', `
  module.exports = {
    BUILD_TIME: ${Date.now()},
    NODE_ENV: "${process.env.NODE_ENV}"
  };
`);

// Write a JSON module
virtualModules.writeModule('data/config.json', JSON.stringify({
  apiUrl: process.env.API_URL,
  features: ['feature1', 'feature2']
}));

// Update existing module
virtualModules.writeModule('cache/runtime-data.js', `
  module.exports = { cache: ${JSON.stringify(runtimeCache)} };
`);

Get Module List

Retrieves list of virtual modules based on optional filter criteria.

/**
 * Retrieves virtual modules based on filter criteria
 * @param filter - Filter type: 'all' | 'static' | 'dynamic' (defaults to 'all')
 * @returns Object mapping file paths to module contents
 */
getModuleList(filter?: 'all' | 'static' | 'dynamic'): Record<string, string>

Usage Examples:

// Get all virtual modules
const allModules = virtualModules.getModuleList();

// Get only static modules (defined at construction)
const staticModules = virtualModules.getModuleList('static');

// Get only dynamic modules (created via writeModule)
const dynamicModules = virtualModules.getModuleList('dynamic');

// Inspect module contents
Object.entries(allModules).forEach(([path, contents]) => {
  console.log(`Virtual module: ${path}`);
  console.log(`Content: ${contents.substring(0, 100)}...`);
});

Types

VirtualStats Class

Mock filesystem stats object for virtual files, used internally by the plugin.

/**
 * Creates virtual file stats object compatible with Node.js fs.Stats
 * @param config - Stats configuration object with filesystem properties
 */
class VirtualStats {
  constructor(config: VirtualStatsConfig);

  // Properties set from config
  dev: number;
  nlink: number;
  uid: number;
  gid: number;
  rdev: number;
  blksize: number;
  ino: number;
  mode: number;
  size: number;
  blocks: number;
  atime: Date;
  mtime: Date;
  ctime: Date;
  birthtime: Date;

  /** Check if represents a directory */
  isDirectory(): boolean;
  
  /** Check if represents a file */
  isFile(): boolean;
  
  /** Check if represents a block device */
  isBlockDevice(): boolean;
  
  /** Check if represents a character device */
  isCharacterDevice(): boolean;
  
  /** Check if represents a symbolic link */
  isSymbolicLink(): boolean;
  
  /** Check if represents a FIFO */
  isFIFO(): boolean;
  
  /** Check if represents a socket */
  isSocket(): boolean;
}

interface VirtualStatsConfig {
  dev: number;
  nlink: number;
  uid: number;
  gid: number;
  rdev: number;
  blksize: number;
  ino: number;
  mode: number;
  size: number;
  blocks: number;
  atime: Date;
  mtime: Date;
  ctime: Date;
  birthtime: Date;
}

Webpack Compiler Interface

The webpack Compiler type used by the apply method (from webpack types).

// Import from webpack for complete typing
import { Compiler, SyncHook, AsyncSeriesHook } from "webpack";

// Key properties used by VirtualModulesPlugin
interface Compiler {
  hooks: {
    afterEnvironment: SyncHook<[]>;
    afterResolvers: SyncHook<[]>;
    watchRun: AsyncSeriesHook<[Compiler]>;
  };
  inputFileSystem: any; // webpack's internal filesystem
  context: string; // webpack context/working directory
  fileTimestamps: Map<string, number | { safeTime: number; timestamp: number }>;
  name?: string; // optional compiler name
}

Error Handling

The plugin throws errors in the following scenarios:

  • Plugin Not Initialized: Calling writeModule() before the plugin has been applied to a webpack compiler
  • Webpack Version Incompatibility: If webpack version cannot be detected or is unsupported
  • Filesystem Access: If webpack's internal filesystem APIs are not available
// Proper error handling
try {
  virtualModules.writeModule('test.js', 'module.exports = { test: true };');
} catch (error) {
  if (error.message.includes('Plugin has not been initialized')) {
    console.error('Plugin must be applied to webpack compiler first');
  }
  throw error;
}

Watch Mode Integration

Virtual modules automatically integrate with webpack's watch mode. When a virtual module is updated via writeModule(), webpack will detect the change and trigger a recompilation, just as if a physical file had been modified.

// This will trigger webpack recompilation in watch mode
compiler.hooks.compilation.tap('UpdateVirtualModule', () => {
  virtualModules.writeModule('runtime-config.js', `
    module.exports = { timestamp: ${Date.now()} };
  `);
});