Thanks to visit codestin.com
Credit goes to github.com

Skip to content

[AssetMapper] Circular reference error because IMPORT_PATTERN regexp matches comments as well #51291

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

Closed
mhitza opened this issue Aug 6, 2023 · 3 comments

Comments

@mhitza
Copy link

mhitza commented Aug 6, 2023

Symfony version(s) affected

6.3.2

Description

I'm trying to integrate AssetMapper within one of my projects, and I'm stuck because I get a circular reference error.

In MappedAssetFactory.php line 39:
                                                                                                 
  Circular reference detected while creating asset for "js/htmx.js": "js/htmx.js -> js/htmx.js"

How to reproduce

The issue shows with htmx.js library, as it has the following style of comments within the code:

/**
 *
 * @param {HTMLElement} elt
 * @param {string} swapInfoOverride
 * @returns {import("./htmx").HtmxSwapSpecification}
 */
function getSwapSpecification(elt, swapInfoOverride) {

The import syntax within the return annotations trips up the import pattern regexp causing a false positive when checking for circular references.

Possible Solution

Short of writing/integratng a proper javascript parser, the only quicker workaround I can think of right now would be to use the PREG_OFFSET_CAPTURE flag for the replace regexp in JavaScriptImportPathCompiler.php, and use that offset information to slice a context around the position in order to deduce if the the match is within a comment or string (?) context (requiering the implementation of these two type of parsers).

Additional Context

As a workaround, if it is useful for other users landing on this issue, I have written a small js script to strip out all the comments from a JavaScript file https://gist.github.com/mhitza/ddc8326e1c94094bdab762e6171e459a

@weaverryan
Copy link
Member

Hey @mhitza!

Yea, I expected this to happen eventually - I was curious to see what situation caused it exactly.

However, I wasn't able to repeat this: I created a new Symfony app, installed asset mapper, ran importmap:require htmlx.org and then added import 'htmx.org'; to my assets/app.js file. I also verified that HTMX was functioning correctly on my page.

Also, while I DO agree that @returns {import("./htmx").HtmxSwapSpecification} will incorrectly be matched by the regex, I can't see how it would trigger the circular reference. When we parse this, we would find ./htmx. But that class doesn't assume/add the .js onto the end. So it would try to look for a file called htmx, not htmx.js. And, while that might trigger a log warning when the assets build, it wouldn't create a real problem.

So I think there may be a legit issue here yet, but I'm still missing a piece. Do you have a reproducer?

Cheers!

@mhitza
Copy link
Author

mhitza commented Aug 8, 2023

The following code should create an appropiate environment (assuming all the tools are present, of course)

symfony new poc --version="6.3.*" --webapp

cd poc

composer require symfony/asset-mapper symfony/asset symfony/twig-pack

mkdir assets/js

curl https://raw.githubusercontent.com/bigskysoftware/htmx/master/src/htmx.js --output assets/js/htmx.js

echo "<script type=module>import '{{ asset('js/htmx.js') }}';</script></body>" > replace.txt

sed -i '/\/body>/r replace.txt' templates/base.html.twig

./bin/console make:controller HomeController

symfony serve

https://localhost:8000/home should show the error I've encountered.


I go through the process of manually updating my local htmx.js file by copying the source code from GitHub locally in assets/js/htmx.js . For this project, I don't use: 1) nodejs package manager, 2) js cdns, 3) minified or stripped code (well, not until a few days ago :) )

@weaverryan
Copy link
Member

weaverryan commented Aug 10, 2023

Fixed in: #51345 - the circular reference was actually triggered when trying to create an informative log message. After that PR, the parser will still incorrectly find these import statements, but they'll just be ignored as no htmx file exists (htmx.js exists, but not htmx). You may see a few warning logs about this - but those are just that: warnings - and they can be ignored.

Thanks for the quick-to-setup reproducer ❤️

nicolas-grekas added a commit that referenced this issue Aug 14, 2023
…be thrown while making error message (weaverryan)

This PR was squashed before being merged into the 6.3 branch.

Discussion
----------

[AssetMapper] Fixing bug where a circular exception could be thrown while making error message

| Q             | A
| ------------- | ---
| Branch?       | 6.3
| Bug fix?      | yes
| New feature?  | no
| Deprecations? | none
| Tickets       | Fix #51291
| License       | MIT
| Doc PR        | Not needed

AssetMapper's `JavaScriptImportPathCompiler` parses import statements. That process is imperfect and will over-match in some cases (e.g. matching `import()` that is commented-out). but that's not a huge issue: any matches are simply added to the importmap and matches for not-found-files are ignored.

However, in #51291, we hit a spot where, while trying to improve the log message (`Try adding ".js" to the end of the import - i.e. "%s.js"`), we triggered a circular exception. This PR suppresses that.

We may need to improve the parsing logic later to handle more edge-cases, but we'll handle those if/when they come up.

Cheers!

Commits
-------

63b9635 [AssetMapper] Fixing bug where a circular exception could be thrown while making error message
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants