Skip to content

feat: pure ESM package#23

Merged
chenjiahan merged 3 commits intomainfrom
pure_esm_0315
Mar 15, 2026
Merged

feat: pure ESM package#23
chenjiahan merged 3 commits intomainfrom
pure_esm_0315

Conversation

@chenjiahan
Copy link
Member

  • Convert to pure ESM package

Copilot AI review requested due to automatic review settings March 15, 2026 11:01
@gemini-code-assist
Copy link

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request modernizes the project by transitioning its entire codebase to use ECMAScript Modules (ESM). This foundational change impacts how modules are defined, imported, and exported, and is reflected across the package configuration, build scripts, source code, and test infrastructure. The update aims to align the project with contemporary JavaScript standards and improve maintainability.

Highlights

  • Pure ESM Conversion: The project has been fully converted to a pure ECMAScript Module (ESM) package, updating all JavaScript files to use import/export syntax instead of require/module.exports.
  • Build System Update: The build process was migrated from Babel to rslib, leading to significant changes in package.json and pnpm-lock.yaml with the removal of Babel-related dependencies and the introduction of @rslib/core.
  • Dependency Refactoring: Numerous dependencies were removed from pnpm-lock.yaml as part of the ESM transition and build system overhaul, streamlining the project's dependency tree.
  • Test Infrastructure Adjustments: Test configurations and helpers were updated to support ESM, including changes to fixture loading, asynchronous test handling, and dynamic port assignment for server tests.
  • Type Definition Modernization: All TypeScript type definitions (.d.ts files) were updated to align with the ESM export syntax, replacing export = with export default and using export type for better module compatibility.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Changelog
  • package.json
    • Added "type": "module" to declare the package as ESM.
    • Updated the build script to use rslib --syntax es2023 and pnpm run build:types, replacing the Babel-based build.
    • Removed @babel/cli, @babel/core, and @babel/preset-env from devDependencies.
    • Added @rslib/core to devDependencies.
  • pnpm-lock.yaml
    • Removed numerous Babel-related dependencies and their snapshots.
    • Added @rslib/core and @ast-grep/napi related dependencies and their snapshots.
    • Removed several other unused dependencies like anymatch, binary-extensions, chokidar, commander (older version), convert-source-map, core-js-compat, esutils, fs-readdir-recursive, fs.realpath, fsevents, gensync, glob, inflight, is-binary-path, js-tokens, jsesc, lodash.debounce, lru-cache, make-dir, normalize-path, path-is-absolute, pify (older version), readdirp, regenerate-unicode-properties, regenerate, regexpu-core, regjsgen, regjsparser, semver (older version), slash (older version), unicode-canonical-property-names-ecmascript, unicode-match-property-ecmascript, unicode-match-property-value-ecmascript, unicode-property-aliases-ecmascript, yallist.
    • Added rsbuild-plugin-dts and its dependencies.
  • rstest.config.mjs
    • Added a retry: 2 option to the test configuration.
  • src/index.js
    • Converted require statements to import statements.
    • Changed module.exports = wdm; to export default wdm;.
  • src/middleware.js
    • Converted require statements to import statements.
    • Imported range-parser directly and used it instead of require("range-parser") inside parseRangeHeaders.
    • Updated getETag, getEscapeHtml, and getParseTokenList to reference imported modules directly instead of require().
    • Changed module.exports = wrapper; to export default wrapper;.
  • src/utils/compatibleAPI.js
    • Changed module.exports = { ... } to export { ... };.
  • src/utils/escapeHtml.js
    • Changed module.exports = escapeHtml; to export default escapeHtml;.
  • src/utils/etag.js
    • Converted require statements to import statements.
    • Changed module.exports = etag; to export default etag;.
  • src/utils/getFilenameFromUrl.js
    • Converted require statements to import statements.
    • Changed module.exports = getFilenameFromUrl; to export default getFilenameFromUrl;.
  • src/utils/getPaths.js
    • Changed module.exports = getPaths; to export default getPaths;.
  • src/utils/memorize.js
    • Changed module.exports = memorize; to export default memorize;.
  • src/utils/parseTokenList.js
    • Changed module.exports = parseTokenList; to export default parseTokenList;.
  • src/utils/ready.js
    • Changed module.exports = ready; to export default ready;.
  • src/utils/setupHooks.js
    • Changed module.exports = setupHooks; to export default setupHooks;.
  • src/utils/setupOutputFileSystem.js
    • Converted require statements to import statements, specifically for memfs.
    • Modified the logic for creating outputFileSystem to ensure readFileSync and statSync functions are present, falling back to a new Volume instance if not.
    • Changed module.exports = setupOutputFileSystem; to export default setupOutputFileSystem;.
  • src/utils/setupWriteToDisk.js
    • Converted require statements to import statements.
    • Changed module.exports = setupWriteToDisk; to export default setupWriteToDisk;.
  • test/fixtures/foo.js
    • Replaced 'use strict'; and require() with import statements.
  • test/fixtures/webpack.array.config.js
    • Replaced 'use strict'; and require() with import statements and module.exports with export default.
    • Added const __dirname = import.meta.dirname; for path resolution.
  • test/fixtures/webpack.array.dev-server-false.js
    • Replaced 'use strict'; and require() with import statements and module.exports with export default.
    • Added const __dirname = import.meta.dirname; for path resolution.
  • test/fixtures/webpack.array.error.config.js
    • Replaced 'use strict'; and require() with import statements and module.exports with export default.
    • Added const __dirname = import.meta.dirname; for path resolution.
  • test/fixtures/webpack.array.one-error-one-warning-one-no.js
    • Replaced 'use strict'; and require() with import statements and module.exports with export default.
    • Added const __dirname = import.meta.dirname; for path resolution.
  • test/fixtures/webpack.array.one-error-one-warning-one-object.js
    • Replaced 'use strict'; and require() with import statements and module.exports with export default.
    • Added const __dirname = import.meta.dirname; for path resolution.
  • test/fixtures/webpack.array.one-error-one-warning-one-success-with-names.js
    • Replaced 'use strict'; and require() with import statements and module.exports with export default.
    • Added const __dirname = import.meta.dirname; for path resolution.
  • test/fixtures/webpack.array.one-error-one-warning-one-success.js
    • Replaced 'use strict'; and require() with import statements and module.exports with export default.
    • Added const __dirname = import.meta.dirname; for path resolution.
  • test/fixtures/webpack.array.warning.config.js
    • Replaced 'use strict'; and require() with import statements and module.exports with export default.
    • Added const __dirname = import.meta.dirname; for path resolution.
  • test/fixtures/webpack.array.watch-options.config.js
    • Replaced 'use strict'; and require() with import statements and module.exports with export default.
    • Added const __dirname = import.meta.dirname; for path resolution.
  • test/fixtures/webpack.client.server.config.js
    • Replaced 'use strict'; and require() with import statements and module.exports with export default.
    • Added const __dirname = import.meta.dirname; for path resolution.
  • test/fixtures/webpack.config.js
    • Replaced 'use strict'; and require() with import statements and module.exports with export default.
    • Added const __dirname = import.meta.dirname; for path resolution.
  • test/fixtures/webpack.error.config.js
    • Replaced 'use strict'; and require() with import statements and module.exports with export default.
    • Added const __dirname = import.meta.dirname; for path resolution.
  • test/fixtures/webpack.immutable.config.js
    • Replaced 'use strict'; and require() with import statements and module.exports with export default.
    • Added const __dirname = import.meta.dirname; for path resolution.
  • test/fixtures/webpack.no-stats.config.js
    • Replaced 'use strict'; and require() with import statements and module.exports with export default.
    • Added const __dirname = import.meta.dirname; for path resolution.
  • test/fixtures/webpack.public-path.config.js
    • Replaced 'use strict'; and require() with import statements and module.exports with export default.
    • Added const __dirname = import.meta.dirname; for path resolution.
  • test/fixtures/webpack.querystring.config.js
    • Replaced 'use strict'; and require() with import statements and module.exports with export default.
    • Added const __dirname = import.meta.dirname; for path resolution.
  • test/fixtures/webpack.simple.config.js
    • Replaced 'use strict'; and require() with import statements and module.exports with export default.
    • Added const __dirname = import.meta.dirname; for path resolution.
  • test/fixtures/webpack.stats-colors-false.config.js
    • Replaced 'use strict'; and require() with import statements and module.exports with export default.
    • Added const __dirname = import.meta.dirname; for path resolution.
  • test/fixtures/webpack.stats-colors-true.config.js
    • Replaced 'use strict'; and require() with import statements and module.exports with export default.
    • Added const __dirname = import.meta.dirname; for path resolution.
  • test/fixtures/webpack.stats-false.config.js
    • Replaced 'use strict'; and require() with import statements and module.exports with export default.
    • Added const __dirname = import.meta.dirname; for path resolution.
  • test/fixtures/webpack.stats-minimal.config.js
    • Replaced 'use strict'; and require() with import statements and module.exports with export default.
    • Added const __dirname = import.meta.dirname; for path resolution.
  • test/fixtures/webpack.stats-none.config.js
    • Replaced 'use strict'; and require() with import statements and module.exports with export default.
    • Added const __dirname = import.meta.dirname; for path resolution.
  • test/fixtures/webpack.stats-object.config.js
    • Replaced 'use strict'; and require() with import statements and module.exports with export default.
    • Added const __dirname = import.meta.dirname; for path resolution.
  • test/fixtures/webpack.stats-true.config.js
    • Replaced 'use strict'; and require() with import statements and module.exports with export default.
    • Added const __dirname = import.meta.dirname; for path resolution.
  • test/fixtures/webpack.stats-verbose.config.js
    • Replaced 'use strict'; and require() with import statements and module.exports with export default.
    • Added const __dirname = import.meta.dirname; for path resolution.
  • test/fixtures/webpack.warning.config.js
    • Replaced 'use strict'; and require() with import statements and module.exports with export default.
    • Added const __dirname = import.meta.dirname; for path resolution.
  • test/fixtures/webpack.watch-options.config.js
    • Replaced 'use strict'; and require() with import statements and module.exports with export default.
    • Added const __dirname = import.meta.dirname; for path resolution.
  • test/helpers/getCompiler.js
    • Updated import path for webpack.config to include .js extension.
    • Converted require to import.
  • test/helpers/runner.js
    • Converted require to import for merge, express, rspack, middleware, and defaultConfig.
    • Modified getWebpackConfig to use dynamic import() and import.meta.url for fixture loading, making it asynchronous.
    • Adjusted unionConfig assignment to await getWebpackConfig.
  • test/middleware.test.js
    • Updated imports to include .js extensions.
    • Added createServer from node:http and fastifyExpress from @fastify/express.
    • Added Stats from @rspack/core.
    • Added __dirname using import.meta.dirname.
    • Added afterAll hook to restore consoleLogSpy.
    • Changed server listening port from 3000 to 0 for dynamic port assignment in startServer.
    • Updated app.register for Fastify to use the imported fastifyExpress.
  • test/utils/snapshots/setupWriteToDisk.test.js.snap
    • Removed snapshots related to "no write errors" due to test refactoring.
  • test/utils/escapeHtml.test.js
    • Updated import path to include .js extension.
  • test/utils/ready.test.js
    • Updated import path to include .js extension.
  • test/utils/setupHooks.test.js
    • Updated import path to include .js extension.
    • Replaced process.nextTick spy with consoleLogSpy and setImmediate for async test handling.
  • test/utils/setupOutputFileSystem.test.js
    • Updated import path to include .js extension.
    • Modified assertions to check for readFileSync and statSync functions on the outputFileSystem object, reflecting the new memfs creation logic.
  • test/utils/setupWriteToDisk.test.js
    • Updated import path to include .js extension.
    • Imported os and path.
    • Refactored tests to use fs.promises.mkdtemp and fs.promises.rm for temporary directory management, removing direct spies on fs.mkdir and fs.writeFile for a specific test case.
  • types/index.d.ts
    • Changed export = wdm; to export default wdm;.
    • Added export type for various types to ensure proper ESM type visibility.
    • Removed declare namespace wdm block.
  • types/middleware.d.ts
    • Changed export = wrapper; to export default wrapper;.
    • Added export type for various types.
    • Removed declare namespace wrapper block.
  • types/utils/escapeHtml.d.ts
    • Changed export = escapeHtml; to export default escapeHtml;.
  • types/utils/etag.d.ts
    • Changed export = etag; to export default etag;.
    • Added export type for Stats and ReadStream.
    • Removed declare namespace etag block.
  • types/utils/getFilenameFromUrl.d.ts
    • Changed export = getFilenameFromUrl; to export default getFilenameFromUrl;.
    • Added export type for IncomingMessage, ServerResponse, and Extra.
    • Removed declare namespace getFilenameFromUrl block.
  • types/utils/getPaths.d.ts
    • Changed export = getPaths; to export default getPaths;.
    • Added export type for various types.
    • Removed declare namespace getPaths block.
  • types/utils/memorize.d.ts
    • Changed export = memorize; to export default memorize;.
    • Added export type for FunctionReturning and EXPECTED_ANY.
    • Removed declare namespace memorize block.
  • types/utils/parseTokenList.d.ts
    • Changed export = parseTokenList; to export default parseTokenList;.
  • types/utils/ready.d.ts
    • Changed export = ready; to export default ready;.
    • Added export type for IncomingMessage, ServerResponse, and Callback.
    • Removed declare namespace ready block.
  • types/utils/setupHooks.d.ts
    • Changed export = setupHooks; to export default setupHooks;.
    • Added export type for various types.
    • Removed declare namespace setupHooks block.
  • types/utils/setupOutputFileSystem.d.ts
    • Changed export = setupOutputFileSystem; to export default setupOutputFileSystem;.
    • Added export type for various types.
    • Removed declare namespace setupOutputFileSystem block.
  • types/utils/setupWriteToDisk.d.ts
    • Changed export = setupWriteToDisk; to export default setupWriteToDisk;.
    • Added export type for various types.
    • Removed declare namespace setupWriteToDisk block.
Activity
  • The pull request was authored by chenjiahan.
  • The core activity involved a comprehensive refactoring to convert the entire project to use ECMAScript Modules (ESM).
  • This transition necessitated updates to module import/export syntax across all JavaScript source files and corresponding type definitions.
  • The build system was modernized by replacing Babel with rslib, impacting dependency management and build scripts.
  • Test configurations and helper utilities were adjusted to ensure compatibility and reliability within the new ESM environment.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request successfully converts the package to a pure ESM module. The changes are comprehensive, covering everything from package.json configuration and dependency updates to refactoring the source code to use ES modules syntax. The test suite and configuration files have also been updated accordingly. I have one suggestion regarding some redundant JSDoc comments in the generated type definition files that could be cleaned up for better maintainability.

@chenjiahan chenjiahan merged commit 82aad4f into main Mar 15, 2026
5 checks passed
@chenjiahan chenjiahan deleted the pure_esm_0315 branch March 15, 2026 11:07
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR migrates @rspack/dev-middleware from CommonJS to ESM, updates the published TypeScript declaration files accordingly, and adjusts tests/fixtures/build tooling to run in an ESM package context.

Changes:

  • Convert src/** modules (middleware + utils) from require/module.exports to ESM import/export.
  • Update types/** declarations from export = patterns to export default + explicit exported types.
  • Migrate tests/fixtures/helpers to ESM and update build/test configuration (switch build to rslib, add rstest retries).

Reviewed changes

Copilot reviewed 52 out of 65 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
types/utils/setupWriteToDisk.d.ts Switch to export default + explicit exported type aliases.
types/utils/setupOutputFileSystem.d.ts Switch to export default + explicit exported type aliases.
types/utils/setupHooks.d.ts Switch to export default + explicit exported type aliases.
types/utils/ready.d.ts Switch to export default + explicit exported type aliases.
types/utils/parseTokenList.d.ts Switch to export default export style.
types/utils/memorize.d.ts Switch to export default and export helper types.
types/utils/getPaths.d.ts Switch to export default + explicit exported type aliases.
types/utils/getFilenameFromUrl.d.ts Switch to export default + export Extra type.
types/utils/etag.d.ts Switch to export default + explicit exported type aliases.
types/utils/escapeHtml.d.ts Switch to export default export style.
types/middleware.d.ts Switch to export default and export SendErrorOptions and related types.
types/index.d.ts Rework primary public typings to ESM default export + exported types and wrapper namespace exports.
test/utils/setupWriteToDisk.test.js Update imports to ESM and refine write-to-disk tests (incl. real FS test).
test/utils/setupOutputFileSystem.test.js Update imports to ESM and simplify assertions around default fs behavior.
test/utils/setupHooks.test.js Update imports to ESM and adjust async scheduling assertions.
test/utils/ready.test.js Update import path to ESM (.js).
test/utils/escapeHtml.test.js Update import path to ESM (.js).
test/utils/snapshots/setupWriteToDisk.test.js.snap Update snapshots after test behavior changes.
test/middleware.test.js Convert to ESM imports, avoid fixed ports, and update framework wiring.
test/helpers/runner.js Convert CLI helper to ESM and dynamic import() for fixtures.
test/helpers/getCompiler.js Convert helper to ESM and update fixture import path.
test/fixtures/webpack.watch-options.config.js Convert fixture config to ESM export default.
test/fixtures/webpack.warning.config.js Convert fixture config to ESM export default.
test/fixtures/webpack.stats-verbose.config.js Convert fixture config to ESM export default.
test/fixtures/webpack.stats-true.config.js Convert fixture config to ESM export default.
test/fixtures/webpack.stats-object.config.js Convert fixture config to ESM export default.
test/fixtures/webpack.stats-none.config.js Convert fixture config to ESM export default.
test/fixtures/webpack.stats-minimal.config.js Convert fixture config to ESM export default.
test/fixtures/webpack.stats-false.config.js Convert fixture config to ESM export default.
test/fixtures/webpack.stats-colors-true.config.js Convert fixture config to ESM export default.
test/fixtures/webpack.stats-colors-false.config.js Convert fixture config to ESM export default.
test/fixtures/webpack.simple.config.js Convert fixture config to ESM export default.
test/fixtures/webpack.querystring.config.js Convert fixture config to ESM export default.
test/fixtures/webpack.public-path.config.js Convert fixture config to ESM export default.
test/fixtures/webpack.no-stats.config.js Convert fixture config to ESM export default.
test/fixtures/webpack.immutable.config.js Convert fixture config to ESM export default.
test/fixtures/webpack.error.config.js Convert fixture config to ESM export default.
test/fixtures/webpack.config.js Convert fixture config to ESM export default.
test/fixtures/webpack.client.server.config.js Convert fixture config array to ESM export default.
test/fixtures/webpack.array.watch-options.config.js Convert fixture config array to ESM export default.
test/fixtures/webpack.array.warning.config.js Convert fixture config array to ESM export default.
test/fixtures/webpack.array.one-error-one-warning-one-success.js Convert fixture config array to ESM export default.
test/fixtures/webpack.array.one-error-one-warning-one-success-with-names.js Convert fixture config array to ESM export default.
test/fixtures/webpack.array.one-error-one-warning-one-object.js Convert fixture config array to ESM export default.
test/fixtures/webpack.array.one-error-one-warning-one-no.js Convert fixture config array to ESM export default.
test/fixtures/webpack.array.error.config.js Convert fixture config array to ESM export default.
test/fixtures/webpack.array.dev-server-false.js Convert fixture config array to ESM export default.
test/fixtures/webpack.array.config.js Convert fixture config array to ESM export default.
test/fixtures/foo.js Convert fixture entry to ESM import statements.
src/utils/setupWriteToDisk.js Convert util to ESM imports and export default.
src/utils/setupOutputFileSystem.js Convert util to ESM imports and adjust memfs filesystem creation logic.
src/utils/setupHooks.js Convert util export to export default.
src/utils/ready.js Convert util export to export default.
src/utils/parseTokenList.js Convert util export to export default.
src/utils/memorize.js Convert util export to export default.
src/utils/getPaths.js Convert util export to export default.
src/utils/getFilenameFromUrl.js Convert util to ESM imports and export default.
src/utils/etag.js Convert util to ESM imports and export default.
src/utils/escapeHtml.js Convert util export to export default.
src/utils/compatibleAPI.js Convert to named ESM exports.
src/middleware.js Convert middleware to ESM imports/exports and refactor to static imports for some helpers.
src/index.js Convert package entry to ESM imports and export default.
rstest.config.mjs Add test retries.
pnpm-lock.yaml Update lockfile for dependency/tooling changes (remove Babel deps, add rslib).
package.json Mark package as ESM (type: module) and switch build to rslib.
Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

{
"name": "@rspack/dev-middleware",
"version": "7.4.5",
"type": "module",
Comment on lines +37 to +41
const consoleLogSpy = rs.spyOn(globalThis.console, "log").mockImplementation();

const __dirname = import.meta.dirname;

afterAll(() => {
Comment on lines +1 to 7
import path from "node:path";

const path = require('path');
const __dirname = import.meta.dirname;

module.exports = {
export default {
mode: 'development',
context: path.resolve(__dirname),
Comment on lines +1 to 3
import memfs, { Volume, createFsFromVolume } from "memfs";

/** @typedef {import("@rspack/core").MultiCompiler} MultiCompiler */
testEnvironment: "node",
globals: true,
testTimeout: 20000,
retry: 2,
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants