Skip to content

Commit 4dc457d

Browse files
committed
workflow(sfc-playground): make it work in safari and ff
1 parent 5ee7e6b commit 4dc457d

File tree

3 files changed

+51
-19
lines changed

3 files changed

+51
-19
lines changed

packages/sfc-playground/src/output/Preview.vue

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -96,27 +96,38 @@ function createSandbox() {
9696
}
9797
importMap.imports.vue = vueRuntimeUrl.value
9898
const sandboxSrc = srcdoc.replace(/<!--IMPORT_MAP-->/, JSON.stringify(importMap))
99-
sandbox.setAttribute('srcdoc', sandboxSrc)
99+
sandbox.srcdoc = sandboxSrc
100100
container.value.appendChild(sandbox)
101101
102102
proxy = new PreviewProxy(sandbox, {
103103
on_fetch_progress: (progress: any) => {
104104
// pending_imports = progress;
105105
},
106106
on_error: (event: any) => {
107-
runtimeError.value = event.value
107+
const msg = event.value instanceof Error ? event.value.message : event.value
108+
if (
109+
msg.includes('Failed to resolve module specifier') ||
110+
msg.includes('Error resolving module specifier')
111+
) {
112+
runtimeError.value = msg.replace(/\. Relative references must.*$/, '') +
113+
`.\nTip: add an "import-map.json" file to specify import paths for dependencies.`
114+
} else {
115+
runtimeError.value = event.value
116+
}
108117
},
109118
on_unhandled_rejection: (event: any) => {
110119
let error = event.value
111-
if (typeof error === 'string') error = { message: error }
120+
if (typeof error === 'string') {
121+
error = { message: error }
122+
}
112123
runtimeError.value = 'Uncaught (in promise): ' + error.message
113124
},
114125
on_console: (log: any) => {
115126
if (log.level === 'error') {
116127
if (log.args[0] instanceof Error) {
117-
runtimeError.value = log.args[0].stack
128+
runtimeError.value = log.args[0].message
118129
} else {
119-
runtimeError.value = log.args
130+
runtimeError.value = log.args[0]
120131
}
121132
} else if (log.level === 'warn') {
122133
if (log.args[0].toString().includes('[Vue warn]')) {
@@ -145,6 +156,7 @@ function createSandbox() {
145156
}
146157
147158
async function updatePreview() {
159+
console.clear()
148160
runtimeError.value = null
149161
runtimeWarning.value = null
150162
try {
@@ -168,7 +180,7 @@ app.config.errorHandler = e => console.error(e)
168180
app.mount('#app')`.trim()
169181
])
170182
} catch (e) {
171-
runtimeError.value = e.stack
183+
runtimeError.value = e.message
172184
}
173185
}
174186
</script>

packages/sfc-playground/src/output/srcdoc.html

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,6 @@
88
}
99
</style>
1010
<style id="__sfc-styles"></style>
11-
12-
<!-- ES Module Shims: Import maps polyfill for modules browsers without import maps support (all except Chrome 89+) -->
13-
<script async src="https://ga.jspm.io/npm:[email protected]/dist/es-module-shims.min.js"></script>
14-
<script id="map" type="importmap"><!--IMPORT_MAP--></script>
15-
1611
<script>
1712
(() => {
1813
let scriptEls = []
@@ -55,12 +50,12 @@
5550
scriptEl.setAttribute('type', 'module')
5651
// send ok in the module script to ensure sequential evaluation
5752
// of multiple proxy.eval() calls
58-
const done = new Promise((resolve, reject) => {
53+
const done = new Promise((resolve) => {
5954
window.__next__ = resolve
60-
scriptEl.onerror = reject
6155
})
6256
scriptEl.innerHTML = script + `\nwindow.__next__()`
6357
document.head.appendChild(scriptEl)
58+
scriptEl.onrror = err => send_error(err.message, err.stack)
6459
scriptEls.push(scriptEl)
6560
await done
6661
}
@@ -108,11 +103,27 @@
108103
window.addEventListener('message', handle_message, false);
109104

110105
window.onerror = function (msg, url, lineNo, columnNo, error) {
111-
parent.postMessage({ action: 'error', value: error }, '*');
106+
if (msg.includes('module specifier “vue”')) {
107+
// firefox only error, ignore
108+
return false
109+
}
110+
try {
111+
parent.postMessage({ action: 'error', value: error }, '*');
112+
} catch (e) {
113+
parent.postMessage({ action: 'error', value: msg }, '*');
114+
}
112115
}
113116

114117
window.addEventListener("unhandledrejection", event => {
115-
parent.postMessage({ action: 'unhandledrejection', value: event.reason }, '*');
118+
if (event.reason.message.includes('Cross-origin')) {
119+
event.preventDefault()
120+
return
121+
}
122+
try {
123+
parent.postMessage({ action: 'unhandledrejection', value: event.reason }, '*');
124+
} catch (e) {
125+
parent.postMessage({ action: 'unhandledrejection', value: event.reason.message }, '*');
126+
}
116127
});
117128

118129
let previous = { level: null, args: null };
@@ -121,7 +132,10 @@
121132
const original = console[level];
122133
console[level] = (...args) => {
123134
const msg = String(args[0])
124-
if (msg.includes('You are running a development build of Vue')) {
135+
if (
136+
msg.includes('You are running a development build of Vue') ||
137+
msg.includes('You are running the esm-bundler build of Vue')
138+
) {
125139
return
126140
}
127141
const stringifiedArgs = stringify(args);
@@ -137,7 +151,9 @@
137151
try {
138152
parent.postMessage({ action: 'console', level, args }, '*');
139153
} catch (err) {
140-
parent.postMessage({ action: 'console', level: 'unclonable' }, '*');
154+
parent.postMessage({ action: 'console', level, args: args.map(a => {
155+
return a instanceof Error ? a.message : String(a)
156+
}) }, '*');
141157
}
142158
}
143159

@@ -232,6 +248,10 @@
232248
}
233249
})()
234250
</script>
251+
252+
<!-- ES Module Shims: Import maps polyfill for modules browsers without import maps support (all except Chrome 89+) -->
253+
<script async src="https://unpkg.com/[email protected]/dist/es-module-shims.js"></script>
254+
<script type="importmap"><!--IMPORT_MAP--></script>
235255
</head>
236256
<body>
237257
<div id="app"></div>

packages/sfc-playground/src/sfcCompiler.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ let SFCCompiler: typeof defaultCompiler = defaultCompiler
1414

1515
// @ts-ignore
1616
const defaultVueUrl = import.meta.env.PROD
17-
? '/vue.runtime.esm-browser.js' // to be copied on build
18-
: '/src/vue-dev-proxy'
17+
? `${___location.origin}/vue.runtime.esm-browser.js` // to be copied on build
18+
: `${___location.origin}/src/vue-dev-proxy`
1919

2020
export const vueRuntimeUrl = ref(defaultVueUrl)
2121

0 commit comments

Comments
 (0)