export default

This commit is contained in:
pqcqaq 2024-07-20 22:05:48 +08:00
parent 684c7e0c48
commit a40ce69bfc
6 changed files with 73 additions and 24 deletions

View File

@ -8,6 +8,7 @@ import errorBoundary from "../../utils/transpile/errorBoundary";
import "./style.css";
import { CSSTransition, TransitionGroup } from "react-transition-group";
import minifyCode from "../../utils/minify";
// import { execToModule } from "../../utils/transpile/moduleImport";
// import ReactDOM from "react-dom/client";
export const App = () => {
@ -21,22 +22,17 @@ export const App = () => {
const transforms: Transform[] = ["jsx", "typescript"];
const render = (element: ComponentType) => {
const Component = errorBoundary(element, errorCallBack);
if (typeof element === "undefined") {
errorCallBack(new SyntaxError("`render` must be called with valid JSX."));
} else {
const Component = errorBoundary(element, errorCallBack);
setResults([Component]);
}
// ReactDOM.createRoot(document.querySelector(".test-app") as HTMLElement).render(
// <React.StrictMode>
// < Component />
// </React.StrictMode>
// );
};
// 开发环境下useEffect会执行两次模拟装载和卸载组件生产环境没事。
useEffect(() => {
const allCpns = functionBlockList.map((item) => item.code).join("\n").replace(/export default/g, "");
const allCpns = functionBlockList.map((item) => item.code).join("\n").replace(/export\s+default\s+([A-Za-z_$][A-Za-z0-9_$]*)/g, "");
const allPage = functionBlockList
.map((item, index) => `<${item.cpnName} { ...props[${index}] }/>`)
.join("\n");
@ -60,7 +56,7 @@ export const App = () => {
setTimeout(async () => {
const minifiedCode = await minifyCode(allTransformed);
const codeToRun = minifiedCode.replace(/export default/g, "return")
const codeToRun = minifiedCode.replace(/export\s+default/g, "return")
const ApplicationContext = evalCode(
codeToRun,
{
@ -68,8 +64,13 @@ export const App = () => {
props: propsList,
}
);
console.log(ApplicationContext);
render(ApplicationContext);
// // console.log(ApplicationContext);
// const module = await execToModule(minifiedCode, {
// React: 'https://unpkg.com/react@17/umd/react.production.min.js',
// props: propsList,
// })
// render(module.default);
}, 1000);
}, []);

View File

@ -132,7 +132,7 @@ export const Editor = () => {
},
]}
>
<LivePreview {...func.props} />
<LivePreview {...func.props}/>
<LiveError />
</ClickContextProvider>
</LiveProvider>

View File

@ -2,20 +2,23 @@ import { minify } from "terser";
import { jsxConst } from "../handler";
export default async function minifyCode(code: string) {
console.log("minifyCode", code);
const replaced = code
.replace(RegExp(`React.createElement`, "g"), `rc`)
.replace(RegExp(`React.Fragment`, "g"), `rf`)
.replace(RegExp(`React.useState`, "g"), `rs`)
.replace(RegExp(`React.useEffect`, "g"), `re`)
.replace(RegExp(`React.Component`, "g"), `rcp`)
.replace(RegExp(`React.createContext`, "g"), `rcc`)
.replace(RegExp(`React.useContext`, "g"), `rcu`)
.replace(RegExp(`React.useReducer`, "g"), `rd`)
.replace(RegExp(`React.memo`, "g"), `rm`)
.replace(
jsxConst,
`${jsxConst} const rc=React.createElement,rf=React.Fragment,rs=React.useState,re=React.useEffect,rcp=React.Component,rcc=React.createContext,rcu=React.useContext,rd=React.useReducer,rm=React.memo;`
);
// .replace(RegExp(`React.createElement`, "g"), `rc`)
// .replace(RegExp(`React.Fragment`, "g"), `rf`)
// .replace(RegExp(`React.useState`, "g"), `rs`)
// .replace(RegExp(`React.useEffect`, "g"), `re`)
// .replace(RegExp(`React.Component`, "g"), `rcp`)
// .replace(RegExp(`React.createContext`, "g"), `rcc`)
// .replace(RegExp(`React.useContext`, "g"), `rcu`)
// .replace(RegExp(`React.useReducer`, "g"), `rd`)
// .replace(RegExp(`React.memo`, "g"), `rm`)
// .replace(
// jsxConst,
// `${jsxConst} const rc=React.createElement,rf=React.Fragment,rs=React.useState,re=React.useEffect,rcp=React.Component,rcc=React.createContext,rcu=React.useContext,rd=React.useReducer,rm=React.memo;`
// );
const { code: minifiedCode } = await minify(replaced, {
compress: {

View File

@ -27,6 +27,7 @@ export const generateElement = (
const firstPassTransforms: Transform[] = ["jsx"];
enableTypeScript && firstPassTransforms.push("typescript");
// 通过compose函数将多个函数组合成一个函数用于Inline编辑器的代码转换
const transformed = compose<string>(
addJsxConst,
transform({ transforms: ["imports"] }),
@ -74,5 +75,11 @@ export const renderElementAsync = (
const Cpn = evalCode(codeTorun, { React, ...scope, render });
// if (!React.isValidElement(Cpn)) {
// return errorCallback(
// new SyntaxError("The Code didn't return a valid JSX element!")
// );
// }
render(Cpn);
};

View File

@ -0,0 +1,37 @@
import { Transform } from "sucrase";
import transform from "./transform";
import minifyCode from "../minify";
const transforms: Transform[] = ["jsx", "typescript"];
export const execToModule = async (
code: string,
scope: { [key: string]: any } = {}
): Promise<any> => {
// 将scope对象中的属性转换为import语句
const importStatements = Object.keys(scope)
.map(([key, path]) => `import ${key} from '${path}';`)
.join("\n");
// 添加到code之前
const scopedCode = `${importStatements}\n${code}`;
// 使用Babel或其他工具进行转换
const allTransformed = transform({ transforms })(scopedCode);
const minifiedCode = await minifyCode(allTransformed);
// 创建并导入模块
return new Promise((resolve) => {
(async () => {
// 创建一个Blob对象
const blob = new Blob([minifiedCode], { type: "application/javascript" });
// 创建一个URL对象
const url = URL.createObjectURL(blob);
// 动态导入模块
const module = await import(url);
resolve(module);
// 释放URL对象
URL.revokeObjectURL(url);
})();
});
};

View File

@ -11,5 +11,6 @@ export default function transform(opts: Options = {}) {
? opts.transforms.filter(Boolean)
: defaultTransforms;
return (code: string) => _transform(code, { transforms }).code;
return (code: string) =>
_transform(code, { transforms, production: true }).code;
}