Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changeset/solid-pigs-rhyme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@hyperdx/app': patch
---

Transition the local development server from Webpack to Turbopack to
significantly improve build performance and hot-reloading speed.
21 changes: 10 additions & 11 deletions packages/app/next.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -37,30 +37,29 @@ const nextConfig = {
'@opentelemetry/auto-instrumentations-node',
'@hyperdx/node-opentelemetry',
'@hyperdx/instrumentation-sentry-node',
// Outside of Vercel preview deployments, the `/api/[...all]` catch-all
// proxies to a separately-deployed API service and never imports the
// `@hyperdx/api` package at runtime. Mark it (and its subpaths) as a
// CommonJS external so production app builds (Docker fullstack image,
// standalone Next output) stay byte-for-byte equivalent to today and
// do not pull in passport-saml, mongoose, AWS SDK, etc.
...(process.env.HDX_PREVIEW_INLINE_API !== 'true' ? ['@hyperdx/api'] : []),

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Image

When I run this branch locally, I get this error. It's still trying to compile the require('@hyperdx/api/build/serverless'); path for me locally I believe.

Are you getting that?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

addressed it.

],
typescript: {
tsconfigPath: 'tsconfig.build.json',
},
// NOTE: Using Webpack instead of Turbopack (Next.js 16 default)
// Dev uses Turbopack; production build uses Webpack (--webpack).
// Reason: Turbopack has CSS module parsing issues with nested :global syntax
// used in styles/SearchPage.module.scss and other SCSS files.
// The --webpack flag is added to dev and build scripts in package.json.
// TODO: Re-evaluate when Turbopack CSS module support improves
// Ignore otel pkgs warnings
// https://github.com/open-telemetry/opentelemetry-js/issues/4173#issuecomment-1822938936
// TODO: single bundler when Turbopack CSS is solid.
// Ignore otel warnings (Webpack): https://github.com/open-telemetry/opentelemetry-js/issues/4173#issuecomment-1822938936
webpack: (
config,
{ buildId, dev, isServer, defaultLoaders, nextRuntime, webpack },
) => {
if (isServer) {
config.ignoreWarnings = [{ module: /opentelemetry/ }];

// Outside of Vercel preview deployments, the `/api/[...all]` catch-all
// proxies to a separately-deployed API service and never imports the
// `@hyperdx/api` package at runtime. Mark it (and its subpaths) as a
// CommonJS external so production app builds (Docker fullstack image,
// standalone Next output) stay byte-for-byte equivalent to today and
// do not pull in passport-saml, mongoose, AWS SDK, etc.
if (process.env.HDX_PREVIEW_INLINE_API !== 'true') {
config.externals = [
...(config.externals ?? []),
Expand Down
5 changes: 3 additions & 2 deletions packages/app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@
"engines": {
"node": ">=22.16.0"
},
"//bundler": "dev/dev:local run on Turbopack for fast local iteration; build/build:clickhouse run on Webpack (--webpack) for production parity. The two bundlers can diverge on CSS Modules/loaders/module resolution, so build failures may not reproduce in dev. See next.config.mjs for rationale.",
"scripts": {
"dev": "npx dotenv -e .env.development -- next dev --webpack",
"dev:local": "NEXT_PUBLIC_IS_LOCAL_MODE=true npx dotenv -e .env.development -- next dev --webpack",
"dev": "npx dotenv -e .env.development -- next dev --turbopack",
"dev:local": "NEXT_PUBLIC_IS_LOCAL_MODE=true npx dotenv -e .env.development -- next dev --turbopack",
"build": "next build --webpack",
"build:clickhouse": "NEXT_PUBLIC_THEME=clickstack NEXT_PUBLIC_IS_LOCAL_MODE=true NEXT_PUBLIC_CLICKHOUSE_BUILD=true next build --webpack && node scripts/prepare-clickhouse-build-export.js",
"run:clickhouse": "test -d out && npx rimraf tmp && mkdir tmp && cp -r out tmp/clickstack && echo 'visit http://localhost:3000/clickstack to start' && npx serve tmp -l 3000 || echo 'run build:clickhouse first'",
Expand Down
12 changes: 6 additions & 6 deletions packages/app/pages/api/[...all].ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@ export const config = {
// we proxy `/api/*` to a separately-deployed API service as before.
const isInlineApi = process.env.HDX_PREVIEW_INLINE_API === 'true';

export default (req: NextApiRequest, res: NextApiResponse) => {
export default async (req: NextApiRequest, res: NextApiResponse) => {
if (isInlineApi) {
// Lazy require so non-preview production builds — where the webpack
// externals hook in next.config.mjs marks @hyperdx/api as external —
// never attempt to resolve a module that isn't bundled.
// eslint-disable-next-line @typescript-eslint/no-require-imports
const inlineApi = require('@hyperdx/api/build/serverless');
const inlineApi = await import(
/* webpackIgnore: true */
/* turbopackIgnore: true */
'@hyperdx/api/build/serverless'
);
const handler = inlineApi.default ?? inlineApi;
return handler(req, res);
}
Expand Down
36 changes: 17 additions & 19 deletions packages/app/styles/SearchPage.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -14,28 +14,26 @@
overflow: hidden;
z-index: 3; // higher z-index to be above other elements

:global {
.mantine-TextInput-wrapper {
background-color: transparent;
}
:global(.mantine-TextInput-wrapper) {
background-color: transparent;
}

.mantine-TextInput-input {
height: 20px;
min-height: 20px;
background-color: transparent;
color: var(--color-text-secondary);
font-size: var(--mantine-font-size-xs);
:global(.mantine-TextInput-input) {
height: 20px;
min-height: 20px;
background-color: transparent;
color: var(--color-text-secondary);
font-size: var(--mantine-font-size-xs);
}

&::placeholder {
color: var(--color-text-muted);
font-weight: bold;
}
:global(.mantine-TextInput-input::placeholder) {
color: var(--color-text-muted);
font-weight: bold;
}

&:focus {
border: none;
outline: none;
}
}
:global(.mantine-TextInput-input:focus) {
border: none;
outline: none;
}
}

Expand Down