From d7fb4b6004bd346be4f8966b0a9ae8982c02cce4 Mon Sep 17 00:00:00 2001 From: Mark Anthony Cianfrani Date: Thu, 16 Nov 2023 10:30:56 -0500 Subject: [PATCH] feat: support external esm module scripts --- sandpack-client/src/clients/runtime/types.ts | 3 +- sandpack-client/src/clients/static/index.ts | 38 ++++++++++++------- sandpack-client/src/types.ts | 7 +++- sandpack-react/src/types.ts | 6 ++- .../docs/src/pages/advanced-usage/client.mdx | 2 +- 5 files changed, 38 insertions(+), 18 deletions(-) diff --git a/sandpack-client/src/clients/runtime/types.ts b/sandpack-client/src/clients/runtime/types.ts index ceb01998f..669248c07 100644 --- a/sandpack-client/src/clients/runtime/types.ts +++ b/sandpack-client/src/clients/runtime/types.ts @@ -11,6 +11,7 @@ import type { SandpackErrorMessage, SandpackLogLevel, SandpackMessageConsoleMethods, + ExternalScriptResource } from "../.."; export type SandpackRuntimeMessage = BaseSandpackMessage & @@ -66,7 +67,7 @@ export type SandpackRuntimeMessage = BaseSandpackMessage & version: number; isInitializationCompile?: boolean; modules: Modules; - externalResources: string[]; + externalResources?: Array; hasFileResolver: boolean; disableDependencyPreprocessing?: boolean; template?: string | ITemplate; diff --git a/sandpack-client/src/clients/static/index.ts b/sandpack-client/src/clients/static/index.ts index 6038a8a55..09e1b92c8 100644 --- a/sandpack-client/src/clients/static/index.ts +++ b/sandpack-client/src/clients/static/index.ts @@ -5,6 +5,7 @@ import { PreviewController } from "static-browser-server"; import type { ClientOptions, + ExternalScriptResource, ListenerFunction, SandboxSetup, UnsubscribeFunction, @@ -132,26 +133,37 @@ export class SandpackStatic extends SandpackClient { ): FileContent { const tagsToInsert = externalResources .map((resource) => { - const match = resource.match(/\.([^.]*)$/); - const fileType = match?.[1]; - - if (fileType === "css" || resource.includes("fonts.googleapis")) { - return ``; - } - - if (fileType === "js") { - return ``; + if (this.isScriptResource(resource)) { + return ``; + } else { + const match = resource.match(/\.([^.]*)$/); + const fileType = match?.[1]; + + if (fileType === "css" || resource.includes("fonts.googleapis")) { + return ``; + } + + if (fileType === "js") { + return ``; + } + + throw new Error( + `Unable to determine file type for external resource: ${resource}` + ); } - - throw new Error( - `Unable to determine file type for external resource: ${resource}` - ); }) .join("\n"); return this.injectContentIntoHead(content, tagsToInsert); } + private isScriptResource(resource: unknown): resource is ExternalScriptResource { + return typeof resource === 'object' + && resource !== null + && 'type' in resource + && 'src' in resource; + } + private injectScriptIntoHead( content: FileContent, opts: { diff --git a/sandpack-client/src/types.ts b/sandpack-client/src/types.ts index 4e6c0cc87..13e30968b 100644 --- a/sandpack-client/src/types.ts +++ b/sandpack-client/src/types.ts @@ -5,7 +5,7 @@ export interface ClientOptions { /** * Paths to external resources */ - externalResources?: string[]; + externalResources?: Array; /** * Location of the bundler. */ @@ -72,6 +72,11 @@ export interface ClientOptions { teamId?: string; } +export interface ExternalScriptResource { + type: "module" | "importmap" | undefined; + src: string; +} + export interface SandboxSetup { files: SandpackBundlerFiles; dependencies?: Dependencies; diff --git a/sandpack-react/src/types.ts b/sandpack-react/src/types.ts index f3448a7fd..61f647c7f 100644 --- a/sandpack-react/src/types.ts +++ b/sandpack-react/src/types.ts @@ -12,6 +12,7 @@ import type { UnsubscribeFunction, SandpackLogLevel, NpmRegistry, + ExternalScriptResource } from "@codesandbox/sandpack-client"; import type React from "react"; @@ -171,7 +172,8 @@ export interface SandpackOptions { startRoute?: string; skipEval?: boolean; fileResolver?: FileResolver; - externalResources?: string[]; + + externalResources?: Array; } /** @@ -460,7 +462,7 @@ export interface SandpackInternalOptions< startRoute?: string; skipEval?: boolean; fileResolver?: FileResolver; - externalResources?: string[]; + externalResources?: Array; classes?: Record; } diff --git a/website/docs/src/pages/advanced-usage/client.mdx b/website/docs/src/pages/advanced-usage/client.mdx index 2de944c65..2103bf806 100644 --- a/website/docs/src/pages/advanced-usage/client.mdx +++ b/website/docs/src/pages/advanced-usage/client.mdx @@ -291,7 +291,7 @@ The `getCodeSandboxURL` method creates a sandbox from the current files and retu /** * Paths to external resources */ - externalResources?: string[]; + externalResources?: Array; /** * Location of the bundler. Defaults to `${version}-sandpack.codesandbox.io` */