Skip to content
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

fix(svelte): Track components without <script> tags #5957

Merged
merged 4 commits into from Oct 14, 2022

Conversation

Lms24
Copy link
Member

@Lms24 Lms24 commented Oct 14, 2022

This PR makes our Svelte component tracking feature track components without <script> tags. Previously these components would not be picked up by our preprocessor because its script hook is only called for components with script blocks. With this PR, we first leverage the markup hook to check if a script block exists. If it doesn't, we add an empty script tag which we later revisit in the script hook where we inject the component tracking code.

Note: To determine if a script tag exists in the file, we use a regex check which has drawbacks, as it is not 100% bullet proof. However, we decided that for the lack of better options as explained in #5923(comment) we'll go with this approach for now. Also, the svelte compiler internally uses the same regex to detect <script> tags.

This PR adds additional tests to check the new behaviour (brings up preprocessor coverage to 100%)

ref: #5923

function hasScriptTag(content: string): boolean {
// This regex is taken from the Svelte compiler code.
// They use this regex to find matching script tags that are passed to the `script` preprocessor hook:
// https://github.com/sveltejs/svelte/blob/bb83eddfc623437528f24e9fe210885b446e72fa/src/compiler/preprocess/index.ts#L144
Copy link
Member

Choose a reason for hiding this comment

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

Just out of curiosity: Do you know why they have multiline comments like that in their regex?

Copy link
Member Author

@Lms24 Lms24 Oct 14, 2022

Choose a reason for hiding this comment

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

I was also wondering about that. Traced it back yesterday to a commit saying that this helps them actually getting rid of comments later on. I didn't reach a point where I was entirely convinced but i suspect that it has something to do with how they process the "replacements" they identify, leading them to do nothing if there is nothing to preprocess here

// However, we remove the first part of the regex to not match HTML comments
const scriptTagRegex = /<script(\s[^]*?)?(?:>([^]*?)<\/script>|\/>)/gi;

// Regex testing is not a super safe way of checking for the presence of a <script> tag in the Svelte
Copy link
Member

Choose a reason for hiding this comment

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

I agree this is a bit sketchy. Non blocking but have you looked at import { parse } from 'svelte/compiler'; if it outputs something we could use that is a little bit more robust?

Copy link
Member Author

Choose a reason for hiding this comment

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

I was just thinking about that too on my way to the train (apparently, walking really helps some time 😅). Will take a look and see if anything comes out of it

Copy link
Member Author

Choose a reason for hiding this comment

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

Seems much more elegant and safer to use svelte's parser. Changed it in 31f1c52.

Copy link
Member

Choose a reason for hiding this comment

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

Amazing. Super clean!

@github-actions
Copy link
Contributor

size-limit report 📦

Path Size
@sentry/browser - ES5 CDN Bundle (gzipped + minified) 19.42 KB (+0.03% 🔺)
@sentry/browser - ES5 CDN Bundle (minified) 60.09 KB (0%)
@sentry/browser - ES6 CDN Bundle (gzipped + minified) 18.04 KB (0%)
@sentry/browser - ES6 CDN Bundle (minified) 52.97 KB (0%)
@sentry/browser - Webpack (gzipped + minified) 19.77 KB (0%)
@sentry/browser - Webpack (minified) 64.28 KB (0%)
@sentry/react - Webpack (gzipped + minified) 19.79 KB (0%)
@sentry/nextjs Client - Webpack (gzipped + minified) 45.52 KB (0%)
@sentry/browser + @sentry/tracing - ES5 CDN Bundle (gzipped + minified) 25.86 KB (+0.01% 🔺)
@sentry/browser + @sentry/tracing - ES6 CDN Bundle (gzipped + minified) 24.28 KB (0%)

@Lms24 Lms24 enabled auto-merge (squash) October 14, 2022 09:35
@Lms24 Lms24 disabled auto-merge October 14, 2022 09:38
@Lms24 Lms24 force-pushed the lms-fix-svelte-no-script-components-ii branch from 31f1c52 to ed12846 Compare October 14, 2022 11:24
// They use this regex to find matching script tags that are passed to the `script` preprocessor hook:
// https://github.com/sveltejs/svelte/blob/bb83eddfc623437528f24e9fe210885b446e72fa/src/compiler/preprocess/index.ts#L144
// However, we remove the first part of the regex to not match HTML comments
const scriptTagRegex = /<script(\s[^]*?)?(?:>([^]*?)<\/script\s*>|\/>)/gi;

Check failure

Code scanning / CodeQL

Bad HTML filtering regexp

This regular expression does not match script end tags like </script\t\n bar>.
@Lms24
Copy link
Member Author

Lms24 commented Oct 14, 2022

For future readers: Using Svelte's parse functionality didn't work. The problem was that Svelte's parser only parses JS but not typescript, meaning that scripts written in TS (<script lang="ts">) would lead to parsing errors.

This is by design, as Svelte provides an official preprocessor to transpile TS to JS before the .svelte file is parsed. Similarly to our 2-pass approach though, we can't rely on this preprocessor because for TS->JS transpilation, it uses the script hook. This means that our preprocessor's markup hook is executed before the transpilation, regardless of the preprocessor order.

Therefore, we'll revert back to the regex approach.

Last solution: Use a 3rd party library for parsing the entire *.svelte file as HTML and check if a valid top-level <script> tag exists. We'll explore this, if the regex approach causes problems.

Copy link
Member

@AbhiPrasad AbhiPrasad left a comment

Choose a reason for hiding this comment

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

I’m fine with this approach, and I think we learned a lot from it. Should be useful when we look at SvelteKit in the future.

@Lms24 Lms24 merged commit 9c66c39 into master Oct 14, 2022
@Lms24 Lms24 deleted the lms-fix-svelte-no-script-components-ii branch October 14, 2022 12:09
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.

None yet

3 participants