Skip to content

Improve types#555

Merged
alexeyr-ci2 merged 2 commits intomainfrom
alexeyr/improve-types
Mar 20, 2025
Merged

Improve types#555
alexeyr-ci2 merged 2 commits intomainfrom
alexeyr/improve-types

Conversation

@alexeyr-ci2
Copy link
Copy Markdown
Contributor

@alexeyr-ci2 alexeyr-ci2 commented Mar 12, 2025

Summary

More precise types in package/index.d.ts

Pull Request checklist

  • [ ] Add/update test to cover these changes
  • [ ] Update documentation
  • Update CHANGELOG file

Summary by CodeRabbit

  • New Features

    • Enhanced the development server configuration for improved flexibility and precision.
    • Library version resolution now dynamically utilizes the installed version for optimal compatibility.
  • Refactor

    • Refined configuration schemas to ensure more reliable and predictable behavior.
  • Documentation

    • Updated release notes with clearly separated sections for changes and fixes, streamlining review.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 12, 2025

Walkthrough

The pull request introduces new types and modifies existing exported entities in the shakapacker module. It includes an import for RuleSetRule from webpack and the https module from Node. A new Header type is defined, along with ServerType and WebSocketType. The DevServerConfig interface is added to provide a detailed configuration structure for the development server. The types for devServer and rules exports are updated for more specificity. The changelog is updated with new sections for changes and fixes.

Changes

File(s) Change Summary
package/index.d.ts - Added new types: Header, ServerType, WebSocketType
- Introduced the DevServerConfig interface with detailed configuration properties
- Updated exports: devServer now uses DevServerConfig, rules now uses RuleSetRule[]
- Added imports from webpack and Node's https
CHANGELOG.md - Added new section Changed: core-js version is dynamically taken from node_modules
- Added new section Fixed: Improved type precision for devServer and rules configuration

Suggested reviewers

  • G-Rath
  • tomdracz

Poem

In my code burrow, hopping with glee,
New types and rules set our config free.
With imports and docs all neatly aligned,
I nibble on changes, so wisely designed.
A rabbit’s cheer for code so bright—
May our pull requests always delight!
🐇✨

Tip

⚡🧪 Multi-step agentic review comment chat (experimental)
  • We're introducing multi-step agentic chat in review comments. This experimental feature enhances review discussions with the CodeRabbit agentic chat by enabling advanced interactions, including the ability to create pull requests directly from comments.
    - To enable this feature, set early_access to true under in the settings.

📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 46bafcc and e2cc49b.

📒 Files selected for processing (1)
  • package/index.d.ts (2 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (20)
  • GitHub Check: Generator specs (ubuntu-latest, 3.3, gemfiles/Gemfile-rails.7.1.x)
  • GitHub Check: Generator specs (ubuntu-latest, 3.3, gemfiles/Gemfile-rails.7.2.x)
  • GitHub Check: Generator specs (ubuntu-latest, 3.4, gemfiles/Gemfile-rails.8.0.x)
  • GitHub Check: Generator specs (ubuntu-latest, 3.3, gemfiles/Gemfile-rails.8.0.x)
  • GitHub Check: Generator specs (ubuntu-latest, 3.3, gemfiles/Gemfile-rails.7.0.x)
  • GitHub Check: Generator specs (ubuntu-latest, 3.4, gemfiles/Gemfile-rails.7.1.x)
  • GitHub Check: Generator specs (ubuntu-latest, 3.2, gemfiles/Gemfile-rails.7.2.x)
  • GitHub Check: Generator specs (ubuntu-latest, 3.2, gemfiles/Gemfile-rails.7.0.x)
  • GitHub Check: Generator specs (ubuntu-latest, 3.2, gemfiles/Gemfile-rails.8.0.x)
  • GitHub Check: Generator specs (ubuntu-latest, 3.1, gemfiles/Gemfile-rails.7.2.x)
  • GitHub Check: Generator specs (ubuntu-latest, 3.2, gemfiles/Gemfile-rails.7.1.x)
  • GitHub Check: Generator specs (ubuntu-latest, 3.0, gemfiles/Gemfile-rails.7.1.x)
  • GitHub Check: Generator specs (ubuntu-latest, 3.1, gemfiles/Gemfile-rails.7.0.x)
  • GitHub Check: Generator specs (ubuntu-latest, 3.0, gemfiles/Gemfile-rails.7.0.x)
  • GitHub Check: Generator specs (ubuntu-latest, 3.0, gemfiles/Gemfile-rails.6.0.x)
  • GitHub Check: Generator specs (ubuntu-latest, 2.7, gemfiles/Gemfile-rails.7.0.x)
  • GitHub Check: Generator specs (ubuntu-latest, 2.7, gemfiles/Gemfile-rails.7.1.x)
  • GitHub Check: Generator specs (ubuntu-latest, 2.7, gemfiles/Gemfile-rails.6.1.x)
  • GitHub Check: Generator specs (ubuntu-latest, 2.7, gemfiles/Gemfile-rails.6.0.x)
  • GitHub Check: Generator specs (ubuntu-latest, 3.0, gemfiles/Gemfile-rails.6.1.x)
🔇 Additional comments (5)
package/index.d.ts (5)

2-3: Appropriate imports for enhanced type definitions.

The imports for RuleSetRule from webpack and the https module from Node.js are necessary for the new type definitions that follow. They provide proper typing for the webpack rules and HTTPS server options.


36-38: Well-structured type definitions.

These type definitions are clear and appropriate:

  • Header properly represents HTTP headers as either an array of key-value pairs or as a record
  • ServerType and WebSocketType correctly define the allowed string literals

These types are reused in the DevServerConfig interface, promoting better type safety and code organization.


73-73: Improved type specificity for devServer export.

Changing the type from Record<string, unknown> to DevServerConfig significantly improves type safety by providing specific types for all the supported configuration options.


77-77: Correct type for rules export.

Updating the type from Record<string, unknown> to RuleSetRule[] properly reflects that rules is an array of webpack rule configurations. This addresses the issue mentioned in previous review comments and provides better type checking.


40-70:

Details

❓ Verification inconclusive

Comprehensive DevServerConfig interface with clear documentation.

The interface provides detailed type definitions for webpack-dev-server configuration options, with appropriate documentation explaining the snake_case naming convention. The types are accurate and will provide good IDE autocompletion and type checking.

However, there's a potential issue related to the open property that was mentioned in the PR comments. TypeScript errors were reported when importing types from ECMAScript modules in CommonJS context.

Consider whether the open property might need special handling or documentation to address the TypeScript module resolution issues mentioned in the PR comments. You might want to search for more information about:


🌐 Web query:

TypeScript error TS1542 import resolution-mode with webpack-dev-server types

💡 Result:

To resolve TypeScript error TS1542 when using webpack-dev-server types in a Webpack configuration, follow these key solutions:

1. Explicit Type Import for devServer

Ensure proper type recognition by:

// webpack.config.ts
import 'webpack-dev-server'; // Add this line

import { Configuration } from 'webpack';

const config: Configuration = {
  devServer: { // Now recognized by TypeScript
    static: './dist',
    port: 3000
  }
};

2. Module Resolution Configuration

Handle CommonJS requirement for TypeScript config files via tsconfig.json adjustments:

Option 1 - Global override:

{
  "compilerOptions": {
    "module": "CommonJS",
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true
  }
}

Option 2 - ts-node specific settings:

{
  "ts-node": {
    "compilerOptions": {
      "module": "CommonJS"
    }
  },
  "compilerOptions": {
    "module": "ESNext" // For main application
  }
}

3. TypeScript Version Compatibility

Verify compatible versions in package.json:

{
  "devDependencies": {
    "typescript": "^5.0.0",
    "webpack-dev-server": "^4.15.1",
    "@types/webpack-dev-server": "^4.7.1"
  }
}

4. Webpack Configuration Validation

Ensure proper type assertion when needed:

import { Configuration } from 'webpack';
import { DevServer } from 'webpack-dev-server';

const config: Configuration & { devServer?: DevServer } = {
  // Configuration
};

These solutions address the core issues causing TS1542 by:

  1. Making devServer types available through explicit imports[1][9]
  2. Resolving module system conflicts in TypeScript configuration[1][6]
  3. Ensuring version compatibility between TypeScript and webpack-dev-server types[1][6]

For projects using both ESM and TypeScript configs, consider creating a dedicated tsconfig-for-webpack.json with CommonJS settings and reference it in build scripts[1][6].

Citations:


Action Required: Verify TS1542 Setup for the open Property

The overall DevServerConfig interface is comprehensive and well-documented, offering clear typings that enhance IDE support. However, note that users have reported TypeScript error TS1542—which occurs when importing ECMAScript module types in a CommonJS context—in relation to the open property.

Recommendations:

  • Ensure that your webpack configuration explicitly imports webpack-dev-server (e.g., add import 'webpack-dev-server'; in your config file) so that TypeScript properly recognizes the devServer types.
  • Verify your project’s TypeScript configuration in tsconfig.json (or a dedicated tsconfig for webpack) includes settings such as "esModuleInterop": true and "allowSyntheticDefaultImports": true, or consider setting "module": "CommonJS" for configuration files.
  • Confirm that dependency versions for TypeScript, webpack-dev-server, and its types (e.g., @types/webpack-dev-server) are compatible, following the guidance provided in online resources.
  • If users continue to experience TS1542 errors, update the documentation to highlight these configuration steps, particularly in relation to the open property usage.

No changes are required in the current type definitions, but please review and verify that your build and configuration setups address the TS1542 issue.

✨ Finishing Touches
  • 📝 Generate Docstrings

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Comment thread package/index.d.ts Outdated
Comment on lines +40 to +55
export const rules: Record<string, unknown>
export const rules: Configuration['module']['rules']
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This type was wrong, it's an array.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Good catch, not sure why I typed this as a Record - however, these types are wrong:

  1. Configuration['module'] is optional, so you need to wrap with Required<Configuration>
  2. The types for webpack tend to be very loose, allowing a lot of different "conditional" values like empty strings and false, but we know specifically what our values are so it would be better to use RuleSetRule[]

For reference, this is the type of Required<Configuration>['module']:

interface ModuleOptions {
  // ...
  rules?: (undefined | null | false | "" | 0 | RuleSetRule | "...")[];
  // ...
}

Copy link
Copy Markdown
Contributor Author

@alexeyr-ci2 alexeyr-ci2 Mar 14, 2025

Choose a reason for hiding this comment

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

but we know specifically what our values are so it would be better to use RuleSetRule[]

I missed that it was exported, fixed.

Comment thread package/index.d.ts Outdated
[K in keyof T as CamelToSnakeCase<string & K>]: T[K];
}

