Skip to content

Commit

Permalink
Move Vite plugins to their new home (#1935)
Browse files Browse the repository at this point in the history
* Move Oxygen plugin to mini-oxygen package

* Do not log favicon requests

* Ignore .shopify directory from all examples

* Move Hydrogen plugin to hydrogen package

* Add coverage check

* Pass plugin options using a public API

* Get plugin options in CLI for checks

* Flatten Oxygen plugin options

* Type safety for plugin API

* Simplify services in MiniOxygen

* Improve critical CSS code and docs

* Adapt subrequest profiler backend to Vite

* Replace setupScripts with crossBoundarySetup in MiniOxygen Vite

* Add Vite types to tsconfig.json

* Create __H2O_LOG_EVENT directly in Vite

* Update projects to new plugin paths

* Fix HMR

* Fix cross-package types

* Minor fixes to build types

* Fix virtual route test for classic compiler

* Fix type

* Add subrequest profiler logger globally in Node environments

* Improve types and split logic of mini-oxygen handler

* Replicate requestHook at the Vite Environment level

* Fix re-using request body

* Make the request hook be a POST request

* Move source of truth for sub-request profiler types to Hydrogen package

* Fix cross-package types

* Start sending subrequest-profiler events from Hydrogen middleware instead of remix-oxygen

* Support subrequest profiler in Node.js servers

* Use Remix presets for virtual routes (#1940)

* Use Remix presets for virtual routes

* Pin oxygen-cli dependency to fix installation

* Avoid adding virtual routes in build

* Wrap virtual routes in virtual root

* Omit user root when rendering virtual routes

* Move buildDirectory to preset and use it in projects

* Update tests

* Use RemixConfig for appDir

* Hide non actionable error about critical CSS in virtual routes

* Improve types

* Read remix config from Hydrogen plugin

* Fix plugin types in vite.config.ts

* Changesets

* Remove unused internal feature

* Remove @experimental comment

* Dedup package-lock.json
  • Loading branch information
frandiox committed Apr 8, 2024
1 parent 4758bf6 commit ebaf552
Show file tree
Hide file tree
Showing 79 changed files with 1,863 additions and 1,121 deletions.
14 changes: 0 additions & 14 deletions .changeset/angry-games-train.md

This file was deleted.

20 changes: 20 additions & 0 deletions .changeset/little-paws-fry.md
@@ -0,0 +1,20 @@
---
'skeleton': patch
---

In Vite projects, the way that plugins are imported and the options passed to Remix have changed:

```diff
-import {hydrogen, oxygen} from '@shopify/cli-hydrogen/experimental-vite';
+import {hydrogen} from '@shopify/hydrogen/vite';
+import {oxygen} from '@shopify/mini-oxygen/vite';
import {vitePlugin as remix} from '@remix-run/dev';

export default defineConfig({
hydrogen(),
oxygen(),
remix({
- buildDirectory: 'dist',
+ presets: [hydrogen.preset()],
future: {
```
5 changes: 5 additions & 0 deletions .changeset/polite-seahorses-fail.md
@@ -0,0 +1,5 @@
---
'@shopify/hydrogen': patch
---

A new Vite plugin is exported from `@shopify/hydrogen/vite`. It provides DX improvements for Vite users, such as adding `/subrequest-profiler` and `/graphiql`.
5 changes: 5 additions & 0 deletions .changeset/shy-bulldogs-smile.md
@@ -0,0 +1,5 @@
---
'@shopify/remix-oxygen': patch
---

Fix compatibility of `/subrequest-profiler` with Vite.
5 changes: 5 additions & 0 deletions .changeset/shy-seas-own.md
@@ -0,0 +1,5 @@
---
'@shopify/cli-hydrogen': minor
---

The `@shopify/cli-hydrogen/experimental-vite` import path has been removed. Instead, use `@shopify/hydrogen/vite` and `@shopify/mini-oxygen/vite` to import the Vite plugins.
5 changes: 5 additions & 0 deletions .changeset/strong-beds-call.md
@@ -0,0 +1,5 @@
---
'@shopify/mini-oxygen': minor
---

A new Vite plugin is exported from `@shopify/mini-oxygen/vite`. It integrates Vite with MiniOxygen by running the application code within a worker.
1 change: 1 addition & 0 deletions .gitignore
Expand Up @@ -5,6 +5,7 @@ node_modules
.vscode
.turbo
.cache
.shopify
/test-results/
/playwright-report/
/playwright/.cache/
Expand Down
745 changes: 377 additions & 368 deletions package-lock.json

Large diffs are not rendered by default.

10 changes: 3 additions & 7 deletions packages/cli/package.json
Expand Up @@ -29,7 +29,7 @@
"flame-chart-js": "2.3.2",
"get-port": "^7.0.0",
"type-fest": "^4.5.0",
"vite": "~5.1.7",
"vite": "~5.1.0",
"vitest": "^1.0.4"
},
"dependencies": {
Expand Down Expand Up @@ -62,7 +62,7 @@
"peerDependencies": {
"@remix-run/dev": "^2.1.0",
"@shopify/mini-oxygen": "^2.2.5",
"vite": "~5.1.7"
"vite": "~5.1.0"
},
"peerDependenciesMeta": {
"@remix-run/dev": {
Expand All @@ -79,12 +79,8 @@
"exports": {
"./package.json": "./package.json",
"./commands/hydrogen/init": {
"types": "./dist/commands/hydrogen/init.d.ts",
"types": "./dist/init.d.ts",
"default": "./dist/commands/hydrogen/init.js"
},
"./experimental-vite": {
"types": "./dist/lib/vite/plugins.d.ts",
"default": "./dist/lib/vite/plugins.js"
}
},
"files": [
Expand Down
76 changes: 41 additions & 35 deletions packages/cli/src/commands/hydrogen/dev-vite.ts
Expand Up @@ -23,7 +23,6 @@ import {spawnCodegenProcess} from '../../lib/codegen.js';
import {getAllEnvironmentVariables} from '../../lib/environment-variables.js';
import {displayDevUpgradeNotice} from './upgrade.js';
import {prepareDiffDirectory} from '../../lib/template-diff.js';
import {setH2OPluginContext} from '../../lib/vite/shared.js';
import {
getDebugBannerLine,
startTunnelAndPushConfig,
Expand All @@ -35,6 +34,8 @@ import {
} from '../../lib/dev-shared.js';
import {getCliCommand} from '../../lib/shell.js';
import {findPort} from '../../lib/find-port.js';
import {logRequestLine} from '../../lib/mini-oxygen/common.js';
import {findHydrogenPlugin, findOxygenPlugin} from '../../lib/vite-config.js';

export default class DevVite extends Command {
static description =
Expand All @@ -50,7 +51,6 @@ export default class DevVite extends Command {
description:
"Disable rendering fallback routes when a route file doesn't exist.",
env: 'SHOPIFY_HYDROGEN_FLAG_DISABLE_VIRTUAL_ROUTES',
default: false,
}),
...commonFlags.debug,
...commonFlags.inspectorPort,
Expand Down Expand Up @@ -178,36 +178,40 @@ export async function runViteDev({
customLogger,
clearScreen: false,
server: {fs, host: host ? true : undefined},
plugins: customerAccountPushFlag
? [
{
name: 'hydrogen:tunnel',
configureServer: (viteDevServer) => {
viteDevServer.middlewares.use((req, res, next) => {
const host = req.headers.host;

if (host?.includes(TUNNEL_DOMAIN.ORIGINAL)) {
req.headers.host = host.replace(
TUNNEL_DOMAIN.ORIGINAL,
TUNNEL_DOMAIN.REBRANDED,
);
}

next();
});
},
},
]
: [],
...setH2OPluginContext({
cliOptions: {
debug,
ssrEntry,
envPromise: envPromise.then(({allVariables}) => allVariables),
inspectorPort,
disableVirtualRoutes,
plugins: [
{
name: 'hydrogen:cli',
configResolved(config) {
findHydrogenPlugin(config)?.api?.registerPluginOptions({
disableVirtualRoutes,
});

findOxygenPlugin(config)?.api?.registerPluginOptions({
debug,
entry: ssrEntry,
envPromise: envPromise.then(({allVariables}) => allVariables),
inspectorPort,
logRequestLine,
});
},
configureServer: (viteDevServer) => {
if (customerAccountPushFlag) {
viteDevServer.middlewares.use((req, res, next) => {
const host = req.headers.host;

if (host?.includes(TUNNEL_DOMAIN.ORIGINAL)) {
req.headers.host = host.replace(
TUNNEL_DOMAIN.ORIGINAL,
TUNNEL_DOMAIN.REBRANDED,
);
}

next();
});
}
},
},
}),
],
});

process.once('SIGTERM', async () => {
Expand All @@ -218,20 +222,22 @@ export async function runViteDev({
}
});

if (
!viteServer.config.plugins.find((plugin) => plugin.name === 'hydrogen:main')
) {
const h2Plugin = findHydrogenPlugin(viteServer.config);
if (!h2Plugin) {
await viteServer.close();
throw new AbortError(
'Hydrogen plugin not found.',
'Add `hydrogen()` plugin to your Vite config.',
);
}

const h2PluginOptions = h2Plugin.api?.getPluginOptions?.();

const codegenProcess = useCodegen
? spawnCodegenProcess({
rootDirectory: root,
configFilePath: codegenConfigPath,
appDirectory: h2PluginOptions?.remixConfig?.appDirectory,
})
: undefined;

Expand Down Expand Up @@ -284,7 +290,7 @@ export async function runViteDev({

const customSections: AlertCustomSection[] = [];

if (!disableVirtualRoutes) {
if (!h2PluginOptions?.disableVirtualRoutes) {
customSections.push({body: getUtilityBannerlines(finalHost)});
}

Expand Down
14 changes: 14 additions & 0 deletions packages/cli/src/lib/log.ts
Expand Up @@ -195,6 +195,20 @@ export function muteDevLogs({workerReload}: {workerReload?: boolean} = {}) {
/^Re-optimizing dependencies because/i.test(first),
() => {},
],
[
// This error is fixed in new Remix versions:
// https://github.com/remix-run/remix/pull/9194
([first]) => {
const message: string = first?.message ?? first;
return (
/virtual-routes/.test(message) &&
/(Failed to load url|Could not resolve module for file)/i.test(
message,
)
);
},
() => {},
],
[
// Log new lines between Request logs and other logs
([first], existingMatches) => {
Expand Down
30 changes: 13 additions & 17 deletions packages/cli/src/lib/mini-oxygen/common.ts
Expand Up @@ -6,6 +6,7 @@ import {
import colors from '@shopify/cli-kit/node/colors';
import {DEV_ROUTES} from '../request-events.js';
import {AbortError} from '@shopify/cli-kit/node/error';
import type {RequestHookInfo} from '@shopify/mini-oxygen';

// Default port used for debugging in VSCode and Chrome DevTools.
export const DEFAULT_INSPECTOR_PORT = 9229;
Expand All @@ -19,16 +20,11 @@ export function handleMiniOxygenImportFail(): never {
);
}

export function logRequestLine(
// Minimal overlap between Fetch, Miniflare@2 and Miniflare@3 request types.
request: Pick<Request, 'method' | 'url'> & {
headers: {get: (key: string) => string | null};
},
{
responseStatus = 200,
durationMs = 0,
}: {responseStatus?: number; durationMs?: number} = {},
): void {
export function logRequestLine({
request,
response,
meta,
}: RequestHookInfo): void {
try {
const url = new URL(request.url);
if (DEV_ROUTES.has(url.pathname) || url.pathname === '/favicon.ico') return;
Expand All @@ -46,26 +42,26 @@ export function logRequestLine(
}

const colorizeStatus =
responseStatus < 300
response.status < 300
? outputToken.green
: responseStatus < 400
: response.status < 400
? outputToken.cyan
: outputToken.errorText;

outputInfo(
outputContent`${request.method.padStart(6)} ${colorizeStatus(
String(responseStatus),
String(response.status),
)} ${outputToken.italic(type.padEnd(7, ' '))} ${route} ${
durationMs > 0 ? colors.dim(` ${durationMs}ms`) : ''
meta.durationMs > 0 ? colors.dim(` ${meta.durationMs}ms`) : ''
}${info ? ' ' + colors.dim(info) : ''}${
request.headers.get('purpose') === 'prefetch'
request.headers['purpose'] === 'prefetch'
? outputToken.italic(colors.dim(' prefetch'))
: ''
}`,
);
} catch {
if (request && responseStatus) {
outputInfo(`${request.method} ${responseStatus} ${request.url}`);
if (request && response?.status) {
outputInfo(`${request.method} ${response.status} ${request.url}`);
}
}
}
21 changes: 18 additions & 3 deletions packages/cli/src/lib/mini-oxygen/node.ts
Expand Up @@ -87,9 +87,24 @@ export async function startNodeServer({
() => defaultDispatcher(request),
);

logRequestLine(request, {
responseStatus: response.status,
durationMs: startTimeMs > 0 ? Date.now() - startTimeMs : 0,
const endTimeMs = Date.now();

logRequestLine({
request: {
url: request.url,
method: request.method,
headers: Object.fromEntries(request.headers.entries()),
},
response: {
status: response.status,
statusText: response.statusText,
headers: Object.fromEntries(response.headers.entries()),
},
meta: {
startTimeMs,
endTimeMs,
durationMs: startTimeMs > 0 ? endTimeMs - startTimeMs : 0,
},
});

return response;
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/src/lib/mini-oxygen/workerd.ts
Expand Up @@ -57,10 +57,10 @@ export async function startWorkerdServer({

const miniOxygen = createMiniOxygen({
debug,
logRequestLine,
port: appPort,
host: 'localhost',
liveReload: watch,
requestHook: logRequestLine,
inspectorPort: publicInspectorPort,
inspectWorkerName: mainWorkerName,
assets: {port: assetsPort, directory: buildPathClient},
Expand Down
3 changes: 2 additions & 1 deletion packages/cli/src/lib/request-events.ts
Expand Up @@ -30,8 +30,9 @@ export function setConstructors(constructors: {

export const DEV_ROUTES = new Set([
'/graphiql',
'/graphiql/customer-account.schema.json',
'/subrequest-profiler',
'/__vite_warmup',
'/debug-network-server',
]);

type RequestEvent = {
Expand Down

0 comments on commit ebaf552

Please sign in to comment.