setupin 3.0.0 → 3.1.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
@@ -10,32 +10,111 @@
10
10
  <a href="https://bundlephobia.com/package/setupin"><img src="https://img.shields.io/bundlephobia/minzip/setupin"></a>
11
11
  </p>
12
12
 
13
- ## 😏 Why setupin
13
+ ## 😏 What is a setupin?
14
14
 
15
- **setupin** allows you to write Vue's [\<script **setup**\>](https://vuejs.org/api/sfc-script-setup.html)**in** HTML.
15
+ **setupin** allows you to write Vue's [\<script **setup**>](https://vuejs.org/api/sfc-script-setup.html)**in** HTML.
16
16
 
17
- 1. **Easy to learn**
18
- > Offer a friendly environment for beginners to easily grasp the core usage of Vue.
19
- 2. **Simple development**
20
- > Provide a convenient way to rapidly develop small webpage without complex configurations.
21
- 3. **Quick experience**
22
- > Allow users to quickly experiment with Vue's new features in HTML and feel its charm.
17
+ Using the [vue/compiler-sfc](https://github.com/vuejs/core/tree/main/packages/compiler-sfc#readme), which compiled at runtime for esm vue code format, and dynamic execution.
23
18
 
24
- ## 🤯 setupin.html _vs_ setup.vue
19
+ ## 🤯 Code comparison
25
20
 
26
- <p align="center">
27
- <img src="./public/setup.vue.svg" width="49%">
28
- <img src="./public/setupin.html.svg" width="49%">
29
- </p>
21
+ <h4 align=center>esm.html</h4>
22
+ It's a little more complicated
23
+
24
+ ```html
25
+ <!DOCTYPE html>
26
+ <html lang="en">
27
+ <head>
28
+ <meta charset="UTF-8">
29
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
30
+ <title>esm</title>
31
+ <style>
32
+ button {
33
+ font-size: larger;
34
+ }
35
+ </style>
36
+ </head>
37
+ <body>
38
+ <div id="app">
39
+ <button @click="count++">{{ count }}</button>
40
+ </div>
41
+
42
+ <script type="module">
43
+ import { createApp, defineComponent, ref } from 'https://unpkg.com/vue/dist/vue.esm-browser.js';
44
+ const App = defineComponent(() => {
45
+ const count = ref(0);
46
+ return {
47
+ count
48
+ };
49
+ });
50
+ createApp(App).mount('#app')
51
+ </script>
52
+ </body>
53
+ </html>
54
+ ```
55
+
56
+ <h4 align=center>setup.vue</h4>
57
+ Cannot run directly in the browser
58
+
59
+ ```html
60
+ <script setup>
61
+ import { ref } from 'vue'
62
+ const count = ref(0)
63
+ </script>
64
+
65
+ <template>
66
+ <button @click="count++">{{ count }}</button>
67
+ </template>
68
+
69
+ <style>
70
+ button {
71
+ font-size: larger;
72
+ }
73
+ </style>
74
+ ```
75
+
76
+ <h4 align=center>setupin.html</h4>
77
+ unit as one
30
78
 
31
- How about that? Aren't they similar
79
+ ```html
80
+ <head>
81
+ <meta charset="UTF-8">
82
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
83
+ <title>setupin</title>
84
+ <script src="https://unpkg.com/setupin"></script>
85
+ </head>
86
+
87
+ <script setup>
88
+ import { ref } from 'vue'
89
+ const count = ref(0)
90
+ </script>
91
+
92
+ <template>
93
+ <button @click="count++">{{ count }}</button>
94
+ </template>
95
+
96
+ <style>
97
+ button {
98
+ font-size: larger;
99
+ }
100
+ </style>
101
+ ```
32
102
 
103
+ It's exactly the same as [\<script setup>](https://vuejs.org/api/sfc-script-setup.html) except for the \<head>
33
104
  ## 🤓 Characteristics
34
105
 
35
- - [x] supports esm import syntax
36
106
  - [x] [top-level await](https://vuejs.org/api/sfc-script-setup.html#top-level-await)
37
107
  - [x] [sfc css features](https://vuejs.org/api/sfc-css-features.html)
38
- - [x] vue3 macro functions
108
+ - [ ] Split [component](https://vuejs.org/guide/essentials/component-basics.html)
109
+
110
+ ## 🤔 Why setupin
111
+
112
+ 1. **Easy to learn**
113
+ Offer a friendly environment for beginners to easily grasp the core usage of Vue.
114
+ 2. **Simple development**
115
+ Provide a convenient way to rapidly develop small webpage without complex configurations.
116
+ 3. **Quick experience**
117
+ Allow users to quickly experiment with Vue's new features in HTML and feel its charm.
39
118
 
40
119
  ## 😝 Playground
41
120
 
package/README.zh-CN.md CHANGED
@@ -10,32 +10,114 @@
10
10
  <a href="https://bundlephobia.com/package/setupin"><img src="https://img.shields.io/bundlephobia/minzip/setupin"></a>
11
11
  </p>
12
12
 
13
- ## 😏 为什么选择 setupin
13
+ ## 😏 setupin 是什么?
14
14
 
15
- **setupin** 允许你在 HTML 中编写 Vue 的 [\<script setup\>](https://vuejs.org/api/sfc-script-setup.html)
15
+ **setupin** 允许你在 HTML 中编写 Vue 的 [\<script setup>](https://cn.vuejs.org/api/sfc-script-setup.html)语法。
16
16
 
17
- 1. **便于学习**
18
- > 为初学者提供一个友好的环境,帮助他们轻松上手 Vue 的核心用法。
19
- 2. **简易开发**
20
- > 提供便捷的方式,助力快速开发小网页,无需繁琐的配置。
21
- 3. **快速体验**
22
- > 让用户可以快速在 HTML 中尝试 Vue 的新特性,感受其魅力。
17
+ 利用[vue/compiler-sfc](https://github.com/vuejs/core/tree/main/packages/compiler-sfc#readme),在运行时编译为esm格式的vue代码,并动态执行。
23
18
 
24
- ## 🤯 setupin.html _vs_ setup.vue
19
+ ## 🤯 代码对比
25
20
 
26
- <p align="center">
27
- <img src="./public/setup.vue.svg" width="49%">
28
- <img src="./public/setupin.html.svg" width="49%">
29
- </p>
21
+ <h4 align=center>esm.html</h4>
22
+ 写法略微复杂
23
+
24
+ ```html
25
+ <!DOCTYPE html>
26
+ <html lang="en">
27
+ <head>
28
+ <meta charset="UTF-8">
29
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
30
+ <title>esm</title>
31
+ <style>
32
+ button {
33
+ font-size: larger;
34
+ }
35
+ </style>
36
+ </head>
37
+ <body>
38
+ <div id="app">
39
+ <button @click="count++">{{ count }}</button>
40
+ </div>
41
+
42
+ <script type="module">
43
+ import { createApp, defineComponent, ref } from 'https://unpkg.com/vue/dist/vue.esm-browser.js';
44
+ const App = defineComponent(() => {
45
+ const count = ref(0);
46
+ return {
47
+ count
48
+ };
49
+ });
50
+ createApp(App).mount('#app')
51
+ </script>
52
+ </body>
53
+ </html>
54
+ ```
55
+
56
+ <h4 align=center>setup.vue</h4>
57
+ 无法直接在浏览器运行
58
+
59
+ ```html
60
+ <script setup>
61
+ import { ref } from 'vue'
62
+ const count = ref(0)
63
+ </script>
64
+
65
+ <template>
66
+ <button @click="count++">{{ count }}</button>
67
+ </template>
68
+
69
+ <style>
70
+ button {
71
+ font-size: larger;
72
+ }
73
+ </style>
74
+ ```
30
75
 
31
- 怎么样, 它们很像吧。
76
+ <h4 align=center>setupin.html</h4>
77
+ 合二为一
78
+
79
+ ```html
80
+ <head>
81
+ <meta charset="UTF-8">
82
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
83
+ <title>setupin</title>
84
+ <script src="https://unpkg.com/setupin"></script>
85
+ </head>
86
+
87
+ <script setup>
88
+ import { ref } from 'vue'
89
+ const count = ref(0)
90
+ </script>
91
+
92
+ <template>
93
+ <button @click="count++">{{ count }}</button>
94
+ </template>
95
+
96
+ <style>
97
+ button {
98
+ font-size: larger;
99
+ }
100
+ </style>
101
+ ```
102
+
103
+ 除了\<head>之外和[\<script setup>](https://cn.vuejs.org/api/sfc-script-setup.html)写法完全一致
32
104
 
33
105
  ## 🤓 特性
34
106
 
35
- - [x] 支持 esm import 语法
36
107
  - [x] [顶层 await](https://cn.vuejs.org/api/sfc-script-setup.html#top-level-await)
37
108
  - [x] [CSS 功能](https://cn.vuejs.org/api/sfc-css-features)
38
- - [x] vue3 宏函数
109
+ - [ ] 拆分 [组件](https://cn.vuejs.org/guide/essentials/component-basics.html)
110
+
111
+ ## 🤔 为什么选择 setupin
112
+
113
+ 1. **便于学习**
114
+ 为初学者提供一个友好的环境,帮助他们轻松上手 Vue 的核心用法。
115
+
116
+ 2. **简易开发**
117
+ 提供便捷的方式,助力快速开发小网页,无需繁琐的配置。
118
+
119
+ 3. **快速体验**
120
+ 让用户可以快速在 HTML 中尝试 Vue 的新特性,感受其魅力。
39
121
 
40
122
  ## 😝 演练场
41
123
 
package/dist/main.js CHANGED
@@ -51,26 +51,25 @@ var __async = (__this, __arguments, generator) => {
51
51
  };
52
52
  (function() {
53
53
  "use strict";
54
- const ASCII_LOGO = "/***************************************\r\n** _ _ **\r\n** ___ ___| |_ _ _ _ __ (_)_ __ **\r\n** / __|/ _ \\ __| | | | '_ \\| | '_ \\ **\r\n** \\__ \\ __/ |_| |_| | |_/ | | | | | **\r\n** |___/\\___|\\__|\\__,_| .__/|_|_| |_| **\r\n** |_| **\r\n***************************************/\r\n";
54
+ const ASCII_LOGO = "\r\n/***************************************\r\n** _ _ **\r\n** ___ ___| |_ _ _ _ __ (_)_ __ **\r\n** / __|/ _ \\ __| | | | '_ \\| | '_ \\ **\r\n** \\__ \\ __/ |_| |_| | |_/ | | | | | **\r\n** |___/\\___|\\__|\\__,_| .__/|_|_| |_| **\r\n** |_| **\r\n***************************************/\r\n";
55
55
  const APP_VAR_NAME = "APP$";
56
56
  const REPO_NAME = "setupin";
57
- const IMPORTS_JSON = JSON.stringify({ imports: { vue: "https://unpkg.com/vue/dist/vue.runtime.esm-browser.js" } });
57
+ const IMPORTS_JSON = JSON.stringify({ imports: { vue: "https://unpkg.com/vue@latest/dist/vue.runtime.esm-browser.js" } });
58
58
  const INIT_CODE = `
59
- <script>
60
59
  ${ASCII_LOGO}
61
60
  import * as Vue from "vue";
62
- let ${APP_VAR_NAME} = {}
63
- <\/script>
61
+ let ${APP_VAR_NAME} = Object.create(null);
64
62
  `;
65
63
  const CREATE_APP_CODE = `
66
- const { createApp } = Vue
67
- createApp(${APP_VAR_NAME}).mount(document.body)
68
- `;
69
- const CREATE_ASYNC_APP_CODE = `
70
- const { createApp, h, Suspense } = Vue
71
- createApp({
72
- render: () => h(Suspense, null, { default: () => h(${APP_VAR_NAME}) })
73
- }).mount(document.body)
64
+ Vue.createApp(Vue.defineComponent(
65
+ String(${APP_VAR_NAME}.setup).startsWith('async')
66
+ ? () => () =>
67
+ Vue.h(Vue.Suspense, null, {
68
+ default: Vue.h(${APP_VAR_NAME}),
69
+ fallback: Vue.h('div', 'Loading...'),
70
+ })
71
+ : ${APP_VAR_NAME}
72
+ )).mount(document.body)
74
73
  `;
75
74
  /**
76
75
  * @vue/compiler-sfc v3.5.12
@@ -45876,22 +45875,24 @@ ${exposeCall}`
45876
45875
  const id = REPO_NAME;
45877
45876
  function compilerSfc(source) {
45878
45877
  var _a2, _b2;
45879
- const sfcParseResult = parse$2(INIT_CODE + source, { filename });
45878
+ const sfcParseResult = parse$2(source, { filename });
45880
45879
  sfcParseResult.errors.forEach((e) => {
45881
45880
  console.warn(e);
45882
45881
  });
45883
- const sfcScriptBlock = compileScript(sfcParseResult.descriptor, { id });
45882
+ const sfcScriptBlock = compileScript(sfcParseResult.descriptor, { id, isProd: false });
45884
45883
  const sfcTemplateCompileResults = compileTemplate({
45885
45884
  id,
45886
45885
  filename,
45887
- source: (_b2 = (_a2 = sfcParseResult.descriptor.template) == null ? void 0 : _a2.content) != null ? _b2 : ""
45886
+ source: (_b2 = (_a2 = sfcParseResult.descriptor.template) == null ? void 0 : _a2.content) != null ? _b2 : "",
45887
+ isProd: false
45888
45888
  });
45889
45889
  const sfcStyleCompileResultsList = sfcParseResult.descriptor.styles.map((style) => {
45890
45890
  return compileStyle({
45891
45891
  id,
45892
45892
  filename,
45893
45893
  source: style.content,
45894
- scoped: style.scoped
45894
+ scoped: style.scoped,
45895
+ isProd: false
45895
45896
  });
45896
45897
  });
45897
45898
  return {
@@ -45902,7 +45903,7 @@ ${exposeCall}`
45902
45903
  }
45903
45904
  function createDom(row, inner) {
45904
45905
  var _a2;
45905
- const container2 = document.createElement("div");
45906
+ const container2 = document.createElement("body");
45906
45907
  container2.insertAdjacentHTML("afterbegin", row);
45907
45908
  const sample = container2.firstElementChild;
45908
45909
  const dom = document.createElement(sample.tagName);
@@ -45911,9 +45912,7 @@ ${exposeCall}`
45911
45912
  dom.setAttribute(n2, (_a2 = sample.getAttribute(n2)) != null ? _a2 : "");
45912
45913
  }
45913
45914
  return {
45914
- mount(el) {
45915
- el.appendChild(dom);
45916
- }
45915
+ mount: (el) => el.appendChild(dom)
45917
45916
  };
45918
45917
  }
45919
45918
  function watchRoot(handler) {
@@ -45937,13 +45936,18 @@ ${exposeCall}`
45937
45936
  }
45938
45937
  function awaitCompileSfc(handler) {
45939
45938
  return __async(this, null, function* () {
45940
- const sources = yield watchRoot((node2, data) => {
45941
- if (/^(?:script|template|style)$/.test(node2.localName)) {
45942
- data.push(node2.outerHTML);
45943
- node2.localName === "style" ? node2.onload = node2.remove : node2.remove();
45944
- }
45939
+ const clientCodeList = yield watchRoot((node2, clientCodeList2) => {
45940
+ if (!/^(?:script|template|style)$/.test(node2.localName))
45941
+ return;
45942
+ if (node2.hasAttribute("src"))
45943
+ return;
45944
+ clientCodeList2.push(node2.outerHTML);
45945
+ node2.localName === "style" ? node2.onload = node2.remove : node2.remove();
45945
45946
  });
45946
- const { sfcScriptBlock, sfcTemplateCompileResults, sfcStyleCompileResultsList } = compilerSfc(sources.join("\n"));
45947
+ const hasScript = clientCodeList.some((code) => code.slice(1, 7) === "script");
45948
+ if (!hasScript)
45949
+ clientCodeList.push("<script>/* empty script */<\/script>");
45950
+ const { sfcScriptBlock, sfcTemplateCompileResults, sfcStyleCompileResultsList } = compilerSfc(clientCodeList.join("\n"));
45947
45951
  handler(sfcStyleCompileResultsList, sfcScriptBlock, sfcTemplateCompileResults);
45948
45952
  });
45949
45953
  }
@@ -45952,27 +45956,27 @@ ${exposeCall}`
45952
45956
  }
45953
45957
  function generateEsmCode(sfcScriptBlock, sfcTemplateCompileResults) {
45954
45958
  return `
45959
+ ${INIT_CODE}
45955
45960
  ${_scriptTransform(sfcScriptBlock)}
45956
45961
  ${_templateTransform(sfcTemplateCompileResults)}
45957
- if(String(${APP_VAR_NAME}.setup).startsWith('async')){${CREATE_ASYNC_APP_CODE}}
45958
- else{${CREATE_APP_CODE}}
45962
+ ${CREATE_APP_CODE}
45959
45963
  `;
45964
+ function _scriptTransform(sfcScriptBlock2) {
45965
+ const s = new MagicString(sfcScriptBlock2.content);
45966
+ s.replace("export default", `${APP_VAR_NAME} =`);
45967
+ s.replace("Object.defineProperty(__returned__,", "// ");
45968
+ return s.toString();
45969
+ }
45970
+ function _templateTransform(sfcTemplateCompileResults2) {
45971
+ const t = new MagicString(sfcTemplateCompileResults2.code);
45972
+ t.replace("export function render", `${APP_VAR_NAME}.render = function`);
45973
+ return t.toString();
45974
+ }
45960
45975
  }
45961
- function _scriptTransform(sfcScriptBlock) {
45962
- const s = new MagicString(sfcScriptBlock.content);
45963
- s.replace("export default", `${APP_VAR_NAME} =`);
45964
- s.replace("Object.defineProperty(__returned__,", "// ");
45965
- return s.toString();
45966
- }
45967
- function _templateTransform(sfcTemplateCompileResults) {
45968
- const t = new MagicString(sfcTemplateCompileResults.code);
45969
- t.replace("export function render", `${APP_VAR_NAME}.render = function`);
45970
- return t.toString();
45971
- }
45972
- awaitCompileSfc((compiledStyles, ...compiledSetupAndRender) => {
45976
+ awaitCompileSfc((compiledStyleList, ...compiledSetupAndRender) => {
45973
45977
  _toHead(`<script ${REPO_NAME} type="importmap">${IMPORTS_JSON}<\/script>`);
45974
45978
  _toHead(`<script ${REPO_NAME} type="module">`, generateEsmCode(...compiledSetupAndRender));
45975
- _toHead(`<style ${REPO_NAME}>`, generateStyleCode(compiledStyles));
45979
+ _toHead(`<style ${REPO_NAME}>`, generateStyleCode(compiledStyleList));
45976
45980
  });
45977
45981
  function _toHead(...args) {
45978
45982
  createDom(...args).mount(document.head);