Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: support for sandbox context customization #42

Merged
merged 6 commits into from
Jun 14, 2023
Merged

feat: support for sandbox context customization #42

merged 6 commits into from
Jun 14, 2023

Conversation

Blackman99
Copy link
Contributor

@Blackman99 Blackman99 commented Jun 5, 2022

Support for customize some sandbox features

  • Support customize sandbox head tags, such as <link ref="stylesheet" href="custom/css/file">
  • Support customize sandbox app import code, such as import SomePlugin/GlobalComponent from 'customLib'
  • Support customize sandbox app usage code, such as app.use(SomePlugin), app.component('CompName', GlobalComponent)

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)

Copy link
Member

@yyx990803 yyx990803 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like this, but IMO the API needs some adjustments:

  1. These should be merged into a single prop previewOptions:
<Repl
  :previewOptions="{
    headHTML: `...`, // inject to end of head
    bodyHTML: `...`, // inject to end of body, e.g. Teleport targets
    customCode: `import foo from 'xxx'; app.use(foo)`
  }"
/>

Note there's no need to separate import statements and app code, since import statements are hoisted can be placed anywhere.

The entire options object can also be provided as a single injection instead of three.

@Blackman99
Copy link
Contributor Author

Blackman99 commented Jun 26, 2022

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
Copy link

fvena commented Jun 1, 2023

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?

@Blackman99 Blackman99 reopened this Jun 1, 2023
@Blackman99 Blackman99 changed the title feat: support for customize sandbox feat: support for sandbox context customization Jun 6, 2023
@yyx990803 yyx990803 merged commit a22b969 into vuejs:main Jun 14, 2023
@fvena
Copy link

fvena commented Jun 14, 2023

👏👏👏👏👏🎉🎉🍾🍾🎉🎉

@bhabgs
Copy link

bhabgs commented Jun 16, 2023

如何在编译阶段,就把ui组件给编译了呢?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants