Skip to content

Commit

Permalink
feat(sourcemaps): Automatically insert Sentry Webpack plugin (#432)
Browse files Browse the repository at this point in the history
Add automatic Webpack plugin insertion to the sourcemaps wizard's webpack flow. Behaviour of when to modify or create a new file is identical with vite flow, similarly, when we shoud fallback copy/paste instructions.

More details in PR

Co-authored-by: Luca Forstner <[email protected]>
  • Loading branch information
Lms24 and lforst authored Sep 12, 2023
1 parent 523b7fa commit 8eae847
Show file tree
Hide file tree
Showing 9 changed files with 1,038 additions and 136 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changelog

## Unreleased

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

## 3.11.0

- feat(android): Add wizard support for Android (#389)
Expand Down
110 changes: 22 additions & 88 deletions src/sourcemaps/tools/vite.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,11 @@ import chalk from 'chalk';
import {
abortIfCancelled,
addDotEnvSentryBuildPluginFile,
askForToolConfigPath,
createNewConfigFile,
getPackageDotJson,
installPackage,
showCopyPasteInstructions,
} from '../../utils/clack-utils';
import { hasPackageInstalled } from '../../utils/package-json';

Expand Down Expand Up @@ -91,58 +94,43 @@ export const configureVitePlugin: SourceMapUploadToolConfigurationFunction =
});

const viteConfigPath =
findFile(path.resolve(process.cwd(), 'vite.config')) ||
(await askForViteConfigPath());
findFile(path.resolve(process.cwd(), 'vite.config')) ??
(await askForToolConfigPath('Vite', 'vite.config.js'));

let successfullyAdded = false;
if (viteConfigPath) {
successfullyAdded = await addVitePluginToConfig(viteConfigPath, options);
} else {
successfullyAdded = await createNewViteConfig(options);
successfullyAdded = await createNewConfigFile(
path.join(process.cwd(), 'vite.config.js'),
getViteConfigSnippet(options, false),
'More information about vite configs: https://vitejs.dev/config/',
);
Sentry.setTag(
'created-new-config',
successfullyAdded ? 'success' : 'fail',
);
}

if (successfullyAdded) {
clack.log.info(
`We recommend checking the ${
viteConfigPath ? 'modified' : 'added'
} file after the wizard finished to ensure it works with your build setup.`,
);

Sentry.setTag('ast-mod', 'success');
} else {
Sentry.setTag('ast-mod', 'fail');
await showCopyPasteInstructions(
path.basename(viteConfigPath || 'vite.config.js'),
options,
getViteConfigSnippet(options, true),
);
}

await addDotEnvSentryBuildPluginFile(options.authToken);
};

async function createNewViteConfig(
options: SourceMapUploadToolConfigurationOptions,
): Promise<boolean> {
try {
await fs.promises.writeFile(
'vite.config.js',
getViteConfigSnippet(options, false),
);
Sentry.setTag('created-new-config', 'success');
return true;
} catch (e) {
debug(e);
Sentry.setTag('created-new-config', 'fail');
clack.log.warn(
`Could not create a new ${chalk.cyan(
'vite.config.js',
)} file. Please create one manually and follow the instructions below.`,
);

clack.log.info(
chalk.gray(
'More information about vite configs: https://vitejs.dev/config/',
),
);

return false;
}
}

export async function addVitePluginToConfig(
viteConfigPath: string,
options: SourceMapUploadToolConfigurationOptions,
Expand All @@ -156,7 +144,7 @@ export async function addVitePluginToConfig(

const mod = parseModule(viteConfigContent);

if (hasSentryContent(mod)) {
if (hasSentryContent(mod.$ast as t.Program)) {
const shouldContinue = await abortIfCancelled(
clack.select({
message: `${prettyViteConfigFilename} already contains Sentry-related code. Should the wizard modify it anyway?`,
Expand Down Expand Up @@ -215,60 +203,6 @@ export async function addVitePluginToConfig(
}
}

async function showCopyPasteInstructions(
viteConfigFilename: string,
options: SourceMapUploadToolConfigurationOptions,
) {
clack.log.step(
`Add the following code to your ${chalk.cyan(viteConfigFilename)} file:`,
);

// Intentionally logging directly to console here so that the code can be copied/pasted directly
// eslint-disable-next-line no-console
console.log(`\n${getViteConfigSnippet(options, true)}`);

await abortIfCancelled(
clack.select({
message: 'Did you copy the snippet above?',
options: [{ label: 'Yes, continue!', value: true }],
initialValue: true,
}),
);
}

async function askForViteConfigPath(): Promise<string | undefined> {
const hasViteConfig = await abortIfCancelled(
clack.confirm({
message: `Do you have a vite config file (e.g. ${chalk.cyan(
'vite.config.js',
)}?`,
initialValue: true,
}),
);

if (!hasViteConfig) {
return undefined;
}

return await abortIfCancelled(
clack.text({
message: 'Please enter the path to your vite config file:',
placeholder: `.${path.sep}vite.config.js`,
validate: (value) => {
if (!value) {
return 'Please enter a path.';
}

try {
fs.accessSync(value);
} catch {
return 'Could not access the file at this path.';
}
},
}),
);
}

function enableSourcemapGeneration(program: t.Program): boolean {
const configObj = getViteConfigObject(program);

Expand Down
Loading

0 comments on commit 8eae847

Please sign in to comment.