Skip to content

Commit

Permalink
Update to use new EESM/importmap one page
Browse files Browse the repository at this point in the history
  • Loading branch information
carloskelly13 committed Nov 18, 2023
1 parent 74c18f4 commit 107991b
Show file tree
Hide file tree
Showing 6 changed files with 919 additions and 364 deletions.
5 changes: 5 additions & 0 deletions .changeset/calm-pianos-confess.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'create-spectacle': minor
---

Update the create-spectacle CLI to use new ESM/import map-based one page.
2 changes: 2 additions & 0 deletions packages/create-spectacle/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
"cli-spinners": "^2.6.1",
"log-update": "4.0.0",
"prompts": "^2.4.2",
"ts-node": "^10.9.1",
"yargs": "^17.5.1"
},
"devDependencies": {
Expand All @@ -29,6 +30,7 @@
},
"resolutions": {},
"scripts": {
"dev": "ts-node src/cli.ts",
"build": "wireit",
"types:check": "wireit",
"lint": "wireit",
Expand Down
57 changes: 57 additions & 0 deletions packages/create-spectacle/src/generators/one-page.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import path from 'path';
import { onePageTemplate } from '../templates/one-page';

const SPECTACLE_PATH = path.resolve(__dirname, '../../../spectacle');
const REACT_VERSION = '18.2.0';
const ESM_SH_VERSION = 'v121';

export const createOnePage = async (name: string, lang: string) => {
const importMap = new Map<string, string>();
const {
dependencies,
peerDependencies
} = require(`${SPECTACLE_PATH}/package.json`);

importMap.set('htm', importUrl('htm', '^3'));
importMap.set('spectacle', 'https://esm.sh/spectacle@10?bundle');

const sortedDeps = <[string, string][]>Object.entries({
...dependencies,
...peerDependencies
}).sort(([a], [b]) => a.localeCompare(b));

for (const [pkg, version] of sortedDeps) {
if (importMap.has(pkg)) continue;
importMap.set(pkg, importUrl(pkg, version));
handlePackageExceptions(pkg, version, importMap);
}

return onePageTemplate({ importMap: importMap.entries(), name, lang });
};

const importUrl = (pkg: string, version: string, extra = '') => {
if (pkg === 'react') version = '18.2.0';
return `https://esm.sh/${ESM_SH_VERSION}/${pkg}@${version}${extra}?deps=react@${REACT_VERSION}`;
};

const handlePackageExceptions = (
pkg: string,
version: string,
importMap: Map<string, string>
) => {
if (pkg === 'react')
importMap.set(
`${pkg}/jsx-runtime`,
importUrl(pkg, version, '/jsx-runtime')
);
else if (pkg === 'react-syntax-highlighter') {
importMap.set(
`${pkg}/dist/cjs/styles/prism/vs-dark.js`,
importUrl(pkg, version, '/dist/esm/styles/prism/vs-dark.js')
);
importMap.set(
`${pkg}/dist/cjs/styles/prism/index.js`,
importUrl(pkg, version, '/dist/esm/styles/prism/index.js')
);
}
};
3 changes: 2 additions & 1 deletion packages/create-spectacle/src/templates/file-writers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { tsconfigTemplate } from './tsconfig';
import { gitignoreTemplate } from './gitignore';
import { readmeTemplate } from './readme';
import { viteConfigTemplate } from './viteConfig';
import { createOnePage } from '../generators/one-page';

export type FileOptions = {
snakeCaseName: string;
Expand Down Expand Up @@ -121,6 +122,6 @@ export const writeOnePageHTMLFile = async ({
}: FileOptions) => {
await writeFile(
path.resolve(process.cwd(), `${snakeCaseName}.html`),
onePageTemplate({ name, lang })
await createOnePage(name, lang)
);
};
33 changes: 23 additions & 10 deletions packages/create-spectacle/src/templates/one-page.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
type OnePageTemplateOptions = {
name: string;
lang: string;
importMap: IterableIterator<[string, string]>;
};

export const onePageTemplate = ({ name, lang }: OnePageTemplateOptions) => `
export const onePageTemplate = ({
name,
lang,
importMap
}: OnePageTemplateOptions) => `
<!DOCTYPE html>
<html lang="${lang}">
<head>
Expand All @@ -15,26 +20,34 @@ export const onePageTemplate = ({ name, lang }: OnePageTemplateOptions) => `
<body>
<div id="root"></div>
<script src="https://unpkg.com/[email protected]/umd/react.production.min.js"></script>
<script src="https://unpkg.com/[email protected]/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/[email protected]/umd/react-is.production.min.js"></script>
<script src="https://unpkg.com/[email protected]/prop-types.min.js"></script>
<script src="https://unpkg.com/spectacle@^9/dist/spectacle.min.js"></script>
<script type="importmap">
{
"imports": {
${Array.from(importMap)
.map(([pkg, url]) => `"${pkg}": "${url}"`)
.join(',\n')}
}
}
</script>
<script type="module">
const {
import htm from 'htm';
import React from 'react';
import ReactDOM from 'react-dom';
import {
FlexBox,
Heading,
SpectacleLogo,
Slide,
Deck,
} = Spectacle;
DefaultTemplate
} from 'spectacle';
import htm from 'https://unpkg.com/htm@^3?module';
const html = htm.bind(React.createElement);
const template = () => html\`<\${DefaultTemplate} />\`;
const Presentation = () => html\`
<\${Deck}>
<\${Deck} template=\${template}>
<\${Slide}>
<\${FlexBox} height="100%">
<\${Heading}>${name}</\${Heading}>
Expand Down
Loading

0 comments on commit 107991b

Please sign in to comment.