Skip to content

Commit

Permalink
feat: support external esm module scripts
Browse files Browse the repository at this point in the history
  • Loading branch information
markacianfrani committed Nov 16, 2023
1 parent 6b57249 commit d7fb4b6
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 18 deletions.
3 changes: 2 additions & 1 deletion sandpack-client/src/clients/runtime/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import type {
SandpackErrorMessage,
SandpackLogLevel,
SandpackMessageConsoleMethods,
ExternalScriptResource
} from "../..";

export type SandpackRuntimeMessage = BaseSandpackMessage &
Expand Down Expand Up @@ -66,7 +67,7 @@ export type SandpackRuntimeMessage = BaseSandpackMessage &
version: number;
isInitializationCompile?: boolean;
modules: Modules;
externalResources: string[];
externalResources?: Array<string | ExternalScriptResource>;
hasFileResolver: boolean;
disableDependencyPreprocessing?: boolean;
template?: string | ITemplate;
Expand Down
38 changes: 25 additions & 13 deletions sandpack-client/src/clients/static/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { PreviewController } from "static-browser-server";

import type {
ClientOptions,
ExternalScriptResource,
ListenerFunction,
SandboxSetup,
UnsubscribeFunction,
Expand Down Expand Up @@ -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 `<link rel="stylesheet" href="${resource}">`;
}

if (fileType === "js") {
return `<script src="${resource}"></script>`;
if (this.isScriptResource(resource)) {
return `<script type="${resource.type}" src="${resource.src}"></script>`;
} else {
const match = resource.match(/\.([^.]*)$/);
const fileType = match?.[1];

if (fileType === "css" || resource.includes("fonts.googleapis")) {
return `<link rel="stylesheet" href="${resource}">`;
}

if (fileType === "js") {
return `<script src="${resource}"></script>`;
}

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: {
Expand Down
7 changes: 6 additions & 1 deletion sandpack-client/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ export interface ClientOptions {
/**
* Paths to external resources
*/
externalResources?: string[];
externalResources?: Array<string | ExternalScriptResource>;
/**
* Location of the bundler.
*/
Expand Down Expand Up @@ -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;
Expand Down
6 changes: 4 additions & 2 deletions sandpack-react/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import type {
UnsubscribeFunction,
SandpackLogLevel,
NpmRegistry,
ExternalScriptResource
} from "@codesandbox/sandpack-client";
import type React from "react";

Expand Down Expand Up @@ -171,7 +172,8 @@ export interface SandpackOptions {
startRoute?: string;
skipEval?: boolean;
fileResolver?: FileResolver;
externalResources?: string[];

externalResources?: Array<string | ExternalScriptResource>;
}

/**
Expand Down Expand Up @@ -460,7 +462,7 @@ export interface SandpackInternalOptions<
startRoute?: string;
skipEval?: boolean;
fileResolver?: FileResolver;
externalResources?: string[];
externalResources?: Array<string | ExternalScriptResource>;
classes?: Record<string, string>;
}

Expand Down
2 changes: 1 addition & 1 deletion website/docs/src/pages/advanced-usage/client.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,7 @@ The `getCodeSandboxURL` method creates a sandbox from the current files and retu
/**
* Paths to external resources
*/
externalResources?: string[];
externalResources?: Array<string | ExternalScriptResource>;
/**
* Location of the bundler. Defaults to `${version}-sandpack.codesandbox.io`
*/
Expand Down

0 comments on commit d7fb4b6

Please sign in to comment.