Hone logo
Hone
Problems

Simple Vue Dev Server with Hot Module Replacement (HMR)

Building a development server is a fundamental skill for any web developer. This challenge asks you to implement a basic development server for a Vue.js application, including hot module replacement (HMR) to provide a faster development experience. This will solidify your understanding of module bundling, file system watching, and basic server functionality.

Problem Description

You are tasked with creating a simple development server that serves a Vue.js application and supports HMR. The server should:

  1. Serve Static Files: Serve the files in a specified directory (e.g., dist or public) as static assets.
  2. Watch for Changes: Monitor the specified directory for file changes.
  3. Bundle and Rebuild: When a file changes, bundle the Vue.js application using a simple bundler (you can use a basic implementation or a lightweight library like esbuild or rollup for bundling – the focus is on the server logic, not the bundler itself).
  4. Hot Module Replacement (HMR): Implement HMR so that when a file changes, only the modified modules are updated in the browser, without a full page refresh. This requires establishing a WebSocket connection between the server and the browser.
  5. Basic Error Handling: Provide basic error handling for file watching and bundling.

Expected Behavior:

  • The server should start and listen on a specified port (e.g., 8080).
  • When the server starts, it should bundle the Vue.js application.
  • When a file in the watched directory changes, the server should:
    • Re-bundle the application.
    • Send an HMR update to the connected browser via WebSocket.
  • The browser should receive the HMR update and update the relevant modules without a full page refresh.
  • The server should log any errors encountered during file watching or bundling.

Examples

Example 1:

Input:  Directory to serve: 'src', Port: 8080, Vue entry point: 'src/main.ts'
Output: Server started on port 8080.  Files in 'src' are being watched.  HMR enabled.
Explanation: The server starts, serves files from 'src', watches for changes, and enables HMR.  The initial bundle is created.

Example 2:

Input: Directory to serve: 'public', Port: 9000, Vue entry point: 'public/app.ts'
Output: Server started on port 9000. Files in 'public' are being watched. HMR enabled.
Explanation: The server starts, serves files from 'public', watches for changes, and enables HMR. The initial bundle is created.

Example 3: (Edge Case - Invalid Directory)

Input: Directory to serve: 'nonexistent_dir', Port: 8080, Vue entry point: 'src/main.ts'
Output: Error: Directory 'nonexistent_dir' not found. Server exiting.
Explanation: The server detects that the specified directory does not exist and exits gracefully, logging an error.

Constraints

  • Bundler: You can use a simple bundler implementation or a lightweight library like esbuild or rollup. The focus is on the server logic, not the bundler's complexity. Assume the bundler returns a bundle object with a code property (the bundled JavaScript) and a map property (source map, optional).
  • HMR: The HMR implementation should be basic. Sending a simple message to the browser indicating a module has changed is sufficient. The browser-side HMR handling is not required for this challenge.
  • TypeScript: The solution must be written in TypeScript.
  • Node.js: The server should be implemented using Node.js.
  • Port: The server should listen on the specified port. Handle the case where the port is already in use.
  • File Types: The server should watch for changes to .ts, .vue, .js, and .json files.

Notes

  • Consider using Node.js built-in modules like fs, http, and path.
  • You'll need to establish a WebSocket connection for HMR. Libraries like ws can simplify this.
  • The bundling process should be asynchronous to avoid blocking the event loop.
  • Focus on the core server logic and HMR functionality. Detailed error handling and advanced features are not required.
  • Think about how to handle different file types and how to efficiently update modules in the browser during HMR.
  • The browser-side HMR implementation is not part of this challenge. You only need to send the HMR update message to the browser.
Loading editor...
typescript