Skip to content

fix(webpack): use plugin for rollup-compatible dynamic imports #32281

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Jun 3, 2025

Conversation

danielroe
Copy link
Member

@danielroe danielroe commented Jun 3, 2025

🔗 Linked issue

📚 Description

webpack generates a chunk loading mechanism which doesn't place nicely with nitro.

in nitro v2 there's a built in dynamic-require plugin in the rollup build which handles this, but it has periodic problems when webpack changes its output format, and it also relies on a webpack manifest.

this changes switches to a webpack-native plugin to implement this directly in the webpack build, which allows us to handle changes/bugfixes in nuxt directly

@Copilot Copilot AI review requested due to automatic review settings June 3, 2025 13:04
Copy link

Review PR in StackBlitz Codeflow Run & review this pull request in StackBlitz Codeflow.

Copy link

@Copilot 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 updates the dynamic require plugin integration within the Nitro hook for webpack by replacing the legacy dynamic plugin injection with a hook-based approach.

  • Moved plugin injection into the 'rollup:before' hook
  • Replaced old dynamicRequire plugin instantiation with a new rollupCompatPlugin
  • Simplified plugin management by using a single plugins array from config
Comments suppressed due to low confidence (1)

packages/webpack/src/webpack.ts:39

  • The new rollupCompatPlugin configuration omits the 'inline' and 'ignore' options that were present in the original dynamicRequire plugin. Please confirm that these options are no longer necessary, as their removal might affect dynamic import handling.
