vuejs / repl

Vue SFC REPL as a Vue 3 component
https://repl-vuejs.vercel.app
MIT License
930 stars 172 forks source link

feat: support for sandbox context customization #42

Closed Blackman99 closed 1 year ago

Blackman99 commented 2 years ago

Support for customize some sandbox features

Example for global use ElementPlus

<script setup>
import { Repl, ReplStore } from '@vue/repl'

const store = new ReplStore()

store.setImportMap({
  imports: {
    'element-plus': 'https://unpkg.com/element-plus@2.2.5/es/index.mjs'
  }
})

const customImportStatements = [`import ElementPlus from 'element-plus'`]
const customAppUsageCodes = [`app.use(ElementPlus)`]
const customHeadTags = [
  `<link ref="stylesheet" href="https://unpkg.com/element-plus@2.2.5/dist/index.css">`
]
</script>
<template>
  <Repl 
    v-bind="{ 
      customImportStatements, 
      customAppUsageCodes, 
      customHeadTags,
      store
    }"
  />
</template>

Then in the repl editor, you can use any ElementPlus Components

<template>
  <el-button>
   A Button
  </el-button>
</template>

This PR can possibly solve issue (#41)

Blackman99 commented 2 years ago

Thanks for api adjustments suggestion. I've changed the origin api to suggested previewOptions

But there is still a problem: If I merge the import code with the app use code (use the previewOptions.customCode option) like this:

const App = {
  setup() {
    const store = new ReplStore()
    store.setImportMap({
      imports: {
        "casual-ui-vue":
          "https://unpkg.com/casual-ui-vue/dist/casual-ui-vue.es.js",
      },
    });

    return () =>
      h(Repl, {
        store,
        previewOptions: {
          headHTML: '<link rel="stylesheet" href="https://unpkg.com/casual-ui-vue/dist/style.css">',
          customCode: `import CUI from 'casual-ui-vue; app.use(CUI)`
        }
      });
  }
}

somehow the repl shows an error message: Unexpected Identifier which points to the import statement:

middle_img_v2_acf3fee9-6314-4b3a-8044-70cd0df8106g

Here's reproduction link

The error only disappeared when I separate them.

Based on that I changed the previewOptions.customCode to previewOptions.customCode.importCode and previewOptions.customCode.useCode

Here's my changed commit, in the test/main.ts, has some code I've used to test the feature, using a components lib write by myself: Casual UI

in the test/main.ts

const App = {
  setup() {
    const store = new ReplStore()
    store.setImportMap({
      imports: {
        "casual-ui-vue":
          "https://unpkg.com/casual-ui-vue/dist/casual-ui-vue.es.js",
      },
    });

    return () =>
      h(Repl, {
        store,
        previewOptions: {
          headHTML:
            '<link rel="stylesheet" href="https://unpkg.com/casual-ui-vue/dist/style.css">',
          customCode: {
            importCode: `import CUI from 'casual-ui-vue'`,
            useCode: 'app.use(CUI)'
          }
        }
      });
  }
}

In the repl, write some code like this would work as expected:

<script setup>
import { ref } from 'vue'

const msg = ref('Hello World!')
</script>

<template>
  <c-button :label="msg" />
</template>

middle_img_v2_c22e24f1-ecf4-4fbf-b07e-8652d319863g

fvena commented 1 year ago

Why hasn't this feature been merged yet? I believe it could be very useful. Is there any default feature that allows us to accomplish this?

fvena commented 1 year ago

๐Ÿ‘๐Ÿ‘๐Ÿ‘๐Ÿ‘๐Ÿ‘๐ŸŽ‰๐ŸŽ‰๐Ÿพ๐Ÿพ๐ŸŽ‰๐ŸŽ‰

bhabgs commented 1 year ago

ๅฆ‚ไฝ•ๅœจ็ผ–่ฏ‘้˜ถๆฎต๏ผŒๅฐฑๆŠŠui็ป„ไปถ็ป™็ผ–่ฏ‘ไบ†ๅ‘ข๏ผŸ