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: __vite__mapDeps code injection #15732

Merged
merged 7 commits into from Feb 21, 2024
Merged

Conversation

hi-ogawa
Copy link
Collaborator

@hi-ogawa hi-ogawa commented Jan 28, 2024

Description

I copied and adjusted mapFileCommentRegex constant from https://github.com/thlorenz/convert-source-map/blob/1afbeee2f2a42a3747c31dfcfc355387afdf42e2/index.js#L14 so that it will only matches the last line of the source code. (EDIT: now prepending __vite__mapDeps at the top)

I manually verified that sourcemap is working via pnpm -C playground/js-sourcemap build + preview:

Show screenshot
2024-02-21.13-28-46.webm

Additional context


What is the purpose of this pull request?

  • Bug fix
  • New Feature
  • Documentation update
  • Other

Before submitting the PR, please make sure you do the following

  • Read the Contributing Guidelines, especially the Pull Request Guidelines.
  • Check that there isn't already a PR that solves the problem the same way to avoid creating a duplicate.
  • Provide a description in this PR that addresses what the PR is solving, or reference the issue that it solves (e.g. fixes #123).
  • Update the corresponding documentation if needed.
  • Ideally, include relevant tests that fail without this PR but pass with it.

Copy link

stackblitz bot commented Jan 28, 2024

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

@hi-ogawa hi-ogawa changed the title fix: fix __vite__mapDeps injected into a wrong position fix: inject __vite__mapDeps before the correct source map comment Jan 28, 2024
@hi-ogawa hi-ogawa changed the title fix: inject __vite__mapDeps before the correct source map comment fix: inject __vite__mapDeps before the source map comment at the end Jan 28, 2024
@hi-ogawa hi-ogawa marked this pull request as ready for review January 28, 2024 05:05
@hi-ogawa hi-ogawa changed the title fix: inject __vite__mapDeps before the source map comment at the end fix: inject __vite__mapDeps before the source map comment at the last line Jan 28, 2024
Copy link
Collaborator Author

@hi-ogawa hi-ogawa left a comment

Choose a reason for hiding this comment

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

Related to the fact that mapFileCommentRegex matches anywhere in the file, I noticed that sourcemap: "inline" currently removes such string in the code as well:

if (config.build.sourcemap === 'inline') {
chunk.code = chunk.code.replace(
convertSourceMap.mapFileCommentRegex,
'',
)
chunk.code += `\n//# sourceMappingURL=${genSourceMapUrl(map)}`

For example:

// input
console.log(`
this is string literal
//# sourceMappingURL=1.css.map
`)

// output
console.log(`
this is string literal

`)

I suppose we can handle this issue separately?
(Probably the fix is as simple as hi-ogawa#1, but I didn't find a relevant test, so I'll try to come up with that separately)

packages/vite/src/node/plugins/importAnalysisBuild.ts Outdated Show resolved Hide resolved
@@ -41,6 +41,12 @@ const preloadMarkerWithQuote = new RegExp(`['"]${preloadMarker}['"]`, 'g')

const dynamicImportPrefixRE = /import\s*\(/

// modified convert-source-map's `mapFileCommentRegex` to match only at the last line
Copy link
Member

Choose a reason for hiding this comment

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

mapFileCommentRegex to match only at the last line

This is correct for codes generated by Rollup itself. However, a plugin may inject a source map comment between some codes or that doesn't match this regex (e.g. /* sourceMappingURL=validURL *//* sourceMappingMeta={"foo":"bar"} */).
This is not allowed by the spec (although what "at the end of the source" means is not strictly defined). That said, it's supported by many runtimes (tc39/source-map#64) and I guess it's better to avoid making this assumption.

In this case, how about prepending mapDepsCode instead of appending it? We need to deal with the Hashbang Grammar but that's not so hard.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

In this case, how about prepending mapDepsCode instead of appending it? We need to deal with the Hashbang Grammar but that's not so hard.

Thanks for the review!
Right, I was also wondering about prepending it. I think I was worrying about hashbang as well, but probably prepending would be more straight forward overall. Let me try.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I updated a PR to prepend the code 7e714e1

The test case looks rather artificial but I (manually) confirmed that it covers a new code path and also sourcemap works for this case.

@hi-ogawa hi-ogawa changed the title fix: inject __vite__mapDeps before the source map comment at the last line fix: fix __vite__mapDeps code injection for sourcemap Feb 21, 2024
@hi-ogawa hi-ogawa changed the title fix: fix __vite__mapDeps code injection for sourcemap fix: fix __vite__mapDeps code injection Feb 21, 2024
Comment on lines +22 to +25
banner(chunk) {
if (chunk.name.endsWith('after-preload-dynamic-hashbang')) {
return '#!/usr/bin/env node'
}
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I used banner to inject hashbang and test this case since having #! ... inside after-preload-dynamic-hashbang.js seems to cause a parse error somewhere in the pipeline. The error looks like this:

$ pnpm -C playground/js-sourcemap build

> @vitejs/test-js-sourcemap@0.0.0 build /home/hiroshi/code/others/vite/playground/js-sourcemap
> vite build

vite v5.1.3 building for production...
✓ 7 modules transformed.
x Build failed in 56ms
error during build:
RollupError: Expected ident
    at error (file:///home/hiroshi/code/others/vite/node_modules/.pnpm/rollup@4.2.0/node_modules/rollup/dist/es/shared/parseAst.js:337:30)
    at nodeConverters (file:///home/hiroshi/code/others/vite/node_modules/.pnpm/rollup@4.2.0/node_modules/rollup/dist/es/shared/parseAst.js:2072:9)
    at convertNode (file:///home/hiroshi/code/others/vite/node_modules/.pnpm/rollup@4.2.0/node_modules/rollup/dist/es/shared/parseAst.js:957:12)
    at convertProgram (file:///home/hiroshi/code/others/vite/node_modules/.pnpm/rollup@4.2.0/node_modules/rollup/dist/es/shared/parseAst.js:948:48)
    at parseAstAsync (file:///home/hiroshi/code/others/vite/node_modules/.pnpm/rollup@4.2.0/node_modules/rollup/dist/es/shared/parseAst.js:2138:20)
    at Module.tryParseAsync (file:///home/hiroshi/code/others/vite/node_modules/.pnpm/rollup@4.2.0/node_modules/rollup/dist/es/shared/node-entry.js:13357:21)
    at Module.setSource (file:///home/hiroshi/code/others/vite/node_modules/.pnpm/rollup@4.2.0/node_modules/rollup/dist/es/shared/node-entry.js:12953:35)
    at ModuleLoader.addModuleSource (file:///home/hiroshi/code/others/vite/node_modules/.pnpm/rollup@4.2.0/node_modules/rollup/dist/es/shared/node-entry.js:17580:13)
 ELIFECYCLE  Command failed with exit code 1.

@@ -41,6 +41,12 @@ const preloadMarkerWithQuote = new RegExp(`['"]${preloadMarker}['"]`, 'g')

const dynamicImportPrefixRE = /import\s*\(/

// modified convert-source-map's `mapFileCommentRegex` to match only at the last line
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I updated a PR to prepend the code 7e714e1

The test case looks rather artificial but I (manually) confirmed that it covers a new code path and also sourcemap works for this case.

@sapphi-red sapphi-red added p3-minor-bug An edge case that only affects very specific usage (priority) regression The issue only appears after a new release labels Feb 21, 2024
Copy link
Member

@sapphi-red sapphi-red left a comment

Choose a reason for hiding this comment

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

Thanks!

@patak-dev
Copy link
Member

/ecosystem-ci run

@vite-ecosystem-ci
Copy link

📝 Ran ecosystem CI on 3e7e896: Open

suite result latest scheduled
analogjs success success
astro success success
histoire success success
ladle success success
laravel success success
marko success success
nuxt success success
nx failure failure
previewjs success success
qwik success success
rakkas success success
sveltekit success success
unocss success success
vike success success
vite-plugin-pwa success success
vite-plugin-react success success
vite-plugin-react-pages success success
vite-plugin-react-swc success success
vite-plugin-svelte success success
vite-plugin-vue success success
vite-setup-catalogue success success
vitepress success success
vitest success success

@patak-dev patak-dev changed the title fix: fix __vite__mapDeps code injection fix: __vite__mapDeps code injection Feb 21, 2024
Copy link
Member

@bluwy bluwy left a comment

Choose a reason for hiding this comment

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

LGTM! I also prefer the prepend approach

@bluwy bluwy merged commit aff54e1 into vitejs:main Feb 21, 2024
14 checks passed
} else {
s.append(mapDepsCode)
s.prepend(mapDepsCode)
Copy link

@lisonge lisonge Mar 24, 2024

Choose a reason for hiding this comment

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

if fileDeps.length == 0, maybe we do not need exec s.prependLeft or prepend

because sometimes __vite__mapDeps is not used

image

I can't find how to remove the configuration of __vite__mapDeps

Copy link
Member

Choose a reason for hiding this comment

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

We can use [] instead of __vite__mapDeps([${renderedDeps.join(',')}]) if renderedDeps.length is 0. Then, we can skip injecting __vite__mapDeps. Contributions are welcome 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
p3-minor-bug An edge case that only affects very specific usage (priority) regression The issue only appears after a new release
Projects
None yet
Development

Successfully merging this pull request may close these issues.

__vite__mapDeps is not defined
5 participants