Skip to content

Commit

Permalink
feat(nuxt): Use --import as the default installation method (#12070)
Browse files Browse the repository at this point in the history
* feat(nuxt): Use --import as the default installation method

* change to experimental_entrypointWrappedFunctions

* review suggestions
  • Loading branch information
s1gr1d authored Dec 10, 2024
1 parent f48a63e commit 33685cc
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 42 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,12 @@ supported:
When running your application in ESM mode, you will most likely want to <PlatformLink to="/install/esm">follow the ESM instructions</PlatformLink>. However, if you want to avoid using the `--import` command line option, for example if you have no way of configuring a CLI flag, you can also follow an alternative setup that involves importing the `instrument.mjs` file directly in your application.

<Alert level='warning' title='Restrictions of this installation method'>
This installation method has a fundamental restriction: It only supports limited performance instrumentation. Only basic `http` instrumentation will work, and no DB or framework-specific instrumentation will be available.

Because of this, we recommend using this only if the `--import` flag is not an option for you.
This installation method has fundamental restrictions:
- It only supports limited performance instrumentation.
- Only basic `http` instrumentation will work.
- No DB or framework-specific instrumentation will be available.

We recommend using this only if the `--import` flag is not an option for you.
</Alert>

You need to create a file named `instrument.mjs` that imports and initializes Sentry:
Expand Down
37 changes: 10 additions & 27 deletions docs/platforms/javascript/guides/nuxt/install/cli-import.mdx
Original file line number Diff line number Diff line change
@@ -1,45 +1,29 @@
---
title: --import CLI flag
sidebar_order: 2
description: "Learn about using the node `--import` CLI flag."
title: --import CLI flag (default)
sidebar_order: 1
description: "Learn how to use the node --import CLI flag."
---

## Understanding the `--import` CLI Flag

The [`--import` CLI flag](https://nodejs.org/api/cli.html#--importmodule) in Node allows you to preload modules before the application starts.
The [`--import` CLI flag](https://nodejs.org/api/cli.html#--importmodule) in Node is the default way in ESM to preload a module before the application starts.
If you cannot use the SDK's <PlatformLink to="/install/dynamic-import/">default dynamic import behaviour</PlatformLink>, setting
this flag is crucial for ensuring proper server-side initialization, as Sentry needs to be initialized before the rest of the application runs.

## Scenarios where `--import` does not work

- You're not able to add Node CLI flags or environment variables that are scoped to the function runtime
- As of now, Netlify only supports adding scoped environment variables in the paid plan
- As of now, Vercel does not provide an option for scoping environment variables
- **Netlify** only allows scoped environment variables on its paid plans at this time
- **Vercel** doesn't currently provide an option for scoping environment variables

If any of those points apply to you, you cannot use the `--import` flag to initialize Sentry on the server-side.
Check out the guide for using <PlatformLink to="/install/dynamic-import/">dynamic import</PlatformLink> instead.
Check out the guide for using <PlatformLink to="/install/top-level-import/">a top-level import</PlatformLink> or a <PlatformLink to="/install/dynamic-import/">dynamic import</PlatformLink> instead.

## Initializing Sentry with `--import`

To successfully use the `--import` flag, follow these steps:
By default, the SDK will add the Sentry server config to the build output (typically, `.output/server/sentry.server.config.mjs`).

### 1. Disable Dynamic Import

First, disable the dynamic import by setting `dynamicImportForServerEntry` to `false`:

```javascript {filename: nuxt.config.ts} {5}
export default defineNuxtConfig({
modules: ["@sentry/nuxt/module"],

sentry: {
dynamicImportForServerEntry: false,
},
});
```

By disabling the dynamic import, the SDK will add the Sentry server config to the build output (typically `.output/server/sentry.server.config.mjs`).

### 2. Adding `--import` to `node` command
### 1. Adding `--import` to `node` command

After building your Nuxt app with `nuxi build`, add the `--import` flag followed by the Sentry server config path to the `node` command.
With the default Nitro Node preset, this typically looks like this:
Expand All @@ -57,13 +41,12 @@ To make things easier, add a script in the `package.json`:
```json {filename:package.json}
{
"scripts": {
"preview": "NODE_OPTIONS='--import .//server/sentry.server.config.mjs' nuxt preview",
"start": "node --import ./.output/server/sentry.server.config.mjs .output/server/index.mjs"
}
}
```

### 3. Adding `--import` flag in production
### 2. Adding `--import` flag in production

To be able to set up Sentry in production, the `--import` flag needs to be added wherever you run your application's production build output.
Consult your hosting provider's documentation for specific implementation details.
Expand Down
37 changes: 25 additions & 12 deletions docs/platforms/javascript/guides/nuxt/install/dynamic-import.mdx
Original file line number Diff line number Diff line change
@@ -1,24 +1,36 @@
---
title: Dynamic Import (default)
sidebar_order: 1
title: Dynamic Import (experimental)
sidebar_order: 3
description: "Learn about how the Nuxt SDK leverages dynamic input() in the build output."
---

## Understanding the `import()` expression

The `import()` expression (also called "dynamic import") allows conditional and flexible module loading in ESM.
For the Sentry Nuxt SDK, it provides an approach to initialize server-side configuration before application startup.

The Sentry Nuxt SDK will be initialized before any other code runs and the Nitro server runtime code will be loaded later because of `import()`ing it.
This early initialization is required to set up the SDK's instrumentation of various libraries correctly.

## Initializing Sentry with Dynamic `import()`

By default, the Sentry Nuxt SDK includes a Rollup plugin which wraps the server entry file with a dynamic `import()`.
Enable the dynamic `import()` by setting `autoInjectServerSentry`:

```typescript {filename:nuxt.config.ts} {3}
export default defineNuxtConfig({
sentry: {
autoInjectServerSentry: 'experimental_dynamic-import'
},
})
```

After setting this, the Sentry Nuxt SDK adds some build-time configuration to ensure your app is wrapped with `import()`.
With this, Sentry can be initialized before all other modules of the application.

The server entry file will look something like this:
The Nuxt server entry file will look something like this:

```javascript {filename:.output/server/index.mjs}
// Note: file may have some imports and code related to debug IDs
// Note: The file may have some imports and code, related to debug IDs
Sentry.init({
dsn: "..."
});
Expand All @@ -28,8 +40,11 @@ import('./chunks/nitro/nitro.mjs').then(function (n) { return n.r; });

## Scenarios where `import()` doesn't work

We are currently investigating an issue where the server-side is not correctly initialized with a recent update of Nitro (the server-side toolkit in Nuxt).
We are working on figuring this out ([see issue here](https://github.com/getsentry/sentry-javascript/issues/14514)). As a temporary workaround, you can add the following overrides to your application:
Depending on your setup and which version of Nitro is used, the server-side is sometimes not correctly initialized.
The build output **must not** include a regular `import` of the Nitro runtime (e.g. `import './chunks/nitro/nitro.mjs'`).
See the ([GitHub issue here](https://github.com/getsentry/sentry-javascript/issues/14514)) for more information.

As a temporary workaround, you can add the following overrides in your application:

```json {tabTitle:npm} {filename:package.json}
"overrides": {
Expand All @@ -52,16 +67,14 @@ We are working on figuring this out ([see issue here](https://github.com/getsent
}
```

You can also check out the guide for using the <PlatformLink to="/install/cli-import//">CLI flag `--import`</PlatformLink> as this might be a better choice for you.

You can also check out the guide for installing the SDK with a <PlatformLink to="/install/cli-import">CLI flag `--import`</PlatformLink> or a <PlatformLink to="/install/top-level-import/">top-level import</PlatformLink>.

## Re-exporting serverless handler functions

Sentry automatically detects serverless handler functions in the build output and re-exports them from the server entry file.

By default, Sentry re-exports functions named `handler`, `server`, and `default` exports. This will work in most cases and no other action is required.
In case your serverless function has another, custom name you can override this with `entrypointWrappedFunctions`:

If your serverless function has a custom name, you can override it with `experimental_entrypointWrappedFunctions`:

```javascript {filename: nuxt.config.ts} {7}
export default defineNuxtConfig({
Expand All @@ -70,7 +83,7 @@ export default defineNuxtConfig({
sentry: {
// Customize detected function names
// Default value: ['default', 'handler', 'server']
entrypointWrappedFunctions: ['customFunctionName']
experimental_entrypointWrappedFunctions: ['customFunctionName']
},
});
```
42 changes: 42 additions & 0 deletions docs/platforms/javascript/guides/nuxt/install/top-level-import.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
---
title: Top-level import
sidebar_order: 2
description: "Learn about how the Nuxt SDK adds a top-level import to the build output."
---

## Understanding Top-level `import`

Sentry needs to be initialized before the application starts.
If the default way of adding an <PlatformLink to="/install/cli-import">`--import` CLI flag</PlatformLink> flag does not work for you,
set up the SDK for adding a top-level `import`. This will import the Sentry server-side config at the top of the Nuxt server entry file.
In this case, Sentry isn’t initialized before the app starts, but is set up as early as possible.

<Alert level='warning' title='Restrictions of this installation method'>
This installation method has fundamental restrictions:
- It only supports limited performance instrumentation.
- Only basic `http` instrumentation will work.
- No DB or framework-specific instrumentation will be available.

We recommend using this only if the `--import` flag is not an option for you.
</Alert>

## Initializing Sentry With a Top-level `import`

Enable the top-level `import` by setting `autoInjectServerSentry`:

```typescript {filename:nuxt.config.ts} {3}
export default defineNuxtConfig({
sentry: {
autoInjectServerSentry: 'top-level-import'
},
})
```

By default, the SDK will add the Sentry server config to the build output (typically, `.output/server/sentry.server.config.mjs`).

With the top-level `import`, the Nuxt server entry file will look something like this:

```javascript {filename:.output/server/index.mjs}
import './sentry.server.config.mjs';
// Note: The file may have some imports and code, related to debug IDs
```
6 changes: 6 additions & 0 deletions docs/platforms/javascript/guides/nuxt/manual-setup.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,12 @@ dotenv.config();
// ... rest of the file
```

#### Load Sentry config

Sentry can only be loaded on the server-side by being explicitly added via `--import`.

Check out the <PlatformLink to="/install/cli-import">`--import` CLI flag</PlatformLink> docs for setup instructions.

<Alert level="warning">
In the beta state of the Nuxt SDK, some features may not work with certain deployment providers. Check the progress on GitHub: [Compatibility with different Deployment Platforms](https://github.com/getsentry/sentry-javascript/issues/14029)
</Alert>
Expand Down

0 comments on commit 33685cc

Please sign in to comment.