devjar 0.3.1 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/core.mjs +106 -34
- package/lib/module.mjs +6 -4
- package/package.json +5 -5
package/lib/core.mjs
CHANGED
|
@@ -15,33 +15,68 @@ function transformCode(_code, getModuleUrl, externals) {
|
|
|
15
15
|
return replaceImports(code, getModuleUrl, externals)
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
function replaceImports(
|
|
18
|
+
function replaceImports(source, getModuleUrl, externals) {
|
|
19
19
|
let code = ''
|
|
20
20
|
let lastIndex = 0
|
|
21
21
|
let hasReactImports = false
|
|
22
|
-
const [imports] = parse(
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
code +=
|
|
30
|
-
|
|
22
|
+
const [imports] = parse(source)
|
|
23
|
+
const cssImports = []
|
|
24
|
+
let cssImportIndex = 0
|
|
25
|
+
|
|
26
|
+
// start, end, statementStart, statementEnd, assertion, name
|
|
27
|
+
imports.forEach(({ s, e, ss, se, a, n }) => {
|
|
28
|
+
let isCss = false
|
|
29
|
+
code += source.slice(lastIndex, ss) // content from last import to beginning of this line
|
|
30
|
+
|
|
31
31
|
|
|
32
|
+
// handle imports
|
|
33
|
+
if (n.endsWith('.css')) {
|
|
34
|
+
isCss = true
|
|
35
|
+
// Map './styles.css' -> '@styles.css', and collect it
|
|
36
|
+
const cssPath = `${'@' + n.slice(2)}`
|
|
37
|
+
cssImports.push(cssPath)
|
|
38
|
+
|
|
39
|
+
} else {
|
|
40
|
+
code += source.substring(ss, s)
|
|
41
|
+
code += isRelative(n)
|
|
42
|
+
? ('@' + n.slice(2))
|
|
43
|
+
: externals.has(n) ? n : getModuleUrl(n)
|
|
44
|
+
code += source.substring(e, se)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
lastIndex = se
|
|
32
48
|
|
|
33
49
|
if (n === 'react') {
|
|
34
|
-
const statement =
|
|
50
|
+
const statement = source.slice(ss, se)
|
|
35
51
|
if (statement.includes('React')) {
|
|
36
52
|
hasReactImports = true
|
|
37
53
|
}
|
|
38
54
|
}
|
|
55
|
+
|
|
56
|
+
cssImports.forEach(cssPath => {
|
|
57
|
+
code += `\nimport sheet${cssImportIndex} from "${cssPath}" assert { type: "css" };\n`
|
|
58
|
+
cssImportIndex++
|
|
59
|
+
})
|
|
39
60
|
})
|
|
40
|
-
|
|
61
|
+
|
|
62
|
+
if (cssImports.length) {
|
|
63
|
+
code += `const __customStyleSheets = [`
|
|
64
|
+
for (let i = 0; i < cssImports.length; i++) {
|
|
65
|
+
code += `sheet${i}`
|
|
66
|
+
if (i < cssImports.length - 1) {
|
|
67
|
+
code += `, `
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
code += `];\n`
|
|
71
|
+
code += `document.adoptedStyleSheets = [...document.adoptedStyleSheets, ...__customStyleSheets];\n`
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
code += source.substring(lastIndex)
|
|
41
75
|
|
|
42
76
|
if (!hasReactImports) {
|
|
43
77
|
code = `import React from 'react';\n${code}`
|
|
44
78
|
}
|
|
79
|
+
|
|
45
80
|
return code
|
|
46
81
|
}
|
|
47
82
|
|
|
@@ -101,11 +136,31 @@ globalThis.__render__ = _createRenderer(_createModule, getModuleUrl);
|
|
|
101
136
|
return code
|
|
102
137
|
}
|
|
103
138
|
|
|
139
|
+
function createEsShimOptionsScript() {
|
|
140
|
+
return `window.esmsInitOptions = {
|
|
141
|
+
polyfillEnable: ['css-modules', 'json-modules'],
|
|
142
|
+
onerror: error => console.log(error),
|
|
143
|
+
}`
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
function useScript() {
|
|
147
|
+
return useRef(typeof window !== 'undefined' ? document.createElement('script') : null)
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
function setScript(scriptRef, scriptContent, { type } = {}) {
|
|
151
|
+
const script = scriptRef.current
|
|
152
|
+
if (type) script.type = type
|
|
153
|
+
|
|
154
|
+
script.src = `data:text/javascript;utf-8,${encodeURIComponent(scriptContent)}`
|
|
155
|
+
return script
|
|
156
|
+
}
|
|
157
|
+
|
|
104
158
|
function useLiveCode({ getModuleUrl }) {
|
|
105
159
|
const iframeRef = useRef()
|
|
106
160
|
const [error, setError] = useState()
|
|
107
161
|
const rerender = useState({})[1]
|
|
108
|
-
const
|
|
162
|
+
const appScriptRef = useScript()
|
|
163
|
+
const esShimOptionsScript = useScript()
|
|
109
164
|
const uid = useId()
|
|
110
165
|
|
|
111
166
|
// Let getModuleUrl executed on parent window side since it might involve
|
|
@@ -127,27 +182,31 @@ function useLiveCode({ getModuleUrl }) {
|
|
|
127
182
|
|
|
128
183
|
useEffect(() => {
|
|
129
184
|
const iframe = iframeRef.current
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
185
|
+
if (!iframe || !iframe.contentDocument) return
|
|
186
|
+
|
|
187
|
+
const doc = iframe.contentDocument
|
|
188
|
+
const div = document.createElement('div')
|
|
189
|
+
div.id = 'root'
|
|
190
|
+
|
|
191
|
+
const appScriptContent = createMainScript({ uid })
|
|
192
|
+
const scriptOptionsContent = createEsShimOptionsScript()
|
|
193
|
+
|
|
194
|
+
const esmShimOptionsScript = setScript(esShimOptionsScript, scriptOptionsContent)
|
|
195
|
+
const appScript = setScript(appScriptRef, appScriptContent, { type: 'module' })
|
|
196
|
+
// const script = scriptRef.current
|
|
197
|
+
// script.type = 'module'
|
|
198
|
+
// script.id = 'main'
|
|
199
|
+
// script.src = `data:text/javascript;utf-8,${encodeURIComponent(scriptContent)}`
|
|
137
200
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
doc.body.appendChild(div)
|
|
144
|
-
doc.body.appendChild(script)
|
|
145
|
-
}
|
|
201
|
+
doc.body.appendChild(div)
|
|
202
|
+
doc.body.appendChild(esmShimOptionsScript)
|
|
203
|
+
doc.body.appendChild(appScript)
|
|
204
|
+
|
|
146
205
|
return () => {
|
|
147
|
-
if (iframe)
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
206
|
+
if (!iframe || !iframe.contentDocument) return
|
|
207
|
+
doc.body.removeChild(div)
|
|
208
|
+
doc.body.removeChild(esmShimOptionsScript)
|
|
209
|
+
doc.body.removeChild(appScript)
|
|
151
210
|
}
|
|
152
211
|
}, [])
|
|
153
212
|
|
|
@@ -158,6 +217,7 @@ function useLiveCode({ getModuleUrl }) {
|
|
|
158
217
|
}
|
|
159
218
|
|
|
160
219
|
if (files) {
|
|
220
|
+
// { 'react', 'react-dom' }
|
|
161
221
|
const overrideExternals =
|
|
162
222
|
new Set(Object.keys(files).filter(name => !isRelative(name) && name !== 'index.js'))
|
|
163
223
|
|
|
@@ -166,14 +226,25 @@ function useLiveCode({ getModuleUrl }) {
|
|
|
166
226
|
overrideExternals.add('react-dom')
|
|
167
227
|
|
|
168
228
|
try {
|
|
229
|
+
/**
|
|
230
|
+
* transformedFiles
|
|
231
|
+
* {
|
|
232
|
+
* 'index.js': '...',
|
|
233
|
+
* '@mod1': '...',
|
|
234
|
+
* '@mod2': '...',
|
|
235
|
+
*/
|
|
169
236
|
const transformedFiles = Object.keys(files).reduce((res, filename) => {
|
|
170
237
|
const key = isRelative(filename) ? ('@' + filename.slice(2)) : filename
|
|
171
|
-
|
|
238
|
+
if (filename.endsWith('.css')) {
|
|
239
|
+
res[key] = files[filename]
|
|
240
|
+
} else {
|
|
241
|
+
res[key] = transformCode(files[filename], getModuleUrl, overrideExternals)
|
|
242
|
+
}
|
|
172
243
|
return res
|
|
173
244
|
}, {})
|
|
174
245
|
|
|
175
246
|
const iframe = iframeRef.current
|
|
176
|
-
const script =
|
|
247
|
+
const script = appScriptRef.current
|
|
177
248
|
if (iframe) {
|
|
178
249
|
const render = iframe.contentWindow.__render__
|
|
179
250
|
if (render) {
|
|
@@ -187,6 +258,7 @@ function useLiveCode({ getModuleUrl }) {
|
|
|
187
258
|
}
|
|
188
259
|
setError()
|
|
189
260
|
} catch (e) {
|
|
261
|
+
console.error(e)
|
|
190
262
|
setError(e)
|
|
191
263
|
}
|
|
192
264
|
}
|
package/lib/module.mjs
CHANGED
|
@@ -27,15 +27,17 @@ async function createModule(files, { getModuleUrl }) {
|
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
|
|
30
|
-
function createInlinedModule(code) {
|
|
30
|
+
function createInlinedModule(code, type) {
|
|
31
|
+
if (type === 'css') return `data:text/css;utf-8,${encodeURIComponent(code)}`
|
|
32
|
+
|
|
31
33
|
return `data:text/javascript;utf-8,${encodeURIComponent(code)}`
|
|
32
34
|
}
|
|
33
35
|
|
|
34
36
|
await setupImportMap()
|
|
35
37
|
const imports = Object.fromEntries(
|
|
36
|
-
Object.entries(files).map(([
|
|
37
|
-
|
|
38
|
-
createInlinedModule(code),
|
|
38
|
+
Object.entries(files).map(([fileName, code]) => [
|
|
39
|
+
fileName,
|
|
40
|
+
createInlinedModule(code, fileName.endsWith('.css') ? 'css' : 'js'),
|
|
39
41
|
])
|
|
40
42
|
)
|
|
41
43
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "devjar",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": "./lib/index.mjs",
|
|
@@ -12,9 +12,9 @@
|
|
|
12
12
|
],
|
|
13
13
|
"types": "./lib/index.d.ts",
|
|
14
14
|
"scripts": {
|
|
15
|
-
"build": "next build ./
|
|
16
|
-
"start": "next start ./
|
|
17
|
-
"dev": "next dev ./
|
|
15
|
+
"build:site": "next build ./site",
|
|
16
|
+
"start": "next start ./site",
|
|
17
|
+
"dev": "next dev ./site"
|
|
18
18
|
},
|
|
19
19
|
"peerDependencies": {
|
|
20
20
|
"react": "^18.2.0"
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"codice": "latest",
|
|
29
29
|
"devjar": "link:./",
|
|
30
30
|
"lodash-es": "^4.17.21",
|
|
31
|
-
"next": "^13.
|
|
31
|
+
"next": "^13.2.0",
|
|
32
32
|
"react": "^18.2.0",
|
|
33
33
|
"react-dom": "^18.2.0",
|
|
34
34
|
"sugar-high": "^0.4.5"
|