diff --git a/doc-site/.dumi/app.ts b/doc-site/.dumi/app.ts new file mode 100644 index 00000000..12b77d07 --- /dev/null +++ b/doc-site/.dumi/app.ts @@ -0,0 +1,170 @@ +import { type IPreviewerProps } from 'dumi'; +import { type Project } from '@stackblitz/sdk'; +import { IFiles } from 'codesandbox-import-utils/lib/api/define'; + +export function modifyStackBlitzData(memo: Project, props: IPreviewerProps) { + // if use default template: 'create-react-app', demo won't install dependencies automatically + memo.template = 'node'; + return createTemplate(memo, props, true); +} + +export function modifyCodeSandboxData(memo: { files: IFiles }, props: IPreviewerProps) { + return createTemplate(memo, props, false); +} + +function createTemplate(memo: { files: IFiles } | Project, props: IPreviewerProps, isStackBlitz: boolean) { + Object.entries(memo.files).forEach(([name, content]) => { + if (name === 'sandbox.config.json') { + memo.files[name] = { + content: JSON.stringify({ + template: 'node', + startScript: 'dev', + }, null, 2), + isBinary: false, + }; + return; + } + if (name !== 'index.html' && name !== 'package.json') { + memo.files[`src/${name}`] = content; + } + delete memo.files[name]; + }); + Object.entries(template).forEach(([name, content]) => { + if (name === 'package.json') { + const packageJson = JSON.parse(content); + const npmDeps = Object.entries(props.asset.dependencies || {}) + .filter(([key, value]) => value.type === 'NPM') + .reduce((acc: { [key: string]: any }, [key, value]) => { + acc[key] = value.value; + return acc; + }, {}); + packageJson.dependencies = { ...npmDeps, ...packageJson.dependencies }; + content = JSON.stringify(packageJson, null, 2); + } + memo.files[name] = isStackBlitz ? content : { content: content, isBinary: false }; + }); + + return memo; +} + +const template = { + 'tsconfig.json': ` +{ + "compilerOptions": { + "target": "ES2020", + "useDefineForClassFields": true, + "lib": ["ES2020", "DOM", "DOM.Iterable"], + "module": "ESNext", + "skipLibCheck": true, + + /* Bundler mode */ + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "resolveJsonModule": true, + "isolatedModules": true, + "noEmit": true, + "jsx": "react-jsx", + + /* Linting */ + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true + }, + "include": ["src"], + "references": [{ "path": "./tsconfig.node.json" }] +} +`, + 'tsconfig.node.json': ` +{ + "compilerOptions": { + "composite": true, + "skipLibCheck": true, + "module": "ESNext", + "moduleResolution": "bundler", + "allowSyntheticDefaultImports": true, + "strict": true + }, + "include": ["vite.config.ts"] +} +`, + 'vite.config.ts': ` +import { defineConfig } from 'vite'; +import react from '@vitejs/plugin-react'; +import fixReactVirtualized from 'esbuild-plugin-react-virtualized'; + +// https://vitejs.dev/config/ +export default defineConfig({ + plugins: [react()], + optimizeDeps: { + esbuildOptions: { + // 仅用于修复视频剪辑 demo,时间轴模块的依赖 @xzdarcy/react-timeline-editor 的 导入问题 + plugins: [fixReactVirtualized], + }, + }, +}); +`, + 'index.html': ` + + + + + + + Vite + React + TS + + + +
+ + + +`, + 'package.json': ` +{ + "name": "demo", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "tsc && vite build", + "preview": "vite preview" + }, + "dependencies": { + "react": "^18.2.0", + "react-dom": "^18.2.0", + "antd": "^5.11.5" + }, + "devDependencies": { + "@types/react": "^18.2.66", + "@types/react-dom": "^18.2.22", + "@vitejs/plugin-react": "^4.2.1", + "typescript": "^5.2.2", + "esbuild-plugin-react-virtualized": "^1.0.4", + "postcss": "^8.4.38", + "tailwindcss": "^3.4.1", + "vite": "^5.2.0" + } +} +`, + 'tailwind.config.js': ` +module.exports = { + theme: {}, + variants: {}, + plugins: [], + content: [ + './src/**/*.tsx', + ], +}`, + 'src/index.css': ` + @tailwind components; + @tailwind utilities; +`, + 'postcss.config.js': ` +export default { + plugins: { + tailwindcss: {}, + }, +};` +} diff --git a/doc-site/.dumi/theme/builtins/Previewer.tsx b/doc-site/.dumi/theme/builtins/Previewer.tsx index 3da33e82..b08dba26 100644 --- a/doc-site/.dumi/theme/builtins/Previewer.tsx +++ b/doc-site/.dumi/theme/builtins/Previewer.tsx @@ -1,5 +1,5 @@ // @ts-nocheck import Previewer from 'dumi/theme-default/builtins/Previewer'; export default (props) => { - return ; + return ; }; diff --git a/doc-site/docs/demo/utils.ts b/doc-site/docs/demo/utils.ts index 36b97ac2..e160b885 100644 --- a/doc-site/docs/demo/utils.ts +++ b/doc-site/docs/demo/utils.ts @@ -1,18 +1,25 @@ +const BASE_URL = 'https://bilibili.github.io/WebAV'; export function assetsPrefix>( - assetsURL: T + assetsURL: T, ): T { + const base = + window.location.hostname.includes('webcontainer.io') || + window.location.hostname.includes('stackblitz.io') || + window.location.hostname.includes('csb.app') + ? BASE_URL + : ''; const prefix = process.env.NODE_ENV === 'development' ? '/' : '/WebAV/'; if (Array.isArray(assetsURL)) { - return assetsURL.map((url) => `${prefix}${url}`) as T; + return assetsURL.map((url) => `${base}${prefix}${url}`) as T; } return Object.fromEntries( - Object.entries(assetsURL).map(([k, v]) => [k, `${prefix}${v}`]) + Object.entries(assetsURL).map(([k, v]) => [k, `${base}${prefix}${v}`]), ) as T; } export async function createFileWriter( - extName = 'mp4' + extName = 'mp4', ): Promise { const fileHandle = await window.showSaveFilePicker({ suggestedName: `WebAV-export-${Date.now()}.${extName}`,