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

feat(sourcemaps): Automatically insert Sentry Webpack plugin #432

Merged
merged 4 commits into from
Sep 12, 2023

Conversation

Lms24
Copy link
Member

@Lms24 Lms24 commented Sep 7, 2023

This PR adds automatic Webpack plugin insertion to the sourcemaps wizard's webpack flow.

This changes the webpack flow from always showing copy/paste instructions to:

  • check if a webpack config exists
    • if not automatically found, ask if users have one
      • if not, create a new webpack config with the Sentry related code
      • if yes, ask them to enter the path to their config
  • modify existing config
    • add require call for webpack plugin
    • enable source map generation
    • insert the plugin
  • if any if these processes fail, we fall back to showing the copy/paste instructions

Because this is the second time that we're adding auto insertion I took the opportunity to extract some common helper functions which we can reuse in both flows and to finally add some tests. I mainly concentrated on testing important AST modifications and helper functions as these are the most critical parts of the flow.

This PR only handles CJS webpack configs at the moment. We can add ESM support later on, shouldn't be too much work. However, I'd argue that CJS is probably the most common config form.

closes #418

@github-actions
Copy link

github-actions bot commented Sep 7, 2023

Messages
📖 Do not forget to update Sentry-docs with your feature once the pull request gets approved.

Generated by 🚫 dangerJS against 2f4035c

* and showing unchanged lines in gray.
*
* TODO: Link to wizard spec (develop) once it is live
* TODO: refactor copy paste instructions across different wizards to use this function.
Copy link
Member Author

Choose a reason for hiding this comment

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

will do this in a follow-up PR as this one is already (too) big

@Lms24 Lms24 requested review from lforst and mydea September 7, 2023 16:35
Copy link
Member

@lforst lforst left a comment

Choose a reason for hiding this comment

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

I have a few thoughts but nothing majorly blocking. In any case: nice job!

Comment on lines 163 to 166
clack.log.warn(
`Could not find module.exports = { /* config */ } in ${prettyConfigFilename}.
This is fine, please follow the instructions below.`,
);
Copy link
Member

Choose a reason for hiding this comment

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

l/m: I don't think we should show this log message (or any of the log messages that we couldn't find something in the AST) and I think we should just go for the fallback without saying anything. Will people care about these messages? Otherwise, they're just noise. Wdyt? (we should still do telemetry tho)

Copy link
Member Author

Choose a reason for hiding this comment

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

Fair, I agree, it's a little too verbose here. I'll replace it with a debug call. Might still be useful to keep this around for future debugging.

`Could not find module.exports = { /* config */ } in ${prettyConfigFilename}.
This is fine, please follow the instructions below.`,
);
return false;
Copy link
Member

Choose a reason for hiding this comment

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

m: I think we should set a tag for "ast-mod-fail-reason" here.

Comment on lines +121 to +124
export async function modifyWebpackConfig(
webpackConfigPath: string,
options: SourceMapUploadToolConfigurationOptions,
): Promise<boolean> {
Copy link
Member

Choose a reason for hiding this comment

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

l: Do you think it would make sense to split this function into shouldModifyWebpackConfig(): boolean and modifyWebpackConfig(): void?

Sentry.setTag('ast-mod', 'success');
} else {
Sentry.setTag('ast-mod', 'fail');
await showCopyPasteInstructions(
Copy link
Member

Choose a reason for hiding this comment

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

man I really like these utilities we got going here!

try {
await fs.promises.writeFile(filepath, codeSnippet);

Sentry.setTag('created-new-config', 'success');
Copy link
Member

Choose a reason for hiding this comment

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

m: I am wondering if these tags make sense in the case we create multiple configs inside one wizard run but maybe this is a "future us" problem.

Copy link
Member Author

@Lms24 Lms24 Sep 8, 2023

Choose a reason for hiding this comment

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

Hmm that's a good point. Right now, we only call it once but lemme refactor this to take out the tags setting and add to the docs that the function caller is responsible for setting tags.

* @returns true on sucess, false otherwise
*/
export async function createNewConfigFile(
filepath: string,
Copy link
Member

Choose a reason for hiding this comment

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

l/m: I am always wondering if we should be very specific here and say we only take an absPath. Otherwise it's always a bit of guessing what you should provide and where the file will end up.

If we require an abs path we could also always print the filepath in the "relative from cwd" format.

Copy link
Member Author

Choose a reason for hiding this comment

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

Good call, at least for this helper that actually writes to a file. I added a check and a test.

// eslint-disable-next-line no-console
console.log(getCodeSnippet(options));
const successfullyAdded = webpackConfigPath
? await modifyWebpackConfig(webpackConfigPath, options)
Copy link
Member

Choose a reason for hiding this comment

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

l/m: Should we log something along the lines of "Modified your config. Please double check whether it makes sense?" when we modified the config?

Copy link
Member Author

Choose a reason for hiding this comment

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

good idea. I think it makes sense in both cases (modified and added) because if we added a new file, users have to most likely adjust their current way of building.

(code) => {
expect(hasSentryContent(parseModule(code))).toBe(false);
},
);
});

describe('hasSentryContentCjs', () => {
Copy link
Member

Choose a reason for hiding this comment

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

l/m: Do you think it makes sense to think about the esm case? Maybe we can catch both by just looking for "@sentry/vite-plugin" in the file?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah, we can check for a (String)Literal starting with @sentry/. Tests seem to pass with this for esm and cjs. I'll change it.

test/utils/clack-utils.test.ts Outdated Show resolved Hide resolved
@Lms24 Lms24 merged commit 8eae847 into master Sep 12, 2023
9 checks passed
@Lms24 Lms24 deleted the lms/sourcemaps-feat-inject-webpack-config branch September 12, 2023 09:35
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.

Automatically insert plugin into Webpack config
2 participants