Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

[AssetMapper] Rewrite relative paths in export ... from statements#64208

Merged
nicolas-grekas merged 1 commit into
symfony:6.4symfony/symfony:6.4from
ousamabenyounes:fix/issue-64183ousamabenyounes/symfony:fix/issue-64183Copy head branch name to clipboard
May 20, 2026
Merged

[AssetMapper] Rewrite relative paths in export ... from statements#64208
nicolas-grekas merged 1 commit into
symfony:6.4symfony/symfony:6.4from
ousamabenyounes:fix/issue-64183ousamabenyounes/symfony:fix/issue-64183Copy head branch name to clipboard

Conversation

@ousamabenyounes
Copy link
Copy Markdown
Contributor

@ousamabenyounes ousamabenyounes commented May 14, 2026

Q A
Branch? 6.4
Bug fix? yes
New feature? no
Deprecations? no
Issues Fix #64183
License MIT

JavaScriptImportPathCompiler's IMPORT_PATTERN only matches import /
import(...) statements. export * from './x.js' and export { foo } from './x.js'
re-exports are not captured, so the browser receives the original relative path
(unhashed) and 404s on the asset.

Reproduces with

Plain regex test (no PHPUnit needed) on the current 6.4 HEAD pattern:

input: "export * from './other.js';"
preg_match_all(IMPORT_PATTERN, input, $m)  -> 1 raw match, no capture group ($m[1] empty)
=> compile() early-returns, path stays "./other.js"

With the patch, $m[1] captures ./other.js, the path is rewritten through
findAssetForRelativeImport() and emitted as the versioned public path.

Fix

Extend the alternation block in IMPORT_PATTERN with an export branch that
requires a from clause (so plain export const x = 1; is correctly skipped):

export\s+
    (?:\*(?:\s*as\s+\w+)?|[\w\s{},*]+)
    \s*from\s*

This mirrors the existing import\s*(...)?\s*from\s* structure and reuses the
same trailing path-capture group.

Tests

5 new data-provider entries in provideCompileTests():

Case Input
static_export_star_from export * from './other.js';
static_export_named_from export { myFunction } from './other.js';
static_export_multiple_named_from export { myFunction, myOtherFunction } from './other.js';
static_export_star_as_namespace_from export * as myModule from './other.js';
export_const_without_from_is_ignored export const foo = 1;\nexport { bar } from './other.js'; (only the second matches)

Verified locally via docker run php:8.4-cli: 5/5 RED on the upstream/6.4
regex, 5/5 GREEN with the patch; plain export const x = 1; stays 0/0 on both.

Fixes #64183.

@yousefkadah
Copy link
Copy Markdown

Hi @ousamabenyounes 👋 I'd opened #64232 for the same issue (#64183) before spotting yours — closing mine in favor of this one since it came first. A few things from my version that might be worth folding in here:

  1. Minified re-exportsexport\s+ requires whitespace after export, so it misses minified code like export{x}from'./y.js' or export*from'./y.js'. Using export\s* covers those.
  2. Stricter named-export matching[\w\s{},*]+ is quite loose; requiring real braces with a possessive quantifier (\{[^}]*+\}) stays closer to actual JS syntax and avoids potential regex backtracking.
  3. Extra test coverage — a negative test that purely local exports produce no imports:
yield 'local_export_without_from_is_not_a_reexport' => [
    'input' => "export const foo = 1;\nexport default foo;\nexport { foo };",
    'expectedJavaScriptImports' => [],
];

plus a multi-line export { a, b } from "./other.js" case.

Happy to open a PR against your branch with these if it's useful. Thanks for tackling this!

@ousamabenyounes
Copy link
Copy Markdown
Contributor Author

Thanks for the review @yousefkadah — all three folded in at 4c085f6:

  • export\s+export\s* for minified re-exports.
  • Named-export group tightened to \{[^}]*+\} (real braces, possessive).
  • Added the pure negative test, a multi-line export { a, b } from case, and a minified case.

You're credited as co-author on the commit.

@nicolas-grekas
Copy link
Copy Markdown
Member

Thank you @ousamabenyounes.

@nicolas-grekas nicolas-grekas merged commit 53ebd2c into symfony:6.4 May 20, 2026
11 of 13 checks passed
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.

4 participants

Morty Proxy This is a proxified and sanitized view of the page, visit original site.