From 110600cc3c49f03aa1efc807d1c15212e1518e95 Mon Sep 17 00:00:00 2001 From: vaniasuveev Date: Mon, 5 Aug 2024 12:26:01 +0300 Subject: [PATCH 1/4] feat: implemented sentry generator --- plugin/generators.json | 5 + plugin/src/generators/sentry/enums/index.ts | 1 + .../generators/sentry/enums/technologies.ts | 4 + .../app/[locale]/global-error.tsx.template | 23 +++ .../files/sentry.client.config.ts.template | 23 +++ .../files/sentry.edge.config.ts.template | 13 ++ .../files/sentry.server.config.ts.template | 13 ++ plugin/src/generators/sentry/generator.ts | 142 ++++++++++++++++++ plugin/src/generators/sentry/schema.d.ts | 3 + plugin/src/generators/sentry/schema.json | 28 ++++ 10 files changed, 255 insertions(+) create mode 100644 plugin/src/generators/sentry/enums/index.ts create mode 100644 plugin/src/generators/sentry/enums/technologies.ts create mode 100644 plugin/src/generators/sentry/files/app/[locale]/global-error.tsx.template create mode 100644 plugin/src/generators/sentry/files/sentry.client.config.ts.template create mode 100644 plugin/src/generators/sentry/files/sentry.edge.config.ts.template create mode 100644 plugin/src/generators/sentry/files/sentry.server.config.ts.template create mode 100644 plugin/src/generators/sentry/generator.ts create mode 100644 plugin/src/generators/sentry/schema.d.ts create mode 100644 plugin/src/generators/sentry/schema.json diff --git a/plugin/generators.json b/plugin/generators.json index f1710db..0a82c3b 100644 --- a/plugin/generators.json +++ b/plugin/generators.json @@ -29,6 +29,11 @@ "factory": "./src/generators/react-component/generator", "schema": "./src/generators/react-component/schema.json", "description": "react-component generator" + }, + "sentry": { + "factory": "./src/generators/sentry/generator", + "schema": "./src/generators/sentry/schema.json", + "description": "sentry generator" } } } diff --git a/plugin/src/generators/sentry/enums/index.ts b/plugin/src/generators/sentry/enums/index.ts new file mode 100644 index 0000000..28be8dc --- /dev/null +++ b/plugin/src/generators/sentry/enums/index.ts @@ -0,0 +1 @@ +export * from './technologies'; \ No newline at end of file diff --git a/plugin/src/generators/sentry/enums/technologies.ts b/plugin/src/generators/sentry/enums/technologies.ts new file mode 100644 index 0000000..ac49219 --- /dev/null +++ b/plugin/src/generators/sentry/enums/technologies.ts @@ -0,0 +1,4 @@ +export enum Technology { + NEXT_JS = 'Next.js', + REACT_NATIVE = 'React Native', +} diff --git a/plugin/src/generators/sentry/files/app/[locale]/global-error.tsx.template b/plugin/src/generators/sentry/files/app/[locale]/global-error.tsx.template new file mode 100644 index 0000000..fbd1c3d --- /dev/null +++ b/plugin/src/generators/sentry/files/app/[locale]/global-error.tsx.template @@ -0,0 +1,23 @@ +'use client'; + +import * as Sentry from '@sentry/nextjs'; +import NextError from 'next/error'; +import { ReactElement, useEffect } from 'react'; + +interface GlobalErrorProps { + error: Error & { digest?: string }; +} + +export default function GlobalError({ error }: GlobalErrorProps): ReactElement { + useEffect(() => { + Sentry.captureException(error); + }, [error]); + + return ( + + + + + + ); +} diff --git a/plugin/src/generators/sentry/files/sentry.client.config.ts.template b/plugin/src/generators/sentry/files/sentry.client.config.ts.template new file mode 100644 index 0000000..fa2eada --- /dev/null +++ b/plugin/src/generators/sentry/files/sentry.client.config.ts.template @@ -0,0 +1,23 @@ +import * as Sentry from '@sentry/nextjs'; + +Sentry.init({ + // TODO replace with your DSN + dsn: '', + + // Adjust this value in production, or use tracesSampler for greater control + tracesSampleRate: 1, + + debug: false, + replaysOnErrorSampleRate: 1.0, + + // This sets the sample rate to be 10%. You may want this to be 100% while + // in development and sample at a lower rate in production + replaysSessionSampleRate: 0.1, + + // You can remove this option if you're not planning to use the Sentry Session Replay feature: + integrations: [ + Sentry.replayIntegration(), + Sentry.inboundFiltersIntegration(), + ], + denyUrls: ['localhost'], +}); diff --git a/plugin/src/generators/sentry/files/sentry.edge.config.ts.template b/plugin/src/generators/sentry/files/sentry.edge.config.ts.template new file mode 100644 index 0000000..6e7d221 --- /dev/null +++ b/plugin/src/generators/sentry/files/sentry.edge.config.ts.template @@ -0,0 +1,13 @@ +import * as Sentry from '@sentry/nextjs'; + +Sentry.init({ + // TODO replace with your DSN + dsn: '', + + // Adjust this value in production, or use tracesSampler for greater control + tracesSampleRate: 1, + + debug: false, + integrations: [Sentry.inboundFiltersIntegration()], + denyUrls: ['localhost'] +}); diff --git a/plugin/src/generators/sentry/files/sentry.server.config.ts.template b/plugin/src/generators/sentry/files/sentry.server.config.ts.template new file mode 100644 index 0000000..38a4824 --- /dev/null +++ b/plugin/src/generators/sentry/files/sentry.server.config.ts.template @@ -0,0 +1,13 @@ +import * as Sentry from '@sentry/nextjs'; + +Sentry.init({ + // TODO replace with your DSN + dsn: '', + + // Adjust this value in production, or use tracesSampler for greater control + tracesSampleRate: 1, + + debug: false, + integrations: [Sentry.inboundFiltersIntegration()], + denyUrls: ['localhost'], +}); diff --git a/plugin/src/generators/sentry/generator.ts b/plugin/src/generators/sentry/generator.ts new file mode 100644 index 0000000..89fb538 --- /dev/null +++ b/plugin/src/generators/sentry/generator.ts @@ -0,0 +1,142 @@ +import { + addDependenciesToPackageJson, + formatFiles, + generateFiles, + Tree, +} from '@nx/devkit'; +import * as path from 'path'; +import { SentryGeneratorSchema } from './schema'; +import { Technology } from './enums'; + +const webDependencies = { + '@sentry/nextjs': '^8.21.0', +}; + +const mobileDependencies = { + '@sentry/react-native': '~5.22.0', +}; + +export async function sentryGenerator( + tree: Tree, + options: SentryGeneratorSchema, +) { + const projectRoot = `apps/${options.directory}`; + + if (options.technology === Technology.NEXT_JS) { + addDependenciesToPackageJson(tree, webDependencies, {}); + + const nextConfigContent = tree + .read(`apps/${options.directory}/next.config.js`) + .toString() + .replace( + /^const { withNx } = require\('@nrwl\/next\/plugins\/with-nx'\);$/gm, + `const { withSentryConfig } = require("@sentry/nextjs"); + const { withNx } = require('@nrwl/next/plugins/with-nx');`, + ) + .replace( + /^const nextConfig = {/gm, + `const nextConfig = { + sentry: { + // Upload a larger set of source maps for prettier stack traces (increases build time) + widenClientFileUpload: true, + + // Transpiles SDK to be compatible with IE11 (increases bundle size) + transpileClientSDK: true, + + // Routes browser requests to Sentry through a Next.js rewrite to circumvent ad-blockers (increases server load) + tunnelRoute: '/monitoring', + + // Hides source maps from generated client bundles + hideSourceMaps: true, + + // Automatically tree-shake Sentry logger statements to reduce bundle size + disableLogger: true + }, + `, + ) + .replace( + /\(nextConfig\)/gm, + `(withSentryConfig(nextConfig, sentryWebpackPluginOptions))`, + ); + + tree.write( + `apps/${options.directory}/next.config.js`, + nextConfigContent + + ` + /** + * @type {import('@sentry/nextjs').SentryWebpackPluginOptions} + **/ + + const sentryWebpackPluginOptions = { + silent: true, + org: '', + project: 'web-next-js-client', + authToken: process.env.SENTRY_AUTH_TOKEN, + }; + + `, + ); + + const envFiles = ['.env', '.env.development', '.env.production']; + envFiles.forEach((file) => { + const envContent = tree + .read(`apps/${options.directory}/${file}`) + .toString(); + tree.write( + `apps/${options.directory}/${file}`, + envContent + 'SENTRY_AUTH_TOKEN=', + ); + }); + + generateFiles(tree, path.join(__dirname, 'files'), projectRoot, options); + } else if (options.technology === Technology.REACT_NATIVE) { + addDependenciesToPackageJson(tree, mobileDependencies, {}); + + const layoutContent = tree + .read(`apps/${options.directory}/app/_layout.tsx`) + .toString() + .replace( + /^import { Stack } from 'expo-router';$/gm, + `import { Stack } from 'expo-router';import * as Sentry from "@sentry/react-native";import Constants from "expo-constants";`, + ) + .replace(/^export default function RootLayout/gm, `function RootLayout`); + + tree.write( + `apps/${options.directory}/app/_layout.tsx`, + layoutContent + + ` + const routingInstrumentation = new Sentry.ReactNavigationInstrumentation(); + + Sentry.init({ + dsn: Constants.expoConfig?.extra?.sentry?.dsn, + environment: Constants.expoConfig?.extra?.env, + debug: false, + integrations: [new Sentry.ReactNativeTracing({ routingInstrumentation })], + enabled: !__DEV__ + }); + + export default Sentry.wrap(RootLayout);`, + ); + + const appConfigContent = tree + .read(`apps/${options.directory}/app.config.ts`) + .toString() + .replace( + /plugins: \[/g, + `plugins: [ [ + '@sentry/react-native/expo', + { + // TODO Update organization and project name + organization: '', + project: '' + } + ],`, + ); + + tree.write(`apps/${options.directory}/app.config.ts`, appConfigContent); + } + + await formatFiles(tree); +} + +export default sentryGenerator; diff --git a/plugin/src/generators/sentry/schema.d.ts b/plugin/src/generators/sentry/schema.d.ts new file mode 100644 index 0000000..5ef0af3 --- /dev/null +++ b/plugin/src/generators/sentry/schema.d.ts @@ -0,0 +1,3 @@ +export interface SentryGeneratorSchema { + name: string; +} diff --git a/plugin/src/generators/sentry/schema.json b/plugin/src/generators/sentry/schema.json new file mode 100644 index 0000000..0eecdc9 --- /dev/null +++ b/plugin/src/generators/sentry/schema.json @@ -0,0 +1,28 @@ +{ + "$schema": "https://json-schema.org/schema", + "$id": "Sentry", + "title": "", + "type": "object", + "properties": { + "directory": { + "type": "string", + "description": "", + "$default": { + "$source": "argv", + "index": 0 + }, + "x-prompt": "Enter the name of the directory in the 'apps/' folder (e.g: web)" + }, + "technology": { + "type": "string", + "description": "What technology is used in your project?", + "$default": { + "$source": "argv", + "index": 1 + }, + "enum": ["Next.js", "React Native"], + "x-prompt": "What technology is used in your project?" + } + }, + "required": ["directory", "technology"] +} From 99b7a5f44a9fd93f84b1a055837cf3f1fea0c847 Mon Sep 17 00:00:00 2001 From: vaniasuveev Date: Thu, 8 Aug 2024 10:48:02 +0300 Subject: [PATCH 2/4] feat: updated expo-app and next-app generators --- plugin/src/generators/expo-app/generator.ts | 13 +++++++--- plugin/src/generators/expo-app/schema.json | 7 ++++- plugin/src/generators/next-app/generator.ts | 5 ++++ plugin/src/generators/next-app/schema.json | 7 ++++- plugin/src/generators/sentry/enums/index.ts | 1 - .../generators/sentry/enums/technologies.ts | 4 --- plugin/src/generators/sentry/generator.ts | 26 +++++++------------ plugin/src/generators/sentry/schema.json | 12 +-------- 8 files changed, 37 insertions(+), 38 deletions(-) delete mode 100644 plugin/src/generators/sentry/enums/index.ts delete mode 100644 plugin/src/generators/sentry/enums/technologies.ts diff --git a/plugin/src/generators/expo-app/generator.ts b/plugin/src/generators/expo-app/generator.ts index 534fcdb..b99e1a1 100644 --- a/plugin/src/generators/expo-app/generator.ts +++ b/plugin/src/generators/expo-app/generator.ts @@ -13,6 +13,7 @@ import { ExpoAppGeneratorSchema } from './schema'; import scripts from './scripts'; import { existsSync, rmSync } from 'fs'; import { formatName, formatAppIdentifier } from '../../shared/utils'; +import sentryGenerator from '../sentry/generator'; const dependencies = { 'expo-constants': '~16.0.2', @@ -27,18 +28,18 @@ const dependencies = { export async function expoAppGenerator( tree: Tree, - options: ExpoAppGeneratorSchema + options: ExpoAppGeneratorSchema, ) { const appRoot = `apps/${options.directory}`; const appTestFolder = `apps/${options.directory}-e2e`; // Install @nx/expo plugin - execSync('npx nx add @nx/expo', { stdio: 'inherit' }) + execSync('npx nx add @nx/expo', { stdio: 'inherit' }); if (!existsSync(appRoot)) { execSync( `npx nx g @nx/expo:app ${options.name} --directory=apps/${options.directory} --projectNameAndRootFormat=as-provided --unitTestRunner=none --e2eTestRunner=none`, - { stdio: 'inherit' } + { stdio: 'inherit' }, ); } @@ -83,13 +84,17 @@ export async function expoAppGenerator( // https://github.com/kristerkari/react-native-svg-transformer/issues/329 'react-native-svg-transformer': '^1.4.0', }, - { 'cross-env': '^7.0.3' } + { 'cross-env': '^7.0.3' }, ); addDependenciesToPackageJson(tree, dependencies, {}, appPackagePath); await formatFiles(tree); + if (options.withSentry) { + await sentryGenerator(tree, options); + } + return () => { installPackagesTask(tree); execSync('npx expo install --fix', { stdio: 'inherit' }); diff --git a/plugin/src/generators/expo-app/schema.json b/plugin/src/generators/expo-app/schema.json index 4b4c67f..e39544a 100644 --- a/plugin/src/generators/expo-app/schema.json +++ b/plugin/src/generators/expo-app/schema.json @@ -21,7 +21,12 @@ "index": 1 }, "x-prompt": "Enter the name of the directory in the 'apps/' folder (e.g: mobile)" + }, + "withSentry": { + "type": "boolean", + "default": false, + "x-prompt": "Do you want to use sentry in your app?" } }, - "required": ["name", "directory"] + "required": ["name", "directory", "withSentry"] } diff --git a/plugin/src/generators/next-app/generator.ts b/plugin/src/generators/next-app/generator.ts index a098218..f5a3db5 100644 --- a/plugin/src/generators/next-app/generator.ts +++ b/plugin/src/generators/next-app/generator.ts @@ -12,6 +12,7 @@ import { NextAppGeneratorSchema } from './schema'; import { existsSync } from 'fs'; import { formatName } from '../../shared/utils'; import * as path from 'path'; +import sentryGenerator from '../sentry/generator'; const dependencies = { 'next-intl': '^3.17.2', @@ -63,6 +64,10 @@ export async function nextAppGenerator( await formatFiles(tree); + if (options.withSentry) { + await sentryGenerator(tree, options); + } + return () => { installPackagesTask(tree); }; diff --git a/plugin/src/generators/next-app/schema.json b/plugin/src/generators/next-app/schema.json index a385502..85bc36a 100644 --- a/plugin/src/generators/next-app/schema.json +++ b/plugin/src/generators/next-app/schema.json @@ -21,7 +21,12 @@ "index": 1 }, "x-prompt": "Enter the name of the directory in the 'apps/' folder (e.g: web)" + }, + "withSentry": { + "type": "boolean", + "default": false, + "x-prompt": "Do you want to use sentry in your app?" } }, - "required": ["name", "directory"] + "required": ["name", "directory", "withSentry"] } diff --git a/plugin/src/generators/sentry/enums/index.ts b/plugin/src/generators/sentry/enums/index.ts deleted file mode 100644 index 28be8dc..0000000 --- a/plugin/src/generators/sentry/enums/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './technologies'; \ No newline at end of file diff --git a/plugin/src/generators/sentry/enums/technologies.ts b/plugin/src/generators/sentry/enums/technologies.ts deleted file mode 100644 index ac49219..0000000 --- a/plugin/src/generators/sentry/enums/technologies.ts +++ /dev/null @@ -1,4 +0,0 @@ -export enum Technology { - NEXT_JS = 'Next.js', - REACT_NATIVE = 'React Native', -} diff --git a/plugin/src/generators/sentry/generator.ts b/plugin/src/generators/sentry/generator.ts index 89fb538..de2d51b 100644 --- a/plugin/src/generators/sentry/generator.ts +++ b/plugin/src/generators/sentry/generator.ts @@ -6,7 +6,6 @@ import { } from '@nx/devkit'; import * as path from 'path'; import { SentryGeneratorSchema } from './schema'; -import { Technology } from './enums'; const webDependencies = { '@sentry/nextjs': '^8.21.0', @@ -22,11 +21,11 @@ export async function sentryGenerator( ) { const projectRoot = `apps/${options.directory}`; - if (options.technology === Technology.NEXT_JS) { + if (tree.exists(`${projectRoot}/next.config.js`)) { addDependenciesToPackageJson(tree, webDependencies, {}); const nextConfigContent = tree - .read(`apps/${options.directory}/next.config.js`) + .read(`${projectRoot}/next.config.js`) .toString() .replace( /^const { withNx } = require\('@nrwl\/next\/plugins\/with-nx'\);$/gm, @@ -60,7 +59,7 @@ export async function sentryGenerator( ); tree.write( - `apps/${options.directory}/next.config.js`, + `${projectRoot}/next.config.js`, nextConfigContent + ` /** @@ -79,21 +78,16 @@ export async function sentryGenerator( const envFiles = ['.env', '.env.development', '.env.production']; envFiles.forEach((file) => { - const envContent = tree - .read(`apps/${options.directory}/${file}`) - .toString(); - tree.write( - `apps/${options.directory}/${file}`, - envContent + 'SENTRY_AUTH_TOKEN=', - ); + const envContent = tree.read(`${projectRoot}/${file}`).toString(); + tree.write(`${projectRoot}/${file}`, envContent + 'SENTRY_AUTH_TOKEN='); }); generateFiles(tree, path.join(__dirname, 'files'), projectRoot, options); - } else if (options.technology === Technology.REACT_NATIVE) { + } else if (tree.exists(`${projectRoot}/metro.config.js`)) { addDependenciesToPackageJson(tree, mobileDependencies, {}); const layoutContent = tree - .read(`apps/${options.directory}/app/_layout.tsx`) + .read(`${projectRoot}/app/_layout.tsx`) .toString() .replace( /^import { Stack } from 'expo-router';$/gm, @@ -102,7 +96,7 @@ export async function sentryGenerator( .replace(/^export default function RootLayout/gm, `function RootLayout`); tree.write( - `apps/${options.directory}/app/_layout.tsx`, + `${projectRoot}/app/_layout.tsx`, layoutContent + ` const routingInstrumentation = new Sentry.ReactNavigationInstrumentation(); @@ -119,7 +113,7 @@ export async function sentryGenerator( ); const appConfigContent = tree - .read(`apps/${options.directory}/app.config.ts`) + .read(`${projectRoot}/app.config.ts`) .toString() .replace( /plugins: \[/g, @@ -133,7 +127,7 @@ export async function sentryGenerator( ],`, ); - tree.write(`apps/${options.directory}/app.config.ts`, appConfigContent); + tree.write(`${projectRoot}/app.config.ts`, appConfigContent); } await formatFiles(tree); diff --git a/plugin/src/generators/sentry/schema.json b/plugin/src/generators/sentry/schema.json index 0eecdc9..9693713 100644 --- a/plugin/src/generators/sentry/schema.json +++ b/plugin/src/generators/sentry/schema.json @@ -12,17 +12,7 @@ "index": 0 }, "x-prompt": "Enter the name of the directory in the 'apps/' folder (e.g: web)" - }, - "technology": { - "type": "string", - "description": "What technology is used in your project?", - "$default": { - "$source": "argv", - "index": 1 - }, - "enum": ["Next.js", "React Native"], - "x-prompt": "What technology is used in your project?" } }, - "required": ["directory", "technology"] + "required": ["directory"] } From d7b763318530a1ccc6377361bc23cf5120450425 Mon Sep 17 00:00:00 2001 From: vaniasuveev Date: Mon, 26 Aug 2024 14:21:59 +0300 Subject: [PATCH 3/4] refactor: refactored sentry generator --- plugin/src/generators/expo-app/schema.json | 5 +++++ plugin/src/generators/next-app/schema.json | 5 +++++ .../sentry/files/sentry.client.config.ts.template | 3 +-- .../sentry/files/sentry.edge.config.ts.template | 3 +-- .../sentry/files/sentry.server.config.ts.template | 3 +-- plugin/src/generators/sentry/generator.ts | 13 +++++++------ plugin/src/generators/sentry/schema.json | 11 ++++++++++- plugin/src/shared/utils/index.ts | 2 ++ plugin/src/shared/utils/is-expo-app.ts | 5 +++++ plugin/src/shared/utils/is-next-app.ts | 5 +++++ 10 files changed, 42 insertions(+), 13 deletions(-) create mode 100644 plugin/src/shared/utils/is-expo-app.ts create mode 100644 plugin/src/shared/utils/is-next-app.ts diff --git a/plugin/src/generators/expo-app/schema.json b/plugin/src/generators/expo-app/schema.json index e39544a..d60acae 100644 --- a/plugin/src/generators/expo-app/schema.json +++ b/plugin/src/generators/expo-app/schema.json @@ -26,6 +26,11 @@ "type": "boolean", "default": false, "x-prompt": "Do you want to use sentry in your app?" + }, + "DSN": { + "type": "string", + "description": "", + "x-prompt": "Enter the DSN (skip if you do not use Sentry)" } }, "required": ["name", "directory", "withSentry"] diff --git a/plugin/src/generators/next-app/schema.json b/plugin/src/generators/next-app/schema.json index 85bc36a..438bc0e 100644 --- a/plugin/src/generators/next-app/schema.json +++ b/plugin/src/generators/next-app/schema.json @@ -26,6 +26,11 @@ "type": "boolean", "default": false, "x-prompt": "Do you want to use sentry in your app?" + }, + "DSN": { + "type": "string", + "description": "", + "x-prompt": "Enter the DSN (skip if you do not use Sentry)" } }, "required": ["name", "directory", "withSentry"] diff --git a/plugin/src/generators/sentry/files/sentry.client.config.ts.template b/plugin/src/generators/sentry/files/sentry.client.config.ts.template index fa2eada..cd3410d 100644 --- a/plugin/src/generators/sentry/files/sentry.client.config.ts.template +++ b/plugin/src/generators/sentry/files/sentry.client.config.ts.template @@ -1,8 +1,7 @@ import * as Sentry from '@sentry/nextjs'; Sentry.init({ - // TODO replace with your DSN - dsn: '', + dsn: '<%= DSN %>', // Adjust this value in production, or use tracesSampler for greater control tracesSampleRate: 1, diff --git a/plugin/src/generators/sentry/files/sentry.edge.config.ts.template b/plugin/src/generators/sentry/files/sentry.edge.config.ts.template index 6e7d221..bba4747 100644 --- a/plugin/src/generators/sentry/files/sentry.edge.config.ts.template +++ b/plugin/src/generators/sentry/files/sentry.edge.config.ts.template @@ -1,8 +1,7 @@ import * as Sentry from '@sentry/nextjs'; Sentry.init({ - // TODO replace with your DSN - dsn: '', + dsn: '<%= DSN %>', // Adjust this value in production, or use tracesSampler for greater control tracesSampleRate: 1, diff --git a/plugin/src/generators/sentry/files/sentry.server.config.ts.template b/plugin/src/generators/sentry/files/sentry.server.config.ts.template index 38a4824..ded1139 100644 --- a/plugin/src/generators/sentry/files/sentry.server.config.ts.template +++ b/plugin/src/generators/sentry/files/sentry.server.config.ts.template @@ -1,8 +1,7 @@ import * as Sentry from '@sentry/nextjs'; Sentry.init({ - // TODO replace with your DSN - dsn: '', + dsn: '<%= DSN %>', // Adjust this value in production, or use tracesSampler for greater control tracesSampleRate: 1, diff --git a/plugin/src/generators/sentry/generator.ts b/plugin/src/generators/sentry/generator.ts index de2d51b..db59adb 100644 --- a/plugin/src/generators/sentry/generator.ts +++ b/plugin/src/generators/sentry/generator.ts @@ -6,12 +6,13 @@ import { } from '@nx/devkit'; import * as path from 'path'; import { SentryGeneratorSchema } from './schema'; +import { isExpoApp, isNextApp } from '../../shared/utils'; -const webDependencies = { +const nextAppDependencies = { '@sentry/nextjs': '^8.21.0', }; -const mobileDependencies = { +const expoAppDependencies = { '@sentry/react-native': '~5.22.0', }; @@ -21,8 +22,8 @@ export async function sentryGenerator( ) { const projectRoot = `apps/${options.directory}`; - if (tree.exists(`${projectRoot}/next.config.js`)) { - addDependenciesToPackageJson(tree, webDependencies, {}); + if (isNextApp(tree, projectRoot)) { + addDependenciesToPackageJson(tree, nextAppDependencies, {}); const nextConfigContent = tree .read(`${projectRoot}/next.config.js`) @@ -83,8 +84,8 @@ export async function sentryGenerator( }); generateFiles(tree, path.join(__dirname, 'files'), projectRoot, options); - } else if (tree.exists(`${projectRoot}/metro.config.js`)) { - addDependenciesToPackageJson(tree, mobileDependencies, {}); + } else if (isExpoApp(tree, projectRoot)) { + addDependenciesToPackageJson(tree, expoAppDependencies, {}); const layoutContent = tree .read(`${projectRoot}/app/_layout.tsx`) diff --git a/plugin/src/generators/sentry/schema.json b/plugin/src/generators/sentry/schema.json index 9693713..b9c2340 100644 --- a/plugin/src/generators/sentry/schema.json +++ b/plugin/src/generators/sentry/schema.json @@ -12,7 +12,16 @@ "index": 0 }, "x-prompt": "Enter the name of the directory in the 'apps/' folder (e.g: web)" + }, + "DSN": { + "type": "string", + "description": "", + "$default": { + "$source": "argv", + "index": 0 + }, + "x-prompt": "Enter the DSN" } }, - "required": ["directory"] + "required": ["directory", "DSN"] } diff --git a/plugin/src/shared/utils/index.ts b/plugin/src/shared/utils/index.ts index 9125b36..e326a9f 100644 --- a/plugin/src/shared/utils/index.ts +++ b/plugin/src/shared/utils/index.ts @@ -1,2 +1,4 @@ export * from './format-utils'; export * from './cli-utils'; +export * from './is-next-app'; +export * from './is-expo-app' diff --git a/plugin/src/shared/utils/is-expo-app.ts b/plugin/src/shared/utils/is-expo-app.ts new file mode 100644 index 0000000..bd4e16a --- /dev/null +++ b/plugin/src/shared/utils/is-expo-app.ts @@ -0,0 +1,5 @@ +import { Tree } from '@nx/devkit'; + +export const isExpoApp = (tree: Tree, projectRoot: string): boolean => { + return tree.exists(`${projectRoot}/metro.config.js`); +}; diff --git a/plugin/src/shared/utils/is-next-app.ts b/plugin/src/shared/utils/is-next-app.ts new file mode 100644 index 0000000..f3ee77e --- /dev/null +++ b/plugin/src/shared/utils/is-next-app.ts @@ -0,0 +1,5 @@ +import { Tree } from '@nx/devkit'; + +export const isNextApp = (tree: Tree, projectRoot: string): boolean => { + return tree.exists(`${projectRoot}/next.config.js`); +}; From 743e5485e94278cba0014f99cc1c522cdfd26b18 Mon Sep 17 00:00:00 2001 From: vaniasuveev Date: Tue, 27 Aug 2024 17:32:28 +0300 Subject: [PATCH 4/4] feat: updated next and expo generators --- plugin/src/generators/expo-app/generator.ts | 10 +++++----- plugin/src/generators/expo-app/schema.json | 5 ----- plugin/src/generators/next-app/generator.ts | 11 +++++------ plugin/src/generators/next-app/schema.json | 5 ----- plugin/src/generators/sentry/schema.json | 6 +----- 5 files changed, 11 insertions(+), 26 deletions(-) diff --git a/plugin/src/generators/expo-app/generator.ts b/plugin/src/generators/expo-app/generator.ts index b99e1a1..8ba12a5 100644 --- a/plugin/src/generators/expo-app/generator.ts +++ b/plugin/src/generators/expo-app/generator.ts @@ -13,7 +13,6 @@ import { ExpoAppGeneratorSchema } from './schema'; import scripts from './scripts'; import { existsSync, rmSync } from 'fs'; import { formatName, formatAppIdentifier } from '../../shared/utils'; -import sentryGenerator from '../sentry/generator'; const dependencies = { 'expo-constants': '~16.0.2', @@ -91,13 +90,14 @@ export async function expoAppGenerator( await formatFiles(tree); - if (options.withSentry) { - await sentryGenerator(tree, options); - } - return () => { installPackagesTask(tree); execSync('npx expo install --fix', { stdio: 'inherit' }); + if (options.withSentry) { + execSync(`npx nx g sentry --directory=${options.directory}`, { + stdio: 'inherit', + }); + } }; } diff --git a/plugin/src/generators/expo-app/schema.json b/plugin/src/generators/expo-app/schema.json index d60acae..e39544a 100644 --- a/plugin/src/generators/expo-app/schema.json +++ b/plugin/src/generators/expo-app/schema.json @@ -26,11 +26,6 @@ "type": "boolean", "default": false, "x-prompt": "Do you want to use sentry in your app?" - }, - "DSN": { - "type": "string", - "description": "", - "x-prompt": "Enter the DSN (skip if you do not use Sentry)" } }, "required": ["name", "directory", "withSentry"] diff --git a/plugin/src/generators/next-app/generator.ts b/plugin/src/generators/next-app/generator.ts index f5a3db5..11c7972 100644 --- a/plugin/src/generators/next-app/generator.ts +++ b/plugin/src/generators/next-app/generator.ts @@ -12,7 +12,6 @@ import { NextAppGeneratorSchema } from './schema'; import { existsSync } from 'fs'; import { formatName } from '../../shared/utils'; import * as path from 'path'; -import sentryGenerator from '../sentry/generator'; const dependencies = { 'next-intl': '^3.17.2', @@ -61,15 +60,15 @@ export async function nextAppGenerator( // Add dependencies addDependenciesToPackageJson(tree, dependencies, {}); - await formatFiles(tree); - if (options.withSentry) { - await sentryGenerator(tree, options); - } - return () => { installPackagesTask(tree); + if (options.withSentry) { + execSync(`npx nx g sentry --directory=${options.directory}`, { + stdio: 'inherit', + }); + } }; } diff --git a/plugin/src/generators/next-app/schema.json b/plugin/src/generators/next-app/schema.json index 438bc0e..85bc36a 100644 --- a/plugin/src/generators/next-app/schema.json +++ b/plugin/src/generators/next-app/schema.json @@ -26,11 +26,6 @@ "type": "boolean", "default": false, "x-prompt": "Do you want to use sentry in your app?" - }, - "DSN": { - "type": "string", - "description": "", - "x-prompt": "Enter the DSN (skip if you do not use Sentry)" } }, "required": ["name", "directory", "withSentry"] diff --git a/plugin/src/generators/sentry/schema.json b/plugin/src/generators/sentry/schema.json index b9c2340..070ac35 100644 --- a/plugin/src/generators/sentry/schema.json +++ b/plugin/src/generators/sentry/schema.json @@ -16,11 +16,7 @@ "DSN": { "type": "string", "description": "", - "$default": { - "$source": "argv", - "index": 0 - }, - "x-prompt": "Enter the DSN" + "x-prompt": "What is your Sentry DSN?" } }, "required": ["directory", "DSN"]