type DevServerConfig = SnakeCase<Omit<WebpackDevServerConfiguration, 'hot'>> & {
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Translates e.g. allowedHosts to allowed_hosts.

Comment thread package.json
"@babel/preset-env": "^7.16.11",
"@babel/runtime": "^7.17.9",
"@types/babel__core": "^7.0.0",
"@types/webpack": "^5.0.0",
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Types are now included in Webpack itself.

@alexeyr-ci2 alexeyr-ci2 force-pushed the alexeyr/improve-types branch from f2e9fe8 to d67155c Compare March 12, 2025 10:25
Comment thread package.json Outdated
Comment on lines +30 to +31
"@types/webpack-dev-middleware": "5.0.2",
"@types/webpack-dev-server": "4.5.1",
Copy link
Copy Markdown
Contributor Author

@alexeyr-ci2 alexeyr-ci2 Mar 12, 2025

Choose a reason for hiding this comment

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

These are older versions, but ones which don't pull the main packages. And since they are devDependencies, the clients aren't bound to them in any way.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Why are these here at all, given we've already got both of these libs in the tree and they're shipping with their own types? if we're expecting to be compatible with these versions, then we should specify them as optional peer dependencies, otherwise we shouldn't need to include these dependencies (and optionally include both packages as dev dependencies, which shouldn't be an issue as they're already in the tree - though since we're not authoring in TypeScript or doing any type checking ourselves in CI, I don't think it'd be a big deal if we omitted webpack-dev-middleware)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

given we've already got both of these libs in the tree

I only added @types/webpack-dev-server because we didn't:

02:35:03 ~/shaka/shakapacker (alexeyr/improve-types)$ yarn why webpack-dev-server
yarn why v1.22.22
[1/4] Why do we have the module "webpack-dev-server"...?
[2/4] Initialising dependency graph...
[3/4] Finding dependency...
error We couldn't find a match!
Done in 0.18s.
02:35:12 ~/shaka/shakapacker (alexeyr/improve-types)$ yarn why webpack-dev-middleware
yarn why v1.22.22
[1/4] Why do we have the module "webpack-dev-middleware"...?
[2/4] Initialising dependency graph...
[3/4] Finding dependency...
error We couldn't find a match!
Done in 0.16s.

and @types/webpack-dev-middleware version is specified because otherwise @types/webpack-dev-server pulls in a later version which is really the whole webpack-dev-middleware.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Ah right ok well that's a mistake - we should have webpack-dev-server v4.9 as a dev dependency

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I can add it instead of @types/webpack-dev-server then. Would it only be used for the types, though, or do you have something else in mind?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Technically we should be using it since it's specified as a peer dependency and we should be satisfying our own constraints, though in reality it's not needed because our test suite is based around generating dummy projects which include adding this dependency.

Frankly, we could just continue on omitting it for now since we're not doing anything with these types in CI either - I'm fine with either, but my point is based on that regardless of if you're using it for types or runtime stuff, as its listed as a peer dependency it's fair to assume webpack-dev-server is available and that includes for ourselves so if you need it add it

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Since we've decided to duplicate the types anyway, it's moot and we don't need to change package.json at all (except for maybe removing @types/webpack from peer dependencies).

Copy link
Copy Markdown
Contributor Author

@alexeyr-ci2 alexeyr-ci2 Mar 16, 2025

Choose a reason for hiding this comment

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

Done in e2cc49b.

@alexeyr-ci2 alexeyr-ci2 force-pushed the alexeyr/improve-types branch 2 times, most recently from ff08f18 to 6a4c4f0 Compare March 12, 2025 19:39
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
CHANGELOG.md (1)

17-20: Document New "Fixed" Section for Improved Type Definitions

The new "### Fixed" section entry documenting the enhanced type precision for devServer and rules (PR 555) is clear and aligns well with the PR's objectives.

Note: According to markdownlint (MD004), it is recommended to use asterisks (*) instead of dashes (-) for unordered list items. Consider updating the bullet style in this section for consistency.

🧰 Tools
🪛 markdownlint-cli2 (0.17.2)

19-19: Unordered list style
Expected: asterisk; Actual: dash

(MD004, ul-style)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d67155c and 6a4c4f0.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (3)
  • CHANGELOG.md (1 hunks)
  • package.json (1 hunks)
  • package/index.d.ts (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • package.json
  • package/index.d.ts
🧰 Additional context used
🪛 markdownlint-cli2 (0.17.2)
CHANGELOG.md

15-15: Unordered list style
Expected: asterisk; Actual: dash

(MD004, ul-style)


19-19: Unordered list style
Expected: asterisk; Actual: dash

(MD004, ul-style)

@alexeyr-ci2 alexeyr-ci2 force-pushed the alexeyr/improve-types branch from 6a4c4f0 to fc5209f Compare March 14, 2025 07:35
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (3)
CHANGELOG.md (3)

9-10: Clarify the New 'Versions' Section

A new "# Versions" header has been introduced to separate version-related notes. Verify that this addition aligns with the overall changelog structure and naming conventions used in previous releases.


13-16: Document 'Changed' Updates with Core-js Version Improvement

The "### Changed" section effectively records the update regarding using the current core-js version from node_modules. However, the bullet item on line 15 uses a dash (-) while markdownlint recommends using an asterisk (*). For consistency with MD004, please consider updating the bullet style.

🧰 Tools
🪛 markdownlint-cli2 (0.17.2)

15-15: Unordered list style
Expected: asterisk; Actual: dash

(MD004, ul-style)


17-20: Document 'Fixed' Updates for Type Precision

The "### Fixed" section notes the enhancement for more precise types for devServer and rules in the configuration. Similar to the "Changed" bullet, the list item on line 19 uses a dash (-). To comply with the markdownlint guideline (MD004), please consider revising the bullet indicator to an asterisk (*).

🧰 Tools
🪛 markdownlint-cli2 (0.17.2)

19-19: Unordered list style
Expected: asterisk; Actual: dash

(MD004, ul-style)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6a4c4f0 and fc5209f.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (3)
  • CHANGELOG.md (1 hunks)
  • package.json (1 hunks)
  • package/index.d.ts (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • package.json
  • package/index.d.ts
🧰 Additional context used
🪛 markdownlint-cli2 (0.17.2)
CHANGELOG.md

15-15: Unordered list style
Expected: asterisk; Actual: dash

(MD004, ul-style)


19-19: Unordered list style
Expected: asterisk; Actual: dash

(MD004, ul-style)

⏰ Context from checks skipped due to timeout of 90000ms (20)
  • GitHub Check: Testing (ubuntu-latest, 3.0, gemfiles/Gemfile-rails.6.1.x)
  • GitHub Check: Testing (ubuntu-latest, 3.1, gemfiles/Gemfile-rails.7.2.x)
  • GitHub Check: Testing (ubuntu-latest, 3.2, gemfiles/Gemfile-rails.6.1.x)
  • GitHub Check: Generator specs (ubuntu-latest, 3.4, gemfiles/Gemfile-rails.8.0.x)
  • GitHub Check: Generator specs (ubuntu-latest, 3.3, gemfiles/Gemfile-rails.8.0.x)
  • GitHub Check: Generator specs (ubuntu-latest, 3.3, gemfiles/Gemfile-rails.7.2.x)
  • GitHub Check: Generator specs (ubuntu-latest, 3.2, gemfiles/Gemfile-rails.7.2.x)
  • GitHub Check: Generator specs (ubuntu-latest, 3.1, gemfiles/Gemfile-rails.6.1.x)
  • GitHub Check: Generator specs (ubuntu-latest, 3.0, gemfiles/Gemfile-rails.7.0.x)
  • GitHub Check: Generator specs (ubuntu-latest, 3.3, gemfiles/Gemfile-rails.7.1.x)
  • GitHub Check: Generator specs (ubuntu-latest, 3.2, gemfiles/Gemfile-rails.7.1.x)
  • GitHub Check: Generator specs (ubuntu-latest, 3.0, gemfiles/Gemfile-rails.6.1.x)
  • GitHub Check: Generator specs (ubuntu-latest, 2.7, gemfiles/Gemfile-rails.7.0.x)
  • GitHub Check: Generator specs (ubuntu-latest, 2.7, gemfiles/Gemfile-rails.7.1.x)
  • GitHub Check: Generator specs (ubuntu-latest, 2.7, gemfiles/Gemfile-rails.6.1.x)
  • GitHub Check: Generator specs (ubuntu-latest, 3.2, gemfiles/Gemfile-rails.8.0.x)
  • GitHub Check: Generator specs (ubuntu-latest, 3.2, gemfiles/Gemfile-rails.7.0.x)
  • GitHub Check: Generator specs (ubuntu-latest, 3.0, gemfiles/Gemfile-rails.6.0.x)
  • GitHub Check: Generator specs (ubuntu-latest, 2.7, gemfiles/Gemfile-rails.6.0.x)
  • GitHub Check: Generator specs (ubuntu-latest, 3.0, gemfiles/Gemfile-rails.7.1.x)

@G-Rath
Copy link
Copy Markdown
Contributor

G-Rath commented Mar 14, 2025

Note after applying this change to a project, I'm getting some errors that I've actually never seen before in TypeScript:

node_modules/webpack-dev-server/types/lib/Server.d.ts:1501:27 - error TS1542: Type import of an ECMAScript module from a CommonJS module must have a 'resolution-mode' attribute.

1501 type OpenOptions = import("open").Options;
                               ~~~~~~

node_modules/webpack-dev-server/types/lib/Server.d.ts:1657:19 - error TS1542: Type import of an ECMAScript module from a CommonJS module must have a 'resolution-mode' attribute.

1657   options: import("open").Options;
    

I'll do some more digging into what's happening, but I think it would be worth holding off landing this until this error is understood more; it might be worth cherry-picking some of these changes in the meantime e.g. the rules export type is definitely a correct fix, and it might be feasible to manually define/duplicate the dev server properties for the time being before we try sourcing them from the packages themselves

@alexeyr-ci2 alexeyr-ci2 force-pushed the alexeyr/improve-types branch from fc5209f to 3d007f3 Compare March 14, 2025 23:43
@alexeyr-ci2
Copy link
Copy Markdown
Contributor Author

@G-Rath

Seems to be reasonably well described in https://stackoverflow.com/questions/78907286/why-won-t-typescript-let-me-import-a-type-from-an-es-module-into-a-commonjs-modu.

The fix suggested there requires TS 5.3, and I don't know how safe it's to expect everywhere. Can you check if adding with { "resolution-mode": "import" } to import { Configuration as WebpackDevServerConfiguration } from 'webpack-dev-server' actually fixes your project?

According to https://www.typescriptlang.org/docs/handbook/release-notes/typescript-5-3.html, there is also a workaround supported from TS 4.7 and I think that's safe to assume. But I'm not sure about its implications.

it might be feasible to manually define/duplicate the dev server properties for the time being before we try sourcing them from the packages themselves

The major benefit of using the package types is that we'd get the correct properties for the webpack-dev-server version the project uses. But if we don't want to require TS 5.3 from anyone who'd use our types, this is probably the better solution.

@G-Rath
Copy link
Copy Markdown
Contributor

G-Rath commented Mar 15, 2025

The fix suggested there requires TS 5.3, and I don't know how safe it's to expect everywhere

Yup I'd seen that but didn't have time to dig further into it or give it a try, and I believe it needs to be at the import site where the error is raised.

While I'm still not in a good position to dig deeper, I have been able to confirm that last point i.e. adding the resolution-mode assertion to our import does nothing, but the error is resolved if it's added to the import("open") calls in the webpack-dev-server types.

@alexeyr-ci2
Copy link
Copy Markdown
Contributor Author

While I'm still not in a good position to dig deeper, I have been able to confirm that last point i.e. adding the resolution-mode assertion to our import does nothing, but the error is resolved if it's added to the import("open") calls in the webpack-dev-server types.

I misread the error message. Yes, probably better to duplicate and say that it depends on webpack-dev-server version then.

@alexeyr-ci2 alexeyr-ci2 force-pushed the alexeyr/improve-types branch from 46bafcc to e2cc49b Compare March 16, 2025 08:08
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
package/index.d.ts (1)

47-69: Comprehensive type definitions for dev server configuration.

The DevServerConfig interface provides much more precise typing compared to the previous Record<string, unknown>. Some properties still use generic Record<string, unknown> types where more specific types could be used.

Consider further improving the type precision for properties like client, dev_middleware, and proxy by either:

  1. Importing their specific types from webpack-dev-server
  2. Defining more specific interfaces based on the webpack-dev-server documentation

For example:

client?: {
  logging?: 'none' | 'error' | 'warn' | 'info' | 'log' | 'verbose';
  overlay?: boolean | { errors?: boolean; warnings?: boolean };
  progress?: boolean;
  webSocketURL?: string | { hostname?: string; pathname?: string; port?: string; protocol?: string };
}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3d007f3 and 46bafcc.

📒 Files selected for processing (1)
  • package/index.d.ts (2 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (19)
  • GitHub Check: Generator specs (ubuntu-latest, 3.2, gemfiles/Gemfile-rails.6.1.x)
  • GitHub Check: Generator specs (ubuntu-latest, 3.2, gemfiles/Gemfile-rails.7.1.x)
  • GitHub Check: Generator specs (ubuntu-latest, 3.4, gemfiles/Gemfile-rails.7.1.x)
  • GitHub Check: Generator specs (ubuntu-latest, 3.3, gemfiles/Gemfile-rails.7.0.x)
  • GitHub Check: Generator specs (ubuntu-latest, 3.2, gemfiles/Gemfile-rails.8.0.x)
  • GitHub Check: Generator specs (ubuntu-latest, 3.3, gemfiles/Gemfile-rails.7.2.x)
  • GitHub Check: Generator specs (ubuntu-latest, 3.0, gemfiles/Gemfile-rails.7.0.x)
  • GitHub Check: Generator specs (ubuntu-latest, 3.0, gemfiles/Gemfile-rails.7.1.x)
  • GitHub Check: Generator specs (ubuntu-latest, 3.1, gemfiles/Gemfile-rails.7.1.x)
  • GitHub Check: Generator specs (ubuntu-latest, 3.1, gemfiles/Gemfile-rails.7.2.x)
  • GitHub Check: Generator specs (ubuntu-latest, 3.1, gemfiles/Gemfile-rails.7.0.x)
  • GitHub Check: Generator specs (ubuntu-latest, 3.1, gemfiles/Gemfile-rails.6.1.x)
  • GitHub Check: Generator specs (ubuntu-latest, 2.7, gemfiles/Gemfile-rails.7.1.x)
  • GitHub Check: Generator specs (ubuntu-latest, 2.7, gemfiles/Gemfile-rails.6.0.x)
  • GitHub Check: Generator specs (ubuntu-latest, 3.0, gemfiles/Gemfile-rails.6.0.x)
  • GitHub Check: Generator specs (ubuntu-latest, 2.7, gemfiles/Gemfile-rails.6.1.x)
  • GitHub Check: Generator specs (ubuntu-latest, 2.7, gemfiles/Gemfile-rails.7.0.x)
  • GitHub Check: Generator specs (ubuntu-latest, 3.0, gemfiles/Gemfile-rails.6.1.x)
  • GitHub Check: test
🔇 Additional comments (6)
package/index.d.ts (6)

2-3: Good addition of specific type imports.

The imports for RuleSetRule from webpack and the Node.js https module provide the necessary type definitions for the more specific types being introduced in this PR.


36-38: Well-defined utility types for the dev server config.

These types provide clear definitions for headers, server types, and WebSocket types, which will make the dev server configuration more type-safe.


40-46: Clear documentation of the dev server configuration behavior.

The JSDoc comment effectively explains the relationship between this interface and webpack-dev-server's configuration, highlighting the key differences (snake_case property names and hmr instead of hot).


72-72: Improved type precision for devServer export.

Updating the type from Record<string, unknown> to the more specific DevServerConfig interface greatly improves type safety and developer experience.


76-76: Correct fix for rules export type.

Changing from Record<string, unknown> to RuleSetRule[] properly reflects that rules is an array of webpack rules rather than a record object.


40-69:

Details

❓ Verification inconclusive

Be aware of potential TypeScript module resolution issues.

Based on the PR comments, there were concerns about TypeScript errors related to ESM imports from CommonJS modules. While this declaration file doesn't directly address those issues, be mindful that consumers of this package might face compatibility issues with webpack-dev-server types depending on their TypeScript version.

If you're planning to use types from webpack-dev-server directly in the future, consider:

  1. Adding conditional type resolution for different TypeScript versions
  2. Documenting any minimum TypeScript version requirements
  3. Duplicating necessary types to avoid direct dependencies on potentially problematic imports

🌐 Web query:

TypeScript module resolution ESM from CommonJS error TS1542

💡 Result:

When encountering TypeScript error TS1542 ("An import path cannot end with a '.ts' extension") while importing ES modules (ESM) from CommonJS (CJS), the core issue stems from conflicting module systems and resolution strategies. Here's how to resolve it:

Key Problem

TypeScript enforces output file safety by default:

  • CJS projects using require() can't directly import ESM files (must use dynamic import())
  • File extensions must match the output JS format (.js instead of .ts in imports) [1][5]

Solutions

1. For CJS-to-ESM Interop:

// Use dynamic imports for ESM modules in CJS
const { esmFunction } = await import('./esm-module.js');

2. Configure tsconfig.json:

{
  "compilerOptions": {
    "module": "NodeNext", // or "ESNext" for pure ESM
    "moduleResolution": "NodeNext",
    "allowImportingTsExtensions": true, // If using .ts imports
    "esModuleInterop": true // Critical for CJS/ESM interop
  }
}

3. File Extension Handling:

// Always include .js extensions for ESM imports
import { helper } from './utils.js'; // Output extension, not .ts

Common Pitfalls & Fixes

Issue Solution
Mixing CJS/ESM in same project Use "type": "module" in package.json + dynamic imports for CJS [5][9]
Third-party ESM packages Enable esModuleInterop + verify package exports [8][9]
Node.js runtime errors Use --experimental-vm-modules flag for ESM tests [7][9]
Bundler configurations Set moduleResolution: "bundler" for webpack/Rollup [1][5]

Recommended Workflow

  1. Explicit Extensions: Always write imports with .js extensions, even for .ts files [1][5]
  2. Module Boundary: Separate ESM/CJS codebases when possible
  3. Build Tools: Use tsup or rollup with dual CJS/ESM output [5][7]
  4. Type Checking: Enable skipLibCheck: false for strict validation [6][12]

For library authors, include both build formats:

// package.json
{
  "exports": {
    ".": {
      "import": "./dist/esm/index.js",
      "require": "./dist/cjs/index.js"
    }
  }
}

Critical Note: The nodenext/node16 resolutions require strict ESM compliance in Node.js environments, while bundler mode offers more flexibility for frontend tools [1][4][5]. Always match your module and moduleResolution settings to the target runtime environment.

Citations:


ACTION REQUIRED: Verify TypeScript Module Resolution Settings

The changes in package/index.d.ts (lines 40–69) correctly update the webpack-dev-server configuration keys but do not address potential interop issues—specifically, the TS1542 errors arising when consumers import ESM modules from a CommonJS context. While this file isn’t designed to solve these issues, please note the following recommendations for future-proofing:

  • Conditional Type Resolution: If you plan to reference webpack-dev-server types directly, consider implementing conditional types or duplicating essential type definitions to decouple from problematic external dependencies.
  • Documentation Updates: Clearly document the supported TypeScript versions and required tsconfig.json settings (for example, ensuring settings like "module": "NodeNext", "moduleResolution": "NodeNext", and "esModuleInterop": true are appropriately configured) to help consumers avoid TS1542-related issues.
  • Consumer Guidance: Advise users of this package to verify and adjust their TypeScript configurations if they encounter module resolution errors, especially when mixing ESM and CommonJS modules.

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.

5 participants