Skip to content

handle multi-line comments in AssetMapper javascript compiler #58944

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
wants to merge 2 commits into from

Conversation

tacman
Copy link
Contributor

@tacman tacman commented Nov 20, 2024

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

This fixes the issue where assetmapper tries to include a javascript import that is embedded in a comment.

@carsonbot
Copy link

Hey!

Thanks for your PR. You are targeting branch "7.3" but it seems your PR description refers to branch "6.4".
Could you update the PR description or change target branch? This helps core maintainers a lot.

Cheers!

Carsonbot

@tacman
Copy link
Contributor Author

tacman commented Nov 20, 2024

drat, how do I change the target branch?

@OskarStark OskarStark changed the title handle multi-line comments in AssetMapper javscript compiler handle multi-line comments in AssetMapper javascript compiler Nov 20, 2024
@alexislefebvre
Copy link
Contributor

drat, how do I change the target branch?

Press Edit next to the title, it allows to edit the title and the target branch.

@tacman tacman changed the base branch from 7.3 to 6.4 November 22, 2024 18:14
Comment on lines 96 to 137
yield 'import_in_multiline_comment' => [
'input' => <<<EOF
// Asynchronous loading
/**
* Used in conjunction with the `m` component to reduce bundle size.
*
* `m` is a version of the `motion` component that only loads functionality
* critical for the initial render.
*
* `LazyMotion` can then be used to either synchronously or asynchronously
* load animation and gesture support.
*
* ```jsx
* // Synchronous loading
* import { LazyMotion, m, domAnimations } from "framer-motion"
*
* function App() {
* return (
* <LazyMotion features={domAnimations}>
* <m.div animate={{ scale: 2 }} />
* </LazyMotion>
* )
* }
*
* // Asynchronous loading
* import { LazyMotion, m } from "framer-motion"
*
* function App() {
* return (
* <LazyMotion features={() => import('./path/to/domAnimations')}>
* <m.div animate={{ scale: 2 }} />
* </LazyMotion>
* )
* }
* ```
*
* @public
*/
EOF,
'expectedJavaScriptImports' => [],
];

Copy link
Member

Choose a reason for hiding this comment

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

Nice catch, @tacman!
Could you reduce this test to the minimal amount of code? It will be easier to later maintain and also will ensure we are testing this case and not any other conditions. :)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done!

@stof
Copy link
Member

stof commented Nov 25, 2024

@tacman you should not merge branch 7.2 into your feature branch (and even less if you submit this to 6.4)

@tacman
Copy link
Contributor Author

tacman commented Nov 25, 2024

ack! I was trying to fix the failed tests, and merged the wrong branch. git revert HEAD isn't working, is there a way I can simply delete my last commit (which was erroneously merging 7.2)?

@stof
Copy link
Member

stof commented Nov 25, 2024

@tacman you need to reset your branch (not revert, which creates more commits) and perform a force push.

@tacman tacman force-pushed the asset-mapper-multi-line-comments branch from 903d00c to ca4a779 Compare November 25, 2024 10:52
@tacman
Copy link
Contributor Author

tacman commented Nov 25, 2024

OK, hopefully my branch and PR are okay now.

@@ -155,6 +155,11 @@ private function isCommentedOut(mixed $offsetStart, string $fullContent): bool
return true;
}

// inside a multi-line comment, since javascript can't start with a '* '
if ('* ' === $firstTwoChars) {
Copy link
Member

Choose a reason for hiding this comment

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

This is broken for multiple reasons:

  • a JS line can actually start with * if you split a long expression at the position of a multiplication operator, which is totally valid
  • lines inside a multiline comment are not required to start with * . JSDoc comments follow such convention, but as far as the JS parser is concerned, the * is just part of the comment text.

Anyway, by definition of a multiline comment, you cannot identify that you are inside such a comment by inspecting only the currently line.

@tacman
Copy link
Contributor Author

tacman commented Nov 25, 2024

alas, I'm not sure how to solve this then. I imagine with some sort of multi-line comment regex.

On a related note, I'm surprised that api-platform hasn't minified this file in such a way to remove the comments. Of course, it wouldn't be a real solution to this problem, but avoid the immediate issue integrating it.

Comment on lines +96 to +105
yield 'import_in_multiline_comment' => [
'input' => <<<EOF
/**
* <LazyMotion features={() => import('./path/to/domAnimations')} />
* ```
*/
EOF,
'expectedJavaScriptImports' => [],
];

Copy link
Member

Choose a reason for hiding this comment

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

This test is already passing on 6.4 and 7.1 (on my machine).. Could you double-check ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Then perhaps the test is wrong. The underlying problem is with an API Platform js file, causing this trivial example to fail.

symfony new MyApp  --webapp && cd MyApp
composer req api
bin/console make:entity -a Task -n
symfony server:start -d
symfony open:local --path=/api

Copy link
Member

Choose a reason for hiding this comment

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

I'm just trying to get a "before" / "after" here ;) Without it i cannot be sure if what i'm doing has any effect :)

@smnandre
Copy link
Member

I think this is due/new because of this change in the recipes: symfony/recipes@ab0209c

You can hide this by disabling the strict check in dev

framework:
    asset_mapper:
        # The paths to make available to the asset mapper.
        paths:
            - assets/
        missing_import_mode: warn

when@prod:
    framework:
        asset_mapper:
            missing_import_mode: warn

For the parsing part, i made a PR some time ago to add some "parser" code and improve the detection of import..

It seems it's time to reopen it :)

#54134

@dunglas
Copy link
Member

dunglas commented Nov 26, 2024

+1 for the ad-hoc parser PR. I don't think we'll manage to fix this reliably just with regular expressions.

@tacman
Copy link
Contributor Author

tacman commented Nov 26, 2024

It seems to me that the strict setting for 3rd-party bundles is problematic. It's like the deprecation warnings the fill the logs when it's out of the developers control.

Is it possible to make the missing_import_mode related only to the developer's code and excludes /vendor?

smnandre added a commit to smnandre/symfony that referenced this pull request Nov 26, 2024
@smnandre
Copy link
Member

Could you try with this branch @tacman ? I rebased and fixed a test but i have not much time today/tomorrow sorry :)

#58999

@Spomky
Copy link
Contributor

Spomky commented Jan 19, 2025

Hi,

Maybe you could just remove comments first?
I found this and it looks like the regex works fine.

#src/Symfony/Component/AssetMapper/Compiler/JavaScriptImportPathCompiler.phpL62
    public function compile(string $content, MappedAsset $asset, AssetMapperInterface $assetMapper): string
    {
        $pattern = '/(?:(?:\/\*(?:[^*]|(?:\*+[^*\/]))*\*+\/)|(?:(?<!\:|\\\|\'|\")\/\/.*))/';
        $content = preg_replace($pattern, '', $content);

        return preg_replace_callback(self::IMPORT_PATTERN, ...

@smnandre
Copy link
Member

$content = preg_replace($pattern, '', $content);

We do not want to change the source files here (except to replace the url with the good ones).

@smnandre
Copy link
Member

The only way to perfectly ignore comments is to use a state-machine / parser (see #59004)

fabpot added a commit that referenced this pull request Jan 25, 2025
…nandre)

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

Discussion
----------

[AssetMapper] Detect import with a sequence parser

| Q             | A
| ------------- | ---
| Branch?       | 7.3
| Bug fix?      | yes
| New feature?  | no
| Deprecations? | no
| Issues        | Fix #58928  and #58944  (maybe)
| License       | MIT

Third attempt after #54134 and #58999.. this is the good one 👍

I initially started this PR to learn / try things, but it really behaves well.. and _may_ stop (or help stopping) what seems to be a never-ending suite of special cases.

Open to any feedback

Commits
-------

720c387 [AssetMapper] Detect import with a sequence parser
@fabpot fabpot closed this Jan 25, 2025
@tacman tacman deleted the asset-mapper-multi-line-comments branch January 25, 2025 09:35
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.

api platform no longer installs seamlessly with Symfony
8 participants