Skip to content

Commit

Permalink
fix(site): failed to launch codesandbox demo (#4610)
Browse files Browse the repository at this point in the history
* fix(site): `vite` failed to launch `codesandbox`, migrate it to `vue-cli` startup

* chore: hide codesandbox when script with tsx lang

* chore: observer

* chore: observer

* chore: observer

---------

Co-authored-by: Uyarn <uyarnchen@gmail.com>
  • Loading branch information
RSS1102 and uyarn authored Sep 30, 2024
1 parent 03036a1 commit 4c8fa90
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 50 deletions.
2 changes: 1 addition & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,5 @@
"editor.formatOnSave": true,
"editor.defaultFormatter": "dbaeumer.vscode-eslint"
},
"cSpell.words": ["tdesign", "popconfirm", "cascader", "tnode", "backtop", "wechat", "miniprogram","nuxt"]
"cSpell.words": ["tdesign", "popconfirm", "cascader", "tnode", "backtop", "wechat", "miniprogram","nuxt","codesandbox"]
}
4 changes: 2 additions & 2 deletions site/plugin-doc/demo.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ export default function renderDemo(md, container) {
const tpl = `
<td-doc-demo component-name="${componentName.trim()}" demo-name="${demoName}" language="markup" languages="JavaScript,TypeScript" :data-JavaScript="${demoCodeDefName}" :data-TypeScript="${demoTSCodeDefName}">
<div slot="action">
<Stackblitz demo-name="${demoName}" component-name="${componentName}" :code=${demoCodeDefName} />
<CodeSandbox demo-name="${demoName}" component-name="${componentName}" :code=${demoCodeDefName} />
<Stackblitz demo-name="${demoName}" component-name="${componentName.trim()}" :code=${demoCodeDefName} />
<CodeSandbox demo-name="${demoName}" component-name="${componentName.trim()}" :code=${demoCodeDefName} />
</div>
<div class="tdesign-demo-item__body">
<${demoDefName} />
Expand Down
39 changes: 7 additions & 32 deletions site/src/components/codeSandbox/content.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
import orgPkg from '../../../../package.json';

export const htmlContent = `
<div id="app"></div>
<script type="module" src="/src/main.js"></script>
`;
export const htmlContent = `<div id="app"></div>`;

export const mainJsContent = `
import { createApp } from 'vue';
Expand Down Expand Up @@ -42,39 +39,17 @@ export const styleContent = `
}
`;

export const viteConfigContent = `
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import vueJsx from '@vitejs/plugin-vue-jsx';
export default defineConfig({
plugins: [vue(), vueJsx()],
});
`;

export const packageJSONContent = JSON.stringify(
{
name: 'tdesign-vue-next-demo',
version: '0.0.0',
private: true,
scripts: {
dev: 'vite',
build: 'vite build',
serve: 'vite preview',
},
export const packageJSONContent = (name) => {
return {
name: name,
dependencies: {
vue: orgPkg.devDependencies.vue,
less: orgPkg.devDependencies.less,
'tdesign-vue-next': orgPkg.version,
'tdesign-icons-vue-next': orgPkg.dependencies['tdesign-icons-vue-next'],
},
devDependencies: {
vite: orgPkg.devDependencies.vite,
'@vue/compiler-sfc': orgPkg.devDependencies['@vue/compiler-sfc'],
'@vitejs/plugin-vue': orgPkg.devDependencies['@vitejs/plugin-vue'],
'@vitejs/plugin-vue-jsx': orgPkg.devDependencies['@vitejs/plugin-vue-jsx'],
'@vue/cli-plugin-babel': '~4.5.0',
},
},
null,
2,
);
};
};
49 changes: 34 additions & 15 deletions site/src/components/codeSandbox/index.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<template>
<t-tooltip content="在 CodeSandbox 中打开">
<t-loading size="small" :loading="false">
<t-loading v-show="isCodesandboxAvailable" size="small" :loading="isLoading">
<div class="action-online" @click="onRunOnline">
<svg fill="none" height="20" viewBox="0 0 23 23" width="20" xmlns="http://www.w3.org/2000/svg">
<g clip-rule="evenodd" fill-rule="evenodd">
Expand All @@ -20,8 +20,8 @@
</template>

<script>
import { defineComponent, computed, ref } from 'vue';
import { htmlContent, mainJsContent, styleContent, packageJSONContent, viteConfigContent } from './content';
import { defineComponent, ref, onMounted, nextTick, onBeforeUnmount } from 'vue';
import { htmlContent, mainJsContent, styleContent, packageJSONContent } from './content';
export default defineComponent({
name: 'CodeSandbox',
Expand All @@ -31,15 +31,38 @@ export default defineComponent({
},
setup(props) {
const code = ref('');
const params = computed(() => {
return getCodeSandboxParams(code.value, {
title: `${props.demoName} - ${props.componentName}`,
const isLoading = ref(false);
const renderCodeObserver = ref(null);
const observeDom = ref(null);
// TODO: codesandbox + setup tsx
const isCodesandboxAvailable = ref(true);
onMounted(() => {
nextTick(() => {
const currentRenderCode = document.querySelector(
`td-doc-demo[demo-name='${props.demoName}']`,
)?.currentRenderCode;
// only script include jsx/tsx need to check
const toggleCodesandbox = /lang\=\"jsx\"/.test(currentRenderCode);
if (toggleCodesandbox) {
renderCodeObserver.value = new MutationObserver((mutations) => {
const isTsx = /lang\=\"tsx\"/.test(mutations[0].target.currentRenderCode);
isCodesandboxAvailable.value = !isTsx;
});
observeDom.value = document.querySelector(`td-doc-demo[demo-name='${props.demoName}']`);
renderCodeObserver.value.observe(observeDom.value, { attributes: true });
}
});
});
onBeforeUnmount(() => {
renderCodeObserver.value?.unobserve?.(observeDom.value);
renderCodeObserver.value?.disconnect?.();
renderCodeObserver.value = null;
});
const onRunOnline = () => {
code.value = document.querySelector(`td-doc-demo[demo-name='${props.demoName}']`).currentRenderCode;
isLoading.value = true;
fetch('https://codesandbox.io/api/v1/sandboxes/define?json=1', {
method: 'POST',
headers: {
Expand All @@ -49,7 +72,7 @@ export default defineComponent({
body: JSON.stringify({
files: {
'package.json': {
content: packageJSONContent,
content: packageJSONContent(`tdesign-vue-next-${props.componentName}-${props.demoName}-demo`),
},
'index.html': {
content: htmlContent,
Expand All @@ -63,24 +86,20 @@ export default defineComponent({
'src/demo.vue': {
content: code.value,
},
'vite.config.js': {
content: viteConfigContent,
},
},
}),
})
.then((x) => x.json())
.then(({ sandbox_id: sandboxId }) => {
window.open(`https://codesandbox.io/s/${sandboxId}?file=/src/demo.vue`);
})
.finally(() => (this.loading = false));
.finally(() => (isLoading.value = false));
};
return {
params,
onRunOnline,
isLoading,
isCodesandboxAvailable,
};
},
});
</script>

<style lang="scss" scoped></style>

0 comments on commit 4c8fa90

Please sign in to comment.