const rollupCompatPlugin = dynamicRequire({

Copy link

coderabbitai bot commented Jun 3, 2025

Walkthrough

The change removes the injection of the dynamicRequire Rollup plugin into Nitro's Rollup plugin arrays during production builds. Instead of creating and inserting the plugin instance, the updated code registers a hook on Nitro's rollup:before event that accesses the Rollup configuration and removes any existing dynamic-require plugin without adding a replacement. The dynamicRequire plugin implementation and its related imports are deleted. Additionally, a new Webpack plugin, RollupCompatDynamicImportPlugin, is introduced and conditionally added to the Webpack configuration for server production builds to transform Webpack-style dynamic imports into Rollup-compatible dynamic imports. No changes were made to exported or public entity declarations except for the addition of the new Webpack plugin class.

✨ Finishing Touches
  • 📝 Generate Docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 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.
    • Explain this complex logic.
    • 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 explain this code block.
    • @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 explain its main purpose.
    • @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.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

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 generate sequence diagram to generate a sequence diagram of the changes in 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.

Copy link

pkg-pr-new bot commented Jun 3, 2025

Open in StackBlitz

@nuxt/kit

npm i https://pkg.pr.new/@nuxt/kit@32281

nuxt

npm i https://pkg.pr.new/nuxt@32281

@nuxt/rspack-builder

npm i https://pkg.pr.new/@nuxt/rspack-builder@32281

@nuxt/schema

npm i https://pkg.pr.new/@nuxt/schema@32281

@nuxt/vite-builder

npm i https://pkg.pr.new/@nuxt/vite-builder@32281

@nuxt/webpack-builder

npm i https://pkg.pr.new/@nuxt/webpack-builder@32281

commit: 63f12b1

Copy link

@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: 1

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 62afcd5 and cbec432.

📒 Files selected for processing (1)
  • packages/webpack/src/webpack.ts (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
packages/webpack/src/webpack.ts (1)
packages/webpack/src/nitro/plugins/dynamic-require.ts (1)
  • dynamicRequire (35-90)
🪛 GitHub Check: code
packages/webpack/src/webpack.ts

[failure] 42-42:
Mixed spaces and tabs


[failure] 42-42:
Unexpected tab character

🪛 GitHub Actions: autofix.ci
packages/webpack/src/webpack.ts

[error] 42-42: ESLint: Unexpected tab character (@stylistic/no-tabs)

⏰ Context from checks skipped due to timeout of 90000ms (20)
  • GitHub Check: test-fixtures (windows-latest, built, vite, async, manifest-off, json, 20)
  • GitHub Check: test-fixtures (windows-latest, built, webpack, async, manifest-on, json, 20)
  • GitHub Check: test-fixtures (ubuntu-latest, built, rspack, async, manifest-on, json, 20)
  • GitHub Check: test-fixtures (windows-latest, built, rspack, async, manifest-on, json, 20)
  • GitHub Check: test-fixtures (windows-latest, built, vite, async, manifest-on, json, 20)
  • GitHub Check: test-fixtures (windows-latest, dev, vite, async, manifest-on, json, 20)
  • GitHub Check: test-fixtures (ubuntu-latest, built, webpack, default, manifest-on, json, 20)
  • GitHub Check: test-fixtures (windows-latest, dev, vite, default, manifest-off, json, 20)
  • GitHub Check: test-fixtures (ubuntu-latest, built, vite, default, manifest-on, json, 20)
  • GitHub Check: test-fixtures (ubuntu-latest, built, webpack, async, manifest-on, json, 20)
  • GitHub Check: test-fixtures (ubuntu-latest, built, vite, default, manifest-off, json, 20)
  • GitHub Check: test-fixtures (ubuntu-latest, built, rspack, default, manifest-on, json, 20)
  • GitHub Check: test-fixtures (ubuntu-latest, built, vite, async, manifest-on, js, 20)
  • GitHub Check: test-fixtures (ubuntu-latest, built, vite, async, manifest-on, json, 20)
  • GitHub Check: test-fixtures (ubuntu-latest, built, vite, async, manifest-off, json, 20)
  • GitHub Check: test-fixtures (ubuntu-latest, dev, vite, async, manifest-off, json, 20)
  • GitHub Check: test-fixtures (ubuntu-latest, dev, vite, async, manifest-on, js, 20)
  • GitHub Check: test-fixtures (ubuntu-latest, dev, vite, async, manifest-on, json, 20)
  • GitHub Check: test-benchmark
  • GitHub Check: typecheck (windows-latest, bundler)
🔇 Additional comments (1)
packages/webpack/src/webpack.ts (1)

38-59: Excellent architectural improvement using Nitro's hook system.

This refactoring properly leverages Nitro's rollup:before hook instead of directly manipulating internal plugin arrays. The approach is more maintainable and follows Nitro's intended extension patterns whilst preserving the same plugin injection logic.

🧰 Tools
🪛 GitHub Check: code

[failure] 42-42:
Mixed spaces and tabs


[failure] 42-42:
Unexpected tab character

🪛 GitHub Actions: autofix.ci

[error] 42-42: ESLint: Unexpected tab character (@stylistic/no-tabs)

Copy link

codspeed-hq bot commented Jun 3, 2025

CodSpeed Performance Report

Merging #32281 will not alter performance

Comparing fix/replace (63f12b1) with main (62afcd5)

Summary

✅ 10 untouched benchmarks

Copy link

@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)
packages/webpack/src/plugins/rollup-compat-dynamic-import.ts (1)

79-79: Consider using a more robust import detection method.

While unlikely to cause issues, using includes() to check for existing imports could match the string in comments or other contexts. Consider using a regex or AST-based approach for more precise detection.

-    if (needsHelperImport && !transformed.includes('from "./_dynamic-import-helper.mjs"')) {
+    if (needsHelperImport && !/^import\s+.*from\s+["'].?\/_dynamic-import-helper\.mjs["']/m.test(transformed)) {
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between cbec432 and 7796f28.

📒 Files selected for processing (4)
  • packages/webpack/src/nitro/plugins/dynamic-require.ts (0 hunks)
  • packages/webpack/src/plugins/rollup-compat-dynamic-import.ts (1 hunks)
  • packages/webpack/src/presets/base.ts (2 hunks)
  • packages/webpack/src/webpack.ts (1 hunks)
💤 Files with no reviewable changes (1)
  • packages/webpack/src/nitro/plugins/dynamic-require.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/webpack/src/webpack.ts
🧰 Additional context used
🧬 Code Graph Analysis (1)
packages/webpack/src/presets/base.ts (1)
packages/webpack/src/plugins/rollup-compat-dynamic-import.ts (1)
  • RollupCompatDynamicImportPlugin (11-136)
🪛 GitHub Check: CodeQL
packages/webpack/src/plugins/rollup-compat-dynamic-import.ts

[warning] 120-120: Improper code sanitization
Code construction depends on an improperly sanitized value.

⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: build
  • GitHub Check: code
🔇 Additional comments (3)
packages/webpack/src/presets/base.ts (1)

17-17: LGTM! Clean integration of the new plugin.

The import and conditional plugin addition are well-placed and the logic correctly targets server-side production builds where Rollup compatibility is needed.

Also applies to: 123-126

packages/webpack/src/plugins/rollup-compat-dynamic-import.ts (2)

1-136: Well-structured Webpack plugin implementation!

The plugin correctly transforms Webpack-style dynamic imports into Rollup-compatible ones. The implementation follows Webpack plugin best practices with proper hooks, error handling, and performance optimisations.

🧰 Tools
🪛 GitHub Check: CodeQL

[warning] 120-120: Improper code sanitization
Code construction depends on an improperly sanitized value.


113-122: The CodeQL warning is a false positive.

The static analysis warning about improper code sanitization can be safely ignored. The filename values come from Webpack's internally generated chunk files, not user input, and are already properly escaped using JSON.stringify() on both the object key and the import path.

🧰 Tools
🪛 GitHub Check: CodeQL

[warning] 120-120: Improper code sanitization
Code construction depends on an improperly sanitized value.

@danielroe danielroe changed the title fix(webpack): replace dynamic require plugin in nitro hook fix(webpack): use plugin for rollup-compatible dynamic imports Jun 3, 2025
Copy link

@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: 2

♻️ Duplicate comments (1)
packages/webpack/src/plugins/rollup-compat-dynamic-import.ts (1)

4-5: ⚠️ Potential issue

Address the security vulnerability in regex replacement.

The regex replacement pattern captures content from __webpack_require__ expressions and directly interpolates it into generated code without validation, creating a code injection vulnerability.

The captured group could contain malicious code that gets executed. Consider validating the captured content:

-  transformed = transformed.replace(DYNAMIC_IMPORT_REPLACE_RE, (match, filename) => {
+  transformed = transformed.replace(DYNAMIC_IMPORT_REPLACE_RE, (match, filename) => {
+    // Validate that filename contains only safe webpack require patterns
+    if (!/^__webpack_require__\.[a-zA-Z_$][a-zA-Z0-9_$]*\([^)]*\)$/.test(filename.trim())) {
+      throw new Error(`Invalid webpack require pattern: ${filename}`)
+    }
     needsHelperImport = true
     // Generate a rollup-compatible dynamic import using the module ID
     return `_rollupDynamicImport(${filename}).then`
   })
🧹 Nitpick comments (1)
packages/webpack/src/plugins/rollup-compat-dynamic-import.ts (1)

13-66: Improve file filtering and consider performance optimisation.

The method structure is correct, but consider these improvements:

  1. Extract the file extension check to a helper function
  2. Add more explicit comments about chunk filtering logic
  3. Consider early termination for large files that don't need processing
+  private static isJavaScriptFile(filename: string): boolean {
+    return filename.endsWith('.js') || filename.endsWith('.mjs') || filename.endsWith('.cjs')
+  }

   // Transform JavaScript files that contain dynamic imports
   for (const [filename, asset] of Object.entries(assets)) {
-    if (!filename.endsWith('.js') && !filename.endsWith('.mjs') && !filename.endsWith('.cjs')) {
+    if (!RollupCompatDynamicImportPlugin.isJavaScriptFile(filename)) {
       continue
     }
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 7796f28 and d299dcd.

📒 Files selected for processing (1)
  • packages/webpack/src/plugins/rollup-compat-dynamic-import.ts (1 hunks)
🔇 Additional comments (3)
packages/webpack/src/plugins/rollup-compat-dynamic-import.ts (3)

1-2: LGTM!

The imports are appropriate for a Webpack plugin and use proper TypeScript typing.


7-12: LGTM!

Well-documented class that properly implements the WebpackPluginInstance interface.


114-133: LGTM!

Well-implemented helper content generation using safe code generation utilities and proper error handling.

Comment on lines 68 to 86
private transformDynamicImports (source: string): string {
let transformed = source
let needsHelperImport = false

// Transform webpack-style dynamic imports to rollup-compatible ones
transformed = transformed.replace(DYNAMIC_IMPORT_REPLACE_RE, (match, filename) => {
needsHelperImport = true
// Generate a rollup-compatible dynamic import using the module ID
return `_rollupDynamicImport(${filename}).then`
})

// Add import statement at the top if we made any transformations
if (needsHelperImport && !transformed.includes('from "./_dynamic-import-helper.mjs"')) {
const importStatement = 'import { _rollupDynamicImport } from "./_dynamic-import-helper.mjs";\n'
transformed = importStatement + transformed
}

return transformed
}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Improve helper import injection robustness.

The helper import injection logic could be more robust:

  1. The string search for existing imports is fragile
  2. Consider using AST-based injection for reliability
  3. The hardcoded relative path might not work in all webpack configurations
   // Add import statement at the top if we made any transformations
-  if (needsHelperImport && !transformed.includes('from "./_dynamic-import-helper.mjs"')) {
+  if (needsHelperImport && !/import\s+\{[^}]*_rollupDynamicImport[^}]*\}\s+from\s+["']\.?\/?_dynamic-import-helper\.mjs["']/.test(transformed)) {
     const importStatement = 'import { _rollupDynamicImport } from "./_dynamic-import-helper.mjs";\n'
     transformed = importStatement + transformed
   }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
private transformDynamicImports (source: string): string {
let transformed = source
let needsHelperImport = false
// Transform webpack-style dynamic imports to rollup-compatible ones
transformed = transformed.replace(DYNAMIC_IMPORT_REPLACE_RE, (match, filename) => {
needsHelperImport = true
// Generate a rollup-compatible dynamic import using the module ID
return `_rollupDynamicImport(${filename}).then`
})
// Add import statement at the top if we made any transformations
if (needsHelperImport && !transformed.includes('from "./_dynamic-import-helper.mjs"')) {
const importStatement = 'import { _rollupDynamicImport } from "./_dynamic-import-helper.mjs";\n'
transformed = importStatement + transformed
}
return transformed
}
private transformDynamicImports (source: string): string {
let transformed = source
let needsHelperImport = false
// Transform webpack-style dynamic imports to rollup-compatible ones
transformed = transformed.replace(DYNAMIC_IMPORT_REPLACE_RE, (match, filename) => {
needsHelperImport = true
// Generate a rollup-compatible dynamic import using the module ID
return `_rollupDynamicImport(${filename}).then`
})
// Add import statement at the top if we made any transformations
if (needsHelperImport && !/import\s+\{[^}]*_rollupDynamicImport[^}]*\}\s+from\s+["']\.?\/?_dynamic-import-helper\.mjs["']/.test(transformed)) {
const importStatement = 'import { _rollupDynamicImport } from "./_dynamic-import-helper.mjs";\n'
transformed = importStatement + transformed
}
return transformed
}
🤖 Prompt for AI Agents
In packages/webpack/src/plugins/rollup-compat-dynamic-import.ts around lines 68
to 86, the current method of injecting the helper import uses a fragile string
search and a hardcoded relative path. To fix this, replace the string-based
check and insertion with an AST-based approach to reliably detect and inject the
import statement. Also, avoid hardcoding the import path by resolving it
dynamically based on the webpack configuration or plugin context to ensure
compatibility across different setups.

Copy link

@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: 2

♻️ Duplicate comments (1)
packages/webpack/src/plugins/rollup-compat-dynamic-import.ts (1)

98-99: ⚠️ Potential issue

Add null check for chunk.files to prevent runtime errors.

The code iterates over chunk.files without checking if it exists, unlike the safer approach used on line 28.

Apply this diff to add the null check:

-      for (const filename of chunk.files) {
+      for (const filename of chunk.files || []) {
🧹 Nitpick comments (1)
packages/webpack/src/plugins/rollup-compat-dynamic-import.ts (1)

5-6: Strengthen regex patterns for better dynamic import detection.

The current regex patterns may miss edge cases or incorrectly match unintended code patterns:

  1. DYNAMIC_IMPORT_RE assumes the presence of a + operator and .then suffix, which might not cover all webpack dynamic import variations
  2. The capture group (__webpack_require__[^+]*) could potentially capture more than intended in complex expressions

Consider making the patterns more robust to handle various webpack dynamic import formats.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between d299dcd and 63f12b1.

📒 Files selected for processing (1)
  • packages/webpack/src/plugins/rollup-compat-dynamic-import.ts (1 hunks)
🔇 Additional comments (2)
packages/webpack/src/plugins/rollup-compat-dynamic-import.ts (2)

119-119:

✅ Verification successful

Address potential code injection vulnerability in dynamic code generation.

The dynamic generation of the chunk map uses filenames that could potentially contain malicious content, creating a code injection risk. While genString provides some protection, this represents a security concern as flagged by the static analysis.

Consider validating and sanitising chunk filenames before code generation:

+  private sanitiseFilename(filename: string): string {
+    // Allow only safe characters for filenames
+    return filename.replace(/[^a-zA-Z0-9.\-_/]/g, '')
+  }

   private generateHelperContent (chunkFiles: string[]): string {
+    const sanitisedFiles = chunkFiles.map(f => this.sanitiseFilename(f))
     return `
 // Rollup-compatible dynamic import helper generated by webpack
 // This helper enables rollup to consume webpack chunks directly

-const chunkMap = ${genObjectFromRawEntries(chunkFiles.map(filename => [filename, `() => import(${genString('./' + filename)})`]))}
+const chunkMap = ${genObjectFromRawEntries(sanitisedFiles.map(filename => [filename, `() => import(${genString('./' + filename)})`]))}

Let me verify the security implications of this approach:


🏁 Script executed:

#!/bin/bash
# Search for other instances of dynamic code generation that might have similar security concerns
rg -A 3 -B 3 "genObjectFromRawEntries|genString" --type ts

Length of output: 10981


Safe dynamic import generation: no sanitisation needed

Webpack’s chunkFiles array is derived from internal asset filenames (typically deterministic hashes and extensions) rather than user-supplied input, and genString escapes all special characters when emitting a JS string literal. This guards against any code-injection risk in the generated helper. No additional filename sanitisation is required here.


125-125: 🛠️ Refactor suggestion

Sanitise chunkId in error messages to prevent information disclosure.

The error message includes the raw chunkId which could potentially expose sensitive information or be used for reconnaissance attacks.

Apply this diff to sanitise the error message:

-    return Promise.reject(new Error(\`Chunk \${chunkId} not found in chunkMap. Available chunks: \${Object.keys(chunkMap).join(', ')}\`))
+    return Promise.reject(new Error(\`Chunk not found in chunkMap. Available chunks: \${Object.keys(chunkMap).length}\`))

Likely an incorrect or invalid review comment.

Comment on lines +52 to +58
// Transform dynamic imports in this file
const transformedCode = this.transformDynamicImports(originalCode)

if (transformedCode !== originalCode) {
assets[filename] = new compiler.webpack.sources.RawSource(transformedCode)
}
}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add validation for transformed code integrity.

The plugin transforms code using regex replacement but doesn't validate that the transformation produces syntactically correct JavaScript. Invalid transformations could lead to runtime errors.

Consider adding basic validation:

   // Transform dynamic imports in this file
   const transformedCode = this.transformDynamicImports(originalCode)

   if (transformedCode !== originalCode) {
+    // Basic validation to ensure transformation didn't break syntax
+    try {
+      new Function(transformedCode)
+    } catch (error) {
+      throw new Error(`Code transformation resulted in invalid JavaScript for ${filename}: ${error.message}`)
+    }
     assets[filename] = new compiler.webpack.sources.RawSource(transformedCode)
   }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// Transform dynamic imports in this file
const transformedCode = this.transformDynamicImports(originalCode)
if (transformedCode !== originalCode) {
assets[filename] = new compiler.webpack.sources.RawSource(transformedCode)
}
}
// Transform dynamic imports in this file
const transformedCode = this.transformDynamicImports(originalCode)
if (transformedCode !== originalCode) {
// Basic validation to ensure transformation didn't break syntax
try {
new Function(transformedCode)
} catch (error) {
throw new Error(
`Code transformation resulted in invalid JavaScript for ${filename}: ${error.message}`
)
}
assets[filename] = new compiler.webpack.sources.RawSource(transformedCode)
}
🤖 Prompt for AI Agents
In packages/webpack/src/plugins/rollup-compat-dynamic-import.ts around lines 52
to 58, after transforming the dynamic imports, add a validation step to check
that the transformedCode is syntactically valid JavaScript. You can do this by
attempting to parse the transformedCode using a JavaScript parser or a try-catch
block with eval or a similar safe method. If the validation fails, log an error
or throw an exception to prevent invalid code from being emitted. This ensures
that only syntactically correct transformations are applied to the assets.

Comment on lines +105 to +107
if (chunkFiles.length === 0) {
return
}
Copy link

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Consider the implications of skipping helper generation when no chunks are found.

If dynamic imports exist but no valid chunks are found, the helper won't be generated, potentially causing runtime errors when the transformed code tries to use _rollupDynamicImport.

Verify this scenario and consider whether to generate an empty helper or provide better error handling:


🏁 Script executed:

#!/bin/bash
# Check if there are scenarios where dynamic imports might exist without corresponding chunks
rg -A 5 -B 5 "hasRuntime\(\)|canBeInitial\(\)" --type ts

Length of output: 2163


🏁 Script executed:

#!/bin/bash
rg -n "generateDynamicImportHelper" --type ts

Length of output: 296


Ensure proper handling when no chunks are found but dynamic imports were transformed

The current check in generateDynamicImportHelper

if (chunkFiles.length === 0) {
  return
}

will silently skip helper injection even if you’ve rewritten calls to _rollupDynamicImport, leading to uncaught runtime errors.

You should:

  • Track whether any dynamic-import calls were rewritten (e.g. set a hasDynamicImport flag during your AST-transform).
  • Change the empty-array guard to only bail out when no dynamic imports exist.
  • When hasDynamicImport is true but chunkFiles.length === 0, either:
    • Emit a build-time error or warning pointing out that no chunks were generated for dynamic imports, or
    • Generate a stub helper that throws a clear, descriptive error at runtime.

For example, in packages/webpack/src/plugins/rollup-compat-dynamic-import.ts around line 105:

   if (chunkFiles.length === 0) {
-    return
+    // If no dynamic imports were seen, it’s safe to skip helper.
+    if (!this.hasDynamicImport) return
+
+    // Otherwise we need to fail fast or stub out the helper.
+    compilation.warnings.push(
+      new Error('[rollup-compat] Dynamic import transformed but no chunks found.')
+    )
+    this.emitHelper(`
+      function _rollupDynamicImport() {
+        throw new Error('No dynamic import chunks available – check your configuration.')
+      }
+    `)
+    return
   }

This ensures you neither generate a useless helper when it isn’t needed nor leave transformed import calls dangling when it is.

🤖 Prompt for AI Agents
In packages/webpack/src/plugins/rollup-compat-dynamic-import.ts around lines 105
to 107, the current code returns early without generating the helper if
chunkFiles is empty, even if dynamic imports were rewritten, causing runtime
errors. Modify the logic to track whether any dynamic imports were rewritten
with a flag like hasDynamicImport. Only skip helper generation if no dynamic
imports exist. If hasDynamicImport is true but chunkFiles is empty, either emit
a build-time error or generate a stub helper that throws a clear runtime error
to prevent dangling transformed calls.

@danielroe danielroe requested a review from pi0 June 3, 2025 15:30
@danielroe danielroe merged commit 8404fc9 into main Jun 3, 2025
47 checks passed
@danielroe danielroe deleted the fix/replace branch June 3, 2025 16:20
@github-actions github-actions bot mentioned this pull request Jun 3, 2025
@github-actions github-actions bot mentioned this pull request Jun 3, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy