setupin 3.3.0-beta.1 → 3.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,140 +1,142 @@
1
- <p align="right">
2
- <b>English</b> | <a href="./README.zh-CN.md">简体中文</a>
3
- </p>
4
-
5
- <p align="center"><img src="./public/logo.svg"></p>
6
-
7
- <p align="center">
8
- <a href="https://stackblitz.com/edit/setupin"><img src="https://img.shields.io/badge/stackBlitz-blue"></a>
9
- <a href="https://npmjs.com/package/setupin"><img src="https://img.shields.io/npm/v/setupin?color=orange"></a>
10
- <a href="https://bundlephobia.com/package/setupin"><img src="https://img.shields.io/bundlephobia/minzip/setupin"></a>
11
- </p>
12
-
13
- ## 😏 What is a setupin?
14
-
15
- **setupin** allows you to use [Vue SFC](https://vuejs.org/api/sfc-spec) syntax in HTML.
16
-
17
- Using the [sfc2esm](../../../sfc2esm), which compiled at runtime for esm vue code format, and dynamic execution.
18
-
19
- ## 🤯 Code comparison
20
-
21
- <h4 align=center>esm.html</h4>
22
-
23
- vue **esm** is complicated to write
24
-
25
- ```html
26
- <!DOCTYPE html>
27
- <html lang="en">
28
- <head>
29
- <meta charset="UTF-8">
30
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
31
- <title>esm</title>
32
- <style>
33
- button {
34
- font-size: larger;
35
- }
36
- </style>
37
- </head>
38
- <body>
39
- <div id="app">
40
- <button @click="count++">{{ count }}</button>
41
- </div>
42
-
43
- <script type="module">
44
- import { createApp, defineComponent, ref } from 'https://unpkg.com/vue/dist/vue.esm-browser.js';
45
- const App = defineComponent(() => {
46
- const count = ref(0);
47
- return {
48
- count
49
- };
50
- });
51
- createApp(App).mount('#app')
52
- </script>
53
- </body>
54
- </html>
55
- ```
56
-
57
- <h4 align=center>setup.vue</h4>
58
-
59
- vue **sfc** needs to be compiled
60
-
61
- ```html
62
- <script setup>
63
- import { ref } from 'vue'
64
- const count = ref(0)
65
- </script>
66
-
67
- <template>
68
- <button @click="count++">{{ count }}</button>
69
- </template>
70
-
71
- <style>
72
- button {
73
- font-size: larger;
74
- }
75
- </style>
76
- ```
77
-
78
- <h4 align=center>setupin.html</h4>
79
-
80
- **setupin** brings it all together
81
-
82
- ```html
83
- <head>
84
- <meta charset="UTF-8">
85
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
86
- <title>setupin</title>
87
- <script src="https://unpkg.com/setupin"></script>
88
- </head>
89
-
90
- <script setup>
91
- import { ref } from 'vue'
92
- const count = ref(0)
93
- </script>
94
-
95
- <template>
96
- <button @click="count++">{{ count }}</button>
97
- </template>
98
-
99
- <style>
100
- button {
101
- font-size: larger;
102
- }
103
- </style>
104
- ```
105
-
106
- It's exactly the same as Vue SFC except for the \<head>
107
-
108
- ## 🤓 Characteristics
109
-
110
- - [x] [top-level await](https://vuejs.org/api/sfc-script-setup.html#top-level-await)
111
- - [x] [sfc css features](https://vuejs.org/api/sfc-css-features.html)
112
- - [x] [Options API](https://vuejs.org/guide/introduction.html#options-api)
113
-
114
- ## 🤔 Why setupin
115
-
116
- 1. **Easy to learn**
117
- Offer a friendly environment for beginners to easily grasp the core usage of Vue.
118
- 2. **Simple development**
119
- Provide a convenient way to rapidly develop small webpage without complex configurations.
120
- 3. **Quick experience**
121
- Allow users to quickly experiment with Vue's new features in HTML and feel its charm.
122
-
123
- ## 😝 Playground
124
-
125
- try it on
126
- [stackblitz](https://stackblitz.com/edit/setupin?file=index.html)
127
- !
128
-
129
- ## 🥰 Usage
130
-
131
- ```html
132
- <!-- The default is the dev version -->
133
- <script src="https://unpkg.com/setupin"></script>
134
-
135
- <!-- dev -->
136
- <script src="https://unpkg.com/setupin/dist/main.js"></script>
137
-
138
- <!-- prod -->
139
- <script src="https://unpkg.com/setupin/dist/main.prod.js"></script>
140
- ```
1
+ <p align="right">
2
+ <b>English</b> | <a href="./README.zh-CN.md">简体中文</a>
3
+ </p>
4
+
5
+ <p align="center"><img src="./public/logo.svg"></p>
6
+
7
+ <p align="center">
8
+ <a href="https://stackblitz.com/edit/setupin"><img src="https://img.shields.io/badge/stackBlitz-blue"></a>
9
+ <a href="https://npmjs.com/package/setupin"><img src="https://img.shields.io/npm/v/setupin?color=orange"></a>
10
+ <a href="https://bundlephobia.com/package/setupin"><img src="https://img.shields.io/bundlephobia/minzip/setupin"></a>
11
+ </p>
12
+
13
+ ## 😏 What is a setupin?
14
+
15
+ **setupin** allows you to use [Vue SFC](https://vuejs.org/api/sfc-spec) syntax in HTML.
16
+
17
+ ## 📦 Driven by sfc2esm
18
+
19
+ [**sfc2esm**](https://github.com/tofu-xx/sfc2esm) is the core runtime compiler powering setupin. It parses Vue SFC syntax (`<script setup>`, `<template>`, `<style>`) and compiles it into browser-executable ESM code + CSS code at runtime. This eliminates the need for a build step — the compilation happens on-the-fly in the browser.
20
+
21
+ ## 🤯 Code comparison
22
+
23
+ <h4 align=center>esm.html</h4>
24
+
25
+ vue **esm** is complicated to write
26
+
27
+ ```html
28
+ <!DOCTYPE html>
29
+ <html lang="en">
30
+ <head>
31
+ <meta charset="UTF-8">
32
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
33
+ <title>esm</title>
34
+ <style>
35
+ button {
36
+ font-size: larger;
37
+ }
38
+ </style>
39
+ </head>
40
+ <body>
41
+ <div id="app">
42
+ <button @click="count++">{{ count }}</button>
43
+ </div>
44
+
45
+ <script type="module">
46
+ import { createApp, defineComponent, ref } from 'https://unpkg.com/vue/dist/vue.esm-browser.js';
47
+ const App = defineComponent(() => {
48
+ const count = ref(0);
49
+ return {
50
+ count
51
+ };
52
+ });
53
+ createApp(App).mount('#app')
54
+ </script>
55
+ </body>
56
+ </html>
57
+ ```
58
+
59
+ <h4 align=center>setup.vue</h4>
60
+
61
+ vue **sfc** needs to be compiled
62
+
63
+ ```html
64
+ <script setup>
65
+ import { ref } from 'vue'
66
+ const count = ref(0)
67
+ </script>
68
+
69
+ <template>
70
+ <button @click="count++">{{ count }}</button>
71
+ </template>
72
+
73
+ <style>
74
+ button {
75
+ font-size: larger;
76
+ }
77
+ </style>
78
+ ```
79
+
80
+ <h4 align=center>setupin.html</h4>
81
+
82
+ **setupin** brings it all together
83
+
84
+ ```html
85
+ <head>
86
+ <meta charset="UTF-8">
87
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
88
+ <title>setupin</title>
89
+ <script src="https://unpkg.com/setupin"></script>
90
+ </head>
91
+
92
+ <script setup>
93
+ import { ref } from 'vue'
94
+ const count = ref(0)
95
+ </script>
96
+
97
+ <template>
98
+ <button @click="count++">{{ count }}</button>
99
+ </template>
100
+
101
+ <style>
102
+ button {
103
+ font-size: larger;
104
+ }
105
+ </style>
106
+ ```
107
+
108
+ It's exactly the same as Vue SFC except for the \<head>
109
+
110
+ ## 🤓 Characteristics
111
+
112
+ - [x] [top-level await](https://vuejs.org/api/sfc-script-setup.html#top-level-await)
113
+ - [x] [sfc css features](https://vuejs.org/api/sfc-css-features.html)
114
+ - [x] [Options API](https://vuejs.org/guide/introduction.html#options-api)
115
+
116
+ ## 🤔 Why setupin
117
+
118
+ 1. **Easy to learn**
119
+ Offer a friendly environment for beginners to easily grasp the core usage of Vue.
120
+ 2. **Simple development**
121
+ Provide a convenient way to rapidly develop small webpage without complex configurations.
122
+ 3. **Quick experience**
123
+ Allow users to quickly experiment with Vue's new features in HTML and feel its charm.
124
+
125
+ ## 😝 Playground
126
+
127
+ try it on
128
+ [stackblitz](https://stackblitz.com/edit/setupin?file=index.html)
129
+ !
130
+
131
+ ## 🥰 Usage
132
+
133
+ ```html
134
+ <!-- The default is the dev version -->
135
+ <script src="https://unpkg.com/setupin"></script>
136
+
137
+ <!-- dev -->
138
+ <script src="https://unpkg.com/setupin/dist/main.js"></script>
139
+
140
+ <!-- prod -->
141
+ <script src="https://unpkg.com/setupin/dist/main.prod.js"></script>
142
+ ```
package/README.zh-CN.md CHANGED
@@ -1,141 +1,143 @@
1
- <p align="right">
2
- <a href="./README.md">English</a> | <b>简体中文</b>
3
- </p>
4
-
5
- <p align="center"><img src="./public/logo.svg"></p>
6
-
7
- <p align="center">
8
- <a href="https://stackblitz.com/edit/setupin"><img src="https://img.shields.io/badge/stackBlitz-blue"></a>
9
- <a href="https://npmjs.com/package/setupin"><img src="https://img.shields.io/npm/v/setupin?color=orange"></a>
10
- <a href="https://bundlephobia.com/package/setupin"><img src="https://img.shields.io/bundlephobia/minzip/setupin"></a>
11
- </p>
12
-
13
- ## 😏 setupin 是什么?
14
-
15
- **setupin** 允许你在 HTML 中使用 [Vue SFC](https://cn.vuejs.org/api/sfc-spec) 语法。
16
-
17
- 利用[sfc2esm](../../../sfc2esm),在运行时编译为esm格式的vue代码,并动态执行。
18
-
19
- ## 🤯 代码对比
20
-
21
- <h4 align=center>esm.html</h4>
22
-
23
- vue **esm** 写法复杂
24
-
25
- ```html
26
- <!DOCTYPE html>
27
- <html lang="en">
28
- <head>
29
- <meta charset="UTF-8">
30
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
31
- <title>esm</title>
32
- <style>
33
- button {
34
- font-size: larger;
35
- }
36
- </style>
37
- </head>
38
- <body>
39
- <div id="app">
40
- <button @click="count++">{{ count }}</button>
41
- </div>
42
-
43
- <script type="module">
44
- import { createApp, defineComponent, ref } from 'https://unpkg.com/vue/dist/vue.esm-browser.js';
45
- const App = defineComponent(() => {
46
- const count = ref(0);
47
- return {
48
- count
49
- };
50
- });
51
- createApp(App).mount('#app')
52
- </script>
53
- </body>
54
- </html>
55
- ```
56
-
57
- <h4 align=center>setup.vue</h4>
58
-
59
- vue **sfc** 需要编译
60
-
61
- ```html
62
- <script setup>
63
- import { ref } from 'vue'
64
- const count = ref(0)
65
- </script>
66
-
67
- <template>
68
- <button @click="count++">{{ count }}</button>
69
- </template>
70
-
71
- <style>
72
- button {
73
- font-size: larger;
74
- }
75
- </style>
76
- ```
77
-
78
- <h4 align=center>setupin.html</h4>
79
-
80
- **setupin** 将其合二为一
81
-
82
- ```html
83
- <head>
84
- <meta charset="UTF-8">
85
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
86
- <title>setupin</title>
87
- <script src="https://unpkg.com/setupin"></script>
88
- </head>
89
-
90
- <script setup>
91
- import { ref } from 'vue'
92
- const count = ref(0)
93
- </script>
94
-
95
- <template>
96
- <button @click="count++">{{ count }}</button>
97
- </template>
98
-
99
- <style>
100
- button {
101
- font-size: larger;
102
- }
103
- </style>
104
- ```
105
-
106
- 除了\<head>之外和Vue SFC写法完全一致
107
-
108
- ## 🤓 特性
109
-
110
- - [x] [顶层 await](https://cn.vuejs.org/api/sfc-script-setup.html#top-level-await)
111
- - [x] [CSS 功能](https://cn.vuejs.org/api/sfc-css-features)
112
- - [x] [选项式](https://cn.vuejs.org/guide/introduction.html#options-api)
113
-
114
- ## 🤔 为什么选择 setupin
115
-
116
- 1. **便于学习**
117
- 为初学者提供一个友好的环境,帮助他们轻松上手 Vue 的核心用法。
118
-
119
- 2. **简易开发**
120
- 提供便捷的方式,助力快速开发小网页,无需繁琐的配置。
121
-
122
- 3. **快速体验**
123
- 让用户可以快速在 HTML 中尝试 Vue 的新特性,感受其魅力。
124
-
125
- ## 😝 演练场
126
-
127
- [stackblitz](https://stackblitz.com/edit/setupin?file=index.html)
128
- 上尝试一下吧!
129
-
130
- ## 🥰 CDN
131
-
132
- ```html
133
- <!-- 默认是dev版本 -->
134
- <script src="https://unpkg.com/setupin"></script>
135
-
136
- <!-- dev -->
137
- <script src="https://unpkg.com/setupin/dist/main.js"></script>
138
-
139
- <!-- prod -->
140
- <script src="https://unpkg.com/setupin/dist/main.prod.js"></script>
141
- ```
1
+ <p align="right">
2
+ <a href="./README.md">English</a> | <b>简体中文</b>
3
+ </p>
4
+
5
+ <p align="center"><img src="./public/logo.svg"></p>
6
+
7
+ <p align="center">
8
+ <a href="https://stackblitz.com/edit/setupin"><img src="https://img.shields.io/badge/stackBlitz-blue"></a>
9
+ <a href="https://npmjs.com/package/setupin"><img src="https://img.shields.io/npm/v/setupin?color=orange"></a>
10
+ <a href="https://bundlephobia.com/package/setupin"><img src="https://img.shields.io/bundlephobia/minzip/setupin"></a>
11
+ </p>
12
+
13
+ ## 😏 setupin 是什么?
14
+
15
+ **setupin** 允许你在 HTML 中使用 [Vue SFC](https://cn.vuejs.org/api/sfc-spec) 语法。
16
+
17
+ ## 📦 由 sfc2esm 驱动
18
+
19
+ [**sfc2esm**](https://github.com/tofu-xx/sfc2esm) setupin 的核心运行时编译器。它将 Vue SFC 语法(`<script setup>`、`<template>`、`<style>`)在浏览器中实时编译为可执行的 ESM 代码和 CSS 代码,无需构建步骤,开箱即用。
20
+
21
+ ## 🤯 代码对比
22
+
23
+ <h4 align=center>esm.html</h4>
24
+
25
+ vue **esm** 写法复杂
26
+
27
+ ```html
28
+ <!DOCTYPE html>
29
+ <html lang="en">
30
+ <head>
31
+ <meta charset="UTF-8">
32
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
33
+ <title>esm</title>
34
+ <style>
35
+ button {
36
+ font-size: larger;
37
+ }
38
+ </style>
39
+ </head>
40
+ <body>
41
+ <div id="app">
42
+ <button @click="count++">{{ count }}</button>
43
+ </div>
44
+
45
+ <script type="module">
46
+ import { createApp, defineComponent, ref } from 'https://unpkg.com/vue/dist/vue.esm-browser.js';
47
+ const App = defineComponent(() => {
48
+ const count = ref(0);
49
+ return {
50
+ count
51
+ };
52
+ });
53
+ createApp(App).mount('#app')
54
+ </script>
55
+ </body>
56
+ </html>
57
+ ```
58
+
59
+ <h4 align=center>setup.vue</h4>
60
+
61
+ vue **sfc** 需要编译
62
+
63
+ ```html
64
+ <script setup>
65
+ import { ref } from 'vue'
66
+ const count = ref(0)
67
+ </script>
68
+
69
+ <template>
70
+ <button @click="count++">{{ count }}</button>
71
+ </template>
72
+
73
+ <style>
74
+ button {
75
+ font-size: larger;
76
+ }
77
+ </style>
78
+ ```
79
+
80
+ <h4 align=center>setupin.html</h4>
81
+
82
+ **setupin** 将其合二为一
83
+
84
+ ```html
85
+ <head>
86
+ <meta charset="UTF-8">
87
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
88
+ <title>setupin</title>
89
+ <script src="https://unpkg.com/setupin"></script>
90
+ </head>
91
+
92
+ <script setup>
93
+ import { ref } from 'vue'
94
+ const count = ref(0)
95
+ </script>
96
+
97
+ <template>
98
+ <button @click="count++">{{ count }}</button>
99
+ </template>
100
+
101
+ <style>
102
+ button {
103
+ font-size: larger;
104
+ }
105
+ </style>
106
+ ```
107
+
108
+ 除了\<head>之外和Vue SFC写法完全一致
109
+
110
+ ## 🤓 特性
111
+
112
+ - [x] [顶层 await](https://cn.vuejs.org/api/sfc-script-setup.html#top-level-await)
113
+ - [x] [CSS 功能](https://cn.vuejs.org/api/sfc-css-features)
114
+ - [x] [选项式](https://cn.vuejs.org/guide/introduction.html#options-api)
115
+
116
+ ## 🤔 为什么选择 setupin
117
+
118
+ 1. **便于学习**
119
+ 为初学者提供一个友好的环境,帮助他们轻松上手 Vue 的核心用法。
120
+
121
+ 2. **简易开发**
122
+ 提供便捷的方式,助力快速开发小网页,无需繁琐的配置。
123
+
124
+ 3. **快速体验**
125
+ 让用户可以快速在 HTML 中尝试 Vue 的新特性,感受其魅力。
126
+
127
+ ## 😝 演练场
128
+
129
+ 在 [stackblitz](https://stackblitz.com/edit/setupin?file=index.html)
130
+ 上尝试一下吧!
131
+
132
+ ## 🥰 CDN
133
+
134
+ ```html
135
+ <!-- 默认是dev版本 -->
136
+ <script src="https://unpkg.com/setupin"></script>
137
+
138
+ <!-- dev -->
139
+ <script src="https://unpkg.com/setupin/dist/main.js"></script>
140
+
141
+ <!-- prod -->
142
+ <script src="https://unpkg.com/setupin/dist/main.prod.js"></script>
143
+ ```
package/dist/main.js CHANGED
@@ -46040,15 +46040,10 @@ ${exposeCall}`
46040
46040
  awaitClientCode((sfcCode) => {
46041
46041
  var _a2, _b2, _c;
46042
46042
  const site = document["head"];
46043
- const option = {
46044
- id: "setupin",
46045
- appName: "APP$",
46046
- mount: "body"
46047
- };
46048
- const { esmCode, cssCode } = sfc2esm(sfcCode, option);
46043
+ const { esmCode, cssCode } = sfc2esm(sfcCode, { id: "setupin", mount: "body" });
46049
46044
  (_a2 = createDom('<script type="importmap">', JSON.stringify({ imports: { vue: "https://unpkg.com/vue@latest/dist/vue.runtime.esm-browser.js" } }))) == null ? void 0 : _a2.mount(site);
46050
46045
  (_b2 = createDom('<script type="module">', `${asciiLogo}
46051
46046
  ${esmCode}`)) == null ? void 0 : _b2.mount(site);
46052
- cssCode && ((_c = createDom("<style>", cssCode)) == null ? void 0 : _c.mount(document.head));
46047
+ if (cssCode) (_c = createDom("<style>", cssCode)) == null ? void 0 : _c.mount(document.head);
46053
46048
  });
46054
46049
  })();
package/dist/main.prod.js CHANGED
@@ -197,5 +197,5 @@ ${ee}`),a.s.appendRight(N,"}"));if(a.helperImports.size>0){const q=(n=(i=e.templ
197
197
  ** |_| **\r
198
198
  ***************************************/\r
199
199
  `;function mc(t,e){var a;const r=document.createElement("main");r.insertAdjacentHTML("afterbegin",t);const i=r.firstElementChild;if(!i)return;const n=document.createElement(i.tagName);n.innerHTML=e!=null?e:i.innerHTML;for(const o of i.getAttributeNames())n.setAttribute(o,(a=i.getAttribute(o))!=null?a:"");return{mount:o=>o.appendChild(n)}}function Ww(t){const e=[];return new Promise(r=>{const i=new MutationObserver(n=>{for(const{addedNodes:a}of n)a.forEach(o=>o instanceof HTMLElement&&t(o,e))});i.observe(document.head,{childList:!0}),document.addEventListener("DOMContentLoaded",()=>{r(e),i.disconnect()})})}function Hw(t){return Oc(this,null,function*(){const e=yield Ww((r,i)=>{/^(?:script|template|style)$/.test(r.localName)&&(r.hasAttribute("src")||(i.push(r.outerHTML),r.localName==="style"?r.onload=r.remove:r.remove()))});t(e.join(`
200
- `))})}Hw(t=>{var a,o,h;const e=document.body,r={id:"setupin",appName:"APP$",mount:"body"},{esmCode:i,cssCode:n}=Gw(t,r);(a=mc('<script type="importmap">',JSON.stringify({imports:{vue:"https://unpkg.com/vue@latest/dist/vue.runtime.esm-browser.prod.js"}})))==null||a.mount(e),(o=mc('<script type="module">',`${zw}
201
- ${i}`))==null||o.mount(e),n&&((h=mc("<style>",n))==null||h.mount(document.head))})})();
200
+ `))})}Hw(t=>{var n,a,o;const e=document.body,{esmCode:r,cssCode:i}=Gw(t,{id:"setupin",mount:"body"});(n=mc('<script type="importmap">',JSON.stringify({imports:{vue:"https://unpkg.com/vue@latest/dist/vue.runtime.esm-browser.prod.js"}})))==null||n.mount(e),(a=mc('<script type="module">',`${zw}
201
+ ${r}`))==null||a.mount(e),i&&((o=mc("<style>",i))==null||o.mount(document.head))})})();
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "setupin",
3
3
  "type": "module",
4
- "version": "3.3.0-beta.1",
4
+ "version": "3.3.0",
5
5
  "description": "Vue SFC? HTML! <script setup> in html",
6
6
  "author": "tofu-xx <tofu-xx@foxmail.com>",
7
7
  "license": "MIT",
@@ -36,12 +36,15 @@
36
36
  "devDependencies": {
37
37
  "@antfu/eslint-config": "^8.2.0",
38
38
  "@antfu/ni": "^30.0.0",
39
+ "@playwright/test": "^1.60.0",
39
40
  "@types/node": "^25.6.0",
40
41
  "bumpp": "^11.0.1",
41
42
  "eslint": "^10.2.0",
42
43
  "eslint-plugin-format": "^2.0.1",
44
+ "happy-dom": "^20.10.1",
43
45
  "taze": "^19.11.0",
44
- "vite": "^6.0.11"
46
+ "vite": "^6.0.11",
47
+ "vitest": "^4.1.8"
45
48
  },
46
49
  "scripts": {
47
50
  "build": "zsh scripts/build.zsh",
@@ -49,6 +52,10 @@
49
52
  "release": "nr tag && nr build && pnpm publish",
50
53
  "up": "taze major -I",
51
54
  "lint": "eslint .",
52
- "lint:fix": "eslint . --fix"
55
+ "lint:fix": "eslint . --fix",
56
+ "test": "vitest run",
57
+ "test:watch": "vitest",
58
+ "test:e2e": "playwright test --config e2e/playwright.config.ts",
59
+ "test:e2e:ui": "playwright test --config e2e/playwright.config.ts --headed"
53
60
  }
54
61
  }