diff --git a/src/vite-plugins/src/index.ts b/src/vite-plugins/src/index.ts index 544981bd4c..e45869fc6a 100644 --- a/src/vite-plugins/src/index.ts +++ b/src/vite-plugins/src/index.ts @@ -3,7 +3,7 @@ import { minify } from "html-minifier-terser"; import { extname } from "path"; import type { Plugin, ViteDevServer } from "vite"; import viteCompression from "vite-plugin-compression"; -import { forwardToReplica, readCanisterId } from "./utils.js"; +import { forwardToReplica, readCanisterId, readReplicaPort } from "./utils.js"; export * from "./utils.js"; @@ -56,16 +56,15 @@ export const minifyHTML = (): Plugin => ({ * to forward requests to a specific canister */ export const replicaForwardPlugin = ({ - replicaOrigin, forwardDomains /* note: will match exactly on . */, forwardRules, }: { - replicaOrigin: string; forwardDomains?: string[]; forwardRules: Array<{ canisterName: string; hosts: string[] }>; }) => ({ name: "replica-forward", configureServer(server: ViteDevServer) { + const replicaOrigin = `127.0.0.1:${readReplicaPort()}`; server.middlewares.use((req, res, next) => { if ( /* Deny requests to raw URLs, e.g. .raw.ic0.app to make sure that II always uses certified assets diff --git a/src/vite-plugins/src/utils.ts b/src/vite-plugins/src/utils.ts index cb011bf4d0..ad1cea34a4 100644 --- a/src/vite-plugins/src/utils.ts +++ b/src/vite-plugins/src/utils.ts @@ -4,6 +4,14 @@ import { execSync } from "child_process"; import type { IncomingMessage, ServerResponse } from "http"; import { request } from "undici"; +/** + * Read the replica port from dfx's local state + */ +export const readReplicaPort = (): string => { + const stdout = execSync("dfx info webserver-port"); + return stdout.toString().trim(); +}; + /** * Read a canister ID from dfx's local state */ diff --git a/vite.config.ts b/vite.config.ts index 2a5ec92ada..7b1cdc81d2 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -5,6 +5,7 @@ import { minifyHTML, replicaForwardPlugin, } from "@dfinity/internet-identity-vite-plugins"; +import { readReplicaPort } from "@dfinity/internet-identity-vite-plugins/utils"; import basicSsl from "@vitejs/plugin-basic-ssl"; import { resolve } from "path"; import { AliasOptions, UserConfig, defineConfig } from "vite"; @@ -18,7 +19,7 @@ export const aliasConfig: AliasOptions = { $showcase: resolve(__dirname, "src/showcase/src"), }; -export default defineConfig(({ mode }: UserConfig): UserConfig => { +export default defineConfig(({ command, mode }): UserConfig => { // Expand process.env variables with default values to ensure build reproducibility process.env = { ...process.env, @@ -28,6 +29,13 @@ export default defineConfig(({ mode }: UserConfig): UserConfig => { II_VERSION: `${process.env.II_VERSION ?? ""}`, }; + // Astro gets a bit confused and tries to load the server config (including devserver-only + // plugins) on build. This ensures that plugins that need dfx are only invoked on serve. + // https://github.com/withastro/astro/issues/10262 + const isAstro = + process.env["npm_lifecycle_script"]?.includes("astro") === true; + const isServe = command === "serve" && !isAstro; + // Path "../../" have to be expressed relative to the "root". // e.g. // root = src/frontend @@ -72,24 +80,29 @@ export default defineConfig(({ mode }: UserConfig): UserConfig => { ], [...(mode === "production" ? [minifyHTML(), compression()] : [])], [...(process.env.TLS_DEV_SERVER === "1" ? [basicSsl()] : [])], - replicaForwardPlugin({ - replicaOrigin: "127.0.0.1:4943", - forwardDomains: ["icp0.io", "ic0.app"], - forwardRules: [ - { - hosts: ["nice-name.com"], - canisterName: "test_app", - }, - ...(process.env.NO_HOT_RELOAD === "1" - ? [ - { - hosts: ["identity.ic0.app", "identity.internetcomputer.org"], - canisterName: "internet_identity", - }, - ] - : []), - ], - }), + { + ...replicaForwardPlugin({ + forwardDomains: ["icp0.io", "ic0.app"], + forwardRules: [ + { + hosts: ["nice-name.com"], + canisterName: "test_app", + }, + ...(process.env.NO_HOT_RELOAD === "1" + ? [ + { + hosts: [ + "identity.ic0.app", + "identity.internetcomputer.org", + ], + canisterName: "internet_identity", + }, + ] + : []), + ], + }), + apply: () => isServe, + }, ], optimizeDeps: { esbuildOptions: { @@ -98,11 +111,13 @@ export default defineConfig(({ mode }: UserConfig): UserConfig => { }, }, }, - server: { - https: process.env.TLS_DEV_SERVER === "1", - proxy: { - "/api": "http://127.0.0.1:4943", - }, - }, + server: !isServe + ? {} + : { + https: process.env.TLS_DEV_SERVER === "1", + proxy: { + "/api": `http://127.0.0.1:${readReplicaPort()}`, + }, + }, }; });