Fix(Preview): Fixed code pollution bug

Methods and variables in base and main code are isolated to solve the problem of code pollution. Close #4
This commit is contained in:
2024-09-09 16:24:22 +08:00
parent bba90c6783
commit 51ee15749e
7 changed files with 129 additions and 131 deletions

View File

@@ -32,7 +32,7 @@ const Preview = ({
Compiler.compile(files, importMap, entryPoint)
.then((result) => {
setCompiledCode(
`${preExpansionCode}\n${result.outputFiles[0].text}\n${postExpansionCode}`
`(()=>{${preExpansionCode}})();\n(()=>{${result.outputFiles[0].text}})();\n(()=>{${postExpansionCode}})();`
)
setErrorMsg('')
})

View File

@@ -2,7 +2,7 @@ import esbuild, { Loader, OnLoadArgs, Plugin, PluginBuild } from 'esbuild-wasm'
import localforage from 'localforage'
import axios from 'axios'
import { IFiles, IImportMap } from '@/components/Playground/shared'
import { cssToJs, jsonToJs, addReactImport } from '@/components/Playground/files'
import { addReactImport, cssToJs, jsonToJs } from '@/components/Playground/files'
class Compiler {
private init = false
@@ -73,151 +73,149 @@ class Compiler {
files: IFiles,
importMap: IImportMap,
entryPoint: string
): Plugin => {
return {
name: 'file-resolver-plugin',
setup: (build: PluginBuild) => {
build.onResolve({ filter: /.*/ }, (args: esbuild.OnResolveArgs) => {
if (entryPoint === args.path) {
return {
namespace: 'OxygenToolbox',
path: args.path
}
): Plugin => ({
name: 'file-resolver-plugin',
setup: (build: PluginBuild) => {
build.onResolve({ filter: /.*/ }, (args: esbuild.OnResolveArgs) => {
if (entryPoint === args.path) {
return {
namespace: 'OxygenToolbox',
path: args.path
}
if (args.path.startsWith('./') && files[args.path.substring(2)]) {
return {
namespace: 'OxygenToolbox',
path: args.path.substring(2)
}
}
if (args.path.startsWith('./') && files[args.path.substring(2)]) {
return {
namespace: 'OxygenToolbox',
path: args.path.substring(2)
}
if (args.path.startsWith('./') && files[`${args.path.substring(2)}.tsx`]) {
return {
namespace: 'OxygenToolbox',
path: `${args.path.substring(2)}.tsx`
}
}
if (args.path.startsWith('./') && files[`${args.path.substring(2)}.tsx`]) {
return {
namespace: 'OxygenToolbox',
path: `${args.path.substring(2)}.tsx`
}
if (args.path.startsWith('./') && files[`${args.path.substring(2)}.jsx`]) {
return {
namespace: 'OxygenToolbox',
path: `${args.path.substring(2)}.jsx`
}
}
if (args.path.startsWith('./') && files[`${args.path.substring(2)}.jsx`]) {
return {
namespace: 'OxygenToolbox',
path: `${args.path.substring(2)}.jsx`
}
if (args.path.startsWith('./') && files[`${args.path.substring(2)}.ts`]) {
return {
namespace: 'OxygenToolbox',
path: `${args.path.substring(2)}.ts`
}
}
if (args.path.startsWith('./') && files[`${args.path.substring(2)}.ts`]) {
return {
namespace: 'OxygenToolbox',
path: `${args.path.substring(2)}.ts`
}
if (args.path.startsWith('./') && files[`${args.path.substring(2)}.js`]) {
return {
namespace: 'OxygenToolbox',
path: `${args.path.substring(2)}.js`
}
}
if (/\.\/.*\.css/.test(args.path) && !args.resolveDir) {
throw Error(`Css '${args.path}' not found`)
}
if (/^https?:\/\/.*/.test(args.path)) {
return {
namespace: 'default',
path: args.path
}
}
if (
args.path.includes('./') ||
args.path.includes('../') ||
args.path.startsWith('/')
) {
return {
namespace: 'default',
path: new URL(args.path, args.resolveDir.substring(1)).href
}
}
const path = importMap.imports[args.path]
if (!path) {
throw Error(`Import '${args.path}' not found in Import Map`)
}
if (args.path.startsWith('./') && files[`${args.path.substring(2)}.js`]) {
return {
namespace: 'OxygenToolbox',
path: `${args.path.substring(2)}.js`
}
}
if (/\.\/.*\.css/.test(args.path) && !args.resolveDir) {
throw Error(`Css '${args.path}' not found`)
}
if (/^https?:\/\/.*/.test(args.path)) {
return {
namespace: 'default',
path
path: args.path
}
})
}
build.onLoad({ filter: /.*\.css$/ }, (args: OnLoadArgs) => {
const contents = cssToJs(files[args.path])
if (
args.path.includes('./') ||
args.path.includes('../') ||
args.path.startsWith('/')
) {
return {
loader: 'js',
contents
namespace: 'default',
path: new URL(args.path, args.resolveDir.substring(1)).href
}
})
}
build.onLoad({ filter: /.*\.json$/ }, (args: OnLoadArgs) => {
const contents = jsonToJs(files[args.path])
const path = importMap.imports[args.path]
if (!path) {
throw Error(`Import '${args.path}' not found in Import Map`)
}
return {
namespace: 'default',
path
}
})
build.onLoad({ filter: /.*\.css$/ }, (args: OnLoadArgs) => {
const contents = cssToJs(files[args.path])
return {
loader: 'js',
contents
}
})
build.onLoad({ filter: /.*\.json$/ }, (args: OnLoadArgs) => {
const contents = jsonToJs(files[args.path])
return {
loader: 'js',
contents
}
})
build.onLoad({ filter: /.*/ }, async (args: OnLoadArgs) => {
if (entryPoint === args.path) {
return {
loader: 'js',
contents
loader: 'tsx',
contents: addReactImport(files[entryPoint].value)
}
})
}
build.onLoad({ filter: /.*/ }, async (args: OnLoadArgs) => {
if (entryPoint === args.path) {
if (files[args.path]) {
const contents = addReactImport(files[args.path].value)
if (args.path.endsWith('.jsx')) {
return {
loader: 'tsx',
contents: addReactImport(files[entryPoint].value)
}
}
if (files[args.path]) {
const contents = addReactImport(files[args.path].value)
if (args.path.endsWith('.jsx')) {
return {
loader: 'jsx',
contents
}
}
if (args.path.endsWith('.ts')) {
return {
loader: 'ts',
contents
}
}
if (args.path.endsWith('.js')) {
return {
loader: 'js',
contents
}
}
return {
loader: 'tsx',
loader: 'jsx',
contents
}
}
const cached = await this.fileCache.getItem<esbuild.OnLoadResult>(args.path)
if (cached) {
return cached
if (args.path.endsWith('.ts')) {
return {
loader: 'ts',
contents
}
}
const axiosResponse = await axios.get<string>(args.path)
const result: esbuild.OnLoadResult = {
loader: 'jsx',
contents: axiosResponse.data,
resolveDir: (axiosResponse.request as XMLHttpRequest).responseURL
if (args.path.endsWith('.js')) {
return {
loader: 'js',
contents
}
}
return {
loader: 'tsx',
contents
}
}
await this.fileCache.setItem(args.path, result)
const cached = await this.fileCache.getItem<esbuild.OnLoadResult>(args.path)
return result
})
}
if (cached) {
return cached
}
const axiosResponse = await axios.get<string>(args.path)
const result: esbuild.OnLoadResult = {
loader: 'jsx',
contents: axiosResponse.data,
resolveDir: (axiosResponse.request as XMLHttpRequest).responseURL
}
await this.fileCache.setItem(args.path, result)
return result
})
}
}
})
}
export default new Compiler()