@@ -9,12 +9,86 @@ const path = require('path');
9
9
const { transformFileAsync } = require ( '@babel/core' ) ;
10
10
const pretty = require ( 'pretty' ) ;
11
11
12
+ // Paths
12
13
const EXAMPLES = path . resolve ( __dirname , '../..' ) ;
14
+ const SPECTACLE_PATH = path . resolve ( __dirname , '../../../packages/spectacle' ) ;
13
15
const SRC_FILE = path . join ( EXAMPLES , 'js/index.js' ) ;
14
16
const DEST_FILE = path . join ( EXAMPLES , 'one-page/index.html' ) ;
15
17
18
+ // Dependencies.
19
+ const ESM_SH_VERSION = 'v121' ; // v121, stable, etc.
20
+ const {
21
+ dependencies,
22
+ peerDependencies
23
+ } = require ( `${ SPECTACLE_PATH } /package.json` ) ;
24
+ const reactPkgPath = require . resolve ( 'react/package.json' , {
25
+ paths : [ SPECTACLE_PATH ]
26
+ } ) ;
27
+ const { version : reactVersion } = require ( reactPkgPath ) ;
28
+ const DEPS = `deps=react@${ reactVersion } ` ;
29
+
30
+ // Toggle dev resources. (Use if debugging load / dependency errors).
31
+ const IS_DEV = false ;
32
+ const DEV = IS_DEV ? '&dev' : '' ;
33
+
34
+ // Use local built spectacle? Toggle to `true` for dev-only.
35
+ // Note: Due to CORS, you'll need to run `pnpm run --filter ./examples/one-page start` and
36
+ // open http://localhost:5000/examples/one-page to work.
37
+ const USE_LOCAL = false ;
38
+
39
+ // ================================================================================================
40
+ // Import Map
41
+ // ================================================================================================
42
+ const importUrl = ( k , v , extra = '' ) => {
43
+ // Pin react.
44
+ if ( k === 'react' ) {
45
+ v = reactVersion ;
46
+ }
47
+
48
+ return `https://esm.sh/${ ESM_SH_VERSION } /${ k } @${ v } ${ extra } ?${ DEPS } ${ DEV } ` ;
49
+ } ;
50
+
51
+ const getImportMap = ( ) => {
52
+ // Start with extra imports for one-page alone.
53
+ const importMap = {
54
+ htm : importUrl ( 'htm' , '^3' ) ,
55
+ spectacle : USE_LOCAL
56
+ ? '../../packages/spectacle/lib/index.mjs'
57
+ : importUrl ( 'spectacle' , '^10' )
58
+ } ;
59
+
60
+ Object . entries ( Object . assign ( { } , dependencies , peerDependencies ) )
61
+ . sort ( ( a , b ) => a [ 0 ] . localeCompare ( b [ 0 ] ) )
62
+ . forEach ( ( [ k , v ] ) => {
63
+ // General
64
+ importMap [ k ] = importUrl ( k , v ) ;
65
+
66
+ // Special case internal deps
67
+ if ( k === 'react' ) {
68
+ importMap [ `${ k } /jsx-runtime` ] = importUrl ( k , v , '/jsx-runtime' ) ;
69
+ }
70
+ if ( k === 'react-syntax-highlighter' ) {
71
+ importMap [ `${ k } /dist/cjs/styles/prism/vs-dark.js` ] = importUrl (
72
+ k ,
73
+ v ,
74
+ '/dist/esm/styles/prism/vs-dark.js'
75
+ ) ;
76
+ importMap [ `${ k } /dist/cjs/styles/prism/index.js` ] = importUrl (
77
+ k ,
78
+ v ,
79
+ '/dist/esm/styles/prism/index.js'
80
+ ) ;
81
+ }
82
+ } ) ;
83
+
84
+ return importMap ;
85
+ } ;
86
+
87
+ // ================================================================================================
88
+ // Rewriting
89
+ // ================================================================================================
16
90
const htmImport = `
17
- import htm from 'https://unpkg.com/ htm@^3?module ';
91
+ import htm from 'htm';
18
92
const html = htm.bind(React.createElement);
19
93
`
20
94
. replace ( / / gm, '' )
@@ -27,7 +101,7 @@ const spectacleImportReplacer = (match, imports) => {
27
101
. map ( ( i ) => ` ${ i . trim ( ) } ` )
28
102
. join ( `,\n` ) ;
29
103
30
- return `const {\n${ imports } \n} = Spectacle ;\n\n${ htmImport } ` ;
104
+ return `import {\n${ imports } \n} from 'spectacle' ;\n\n${ htmImport } ` ;
31
105
} ;
32
106
33
107
const getSrcContent = async ( src ) => {
@@ -40,7 +114,6 @@ const getSrcContent = async (src) => {
40
114
// Mutate exports and comments.
41
115
code = code
42
116
// Mutate exports to our global imports.
43
- . replace ( / i m p o r t R e a c t ( | D O M ) f r o m ' r e a c t ( | - d o m ) ' ; [ \n ] * / gm, '' )
44
117
. replace ( / i m p o r t { [ ] * ( .* ) } f r o m ' s p e c t a c l e ' ; / , spectacleImportReplacer )
45
118
// Hackily fix / undo babel's poor control comment placment.
46
119
. replace ( / \/ \/ S P E C T A C L E _ C L I / gm, '\n// SPECTACLE_CLI' )
@@ -84,17 +157,27 @@ const getSrcContent = async (src) => {
84
157
return code ;
85
158
} ;
86
159
160
+ // ================================================================================================
161
+ // Output
162
+ // ================================================================================================
87
163
const writeDestContent = async ( destFile , code ) => {
88
164
// Format for indentation in index.html.
89
165
const indent = ' ' ;
90
- code = `${ indent } ${ code } ` ;
91
- code = code . split ( '\n' ) . join ( `\n${ indent } ` ) ;
166
+ code = `${ indent } ${ code . split ( '\n' ) . join ( `\n${ indent } ` ) } ` ;
167
+
168
+ // Import map
169
+ let importMap = JSON . stringify ( { imports : getImportMap ( ) } , null , 2 ) ;
170
+ importMap = `${ indent } ${ importMap . split ( '\n' ) . join ( `\n${ indent } ` ) } ` ;
92
171
93
172
// Get destination content.
94
173
let destContent = ( await fs . readFile ( destFile ) ) . toString ( ) ;
95
174
96
175
// Mutate in our updated code.
97
176
destContent = destContent
177
+ . replace (
178
+ / ( < s c r i p t t y p e = " i m p o r t m a p " > \n ) [ \s \S ] * ?( \n [ ] * < \/ s c r i p t > ) / m,
179
+ ( match , open , close ) => `${ open } ${ importMap } ${ close } `
180
+ )
98
181
. replace (
99
182
/ ( < s c r i p t t y p e = " m o d u l e " > \n ) [ \s \S ] * ?( \n [ ] * < \/ s c r i p t > \n [ ] * < \/ b o d y > \n [ ] * < \/ h t m l > ) / m,
100
183
( match , open , close ) => `${ open } ${ code } ${ close } `
0 commit comments