mirror of https://github.com/vuejs/core.git
feat: binding
This commit is contained in:
parent
717aad275d
commit
1d2f66e111
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"semi": false,
|
||||
"singleQuote": true,
|
||||
"trailingComma": "all"
|
||||
}
|
|
@ -1,27 +1,79 @@
|
|||
import {
|
||||
CodegenContext,
|
||||
CodegenOptions,
|
||||
CodegenResult
|
||||
CodegenResult,
|
||||
} from '@vue/compiler-dom'
|
||||
import { RootIRNode } from './transform'
|
||||
import { DynamicChildren, IRNodeTypes, RootIRNode } from './transform'
|
||||
|
||||
// IR -> JS codegen
|
||||
export function generate(
|
||||
ast: RootIRNode,
|
||||
ir: RootIRNode,
|
||||
options: CodegenOptions & {
|
||||
onContextCreated?: (context: CodegenContext) => void
|
||||
} = {}
|
||||
} = {},
|
||||
): CodegenResult {
|
||||
let code = ''
|
||||
let preamble = "import { template } from 'vue/vapor'\n"
|
||||
let preamble = `import { watchEffect } from 'vue'
|
||||
import { template, setAttr, setText, children, on, insert } from 'vue/vapor'\n`
|
||||
|
||||
const isSetupInlined = !!options.inline
|
||||
|
||||
preamble += ast.template
|
||||
preamble += ir.template
|
||||
.map((template, i) => `const t${i} = template(\`${template.template}\`)\n`)
|
||||
.join('')
|
||||
|
||||
code += 'const root = t0()\n'
|
||||
code += `const root = t0()\n`
|
||||
|
||||
if (ir.children[0]) {
|
||||
code += `const {${genChildrens(
|
||||
ir.children[0].children,
|
||||
)}} = children(root)\n`
|
||||
}
|
||||
|
||||
for (const opration of ir.opration) {
|
||||
switch (opration.type) {
|
||||
case IRNodeTypes.TEXT_NODE: {
|
||||
code += `const n${opration.id} = document.createTextNode(${opration.content})\n`
|
||||
break
|
||||
}
|
||||
|
||||
case IRNodeTypes.INSERT_NODE:
|
||||
{
|
||||
let anchor = ''
|
||||
if (typeof opration.anchor === 'number') {
|
||||
anchor = `, n${opration.anchor}`
|
||||
} else if (opration.anchor === 'first') {
|
||||
anchor = `, 0 /* InsertPosition.FIRST */`
|
||||
}
|
||||
code += `insert(n${opration.element}, n${opration.parent}${anchor})\n`
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
for (const [expr, effects] of Object.entries(ir.effect)) {
|
||||
let scope = `watchEffect(() => {\n`
|
||||
for (const effect of effects) {
|
||||
switch (effect.type) {
|
||||
case IRNodeTypes.SET_PROP:
|
||||
scope += `setAttr(n${effect.element}, ${JSON.stringify(
|
||||
effect.name,
|
||||
)}, undefined, ${expr})\n`
|
||||
break
|
||||
case IRNodeTypes.SET_TEXT:
|
||||
scope += `setText(n${effect.element}, undefined, ${expr})\n`
|
||||
break
|
||||
case IRNodeTypes.SET_EVENT:
|
||||
scope += `on(n${effect.element}, ${JSON.stringify(
|
||||
effect.name,
|
||||
)}, ${expr})\n`
|
||||
break
|
||||
}
|
||||
}
|
||||
scope += '})\n'
|
||||
code += scope
|
||||
}
|
||||
|
||||
code += 'return root'
|
||||
|
||||
const functionName = options.ssr ? `ssrRender` : `render`
|
||||
|
@ -33,7 +85,22 @@ export function generate(
|
|||
|
||||
return {
|
||||
code,
|
||||
ast: ast as any,
|
||||
preamble
|
||||
ast: ir as any,
|
||||
preamble,
|
||||
}
|
||||
}
|
||||
|
||||
function genChildrens(children: DynamicChildren) {
|
||||
let str = ''
|
||||
for (const [index, child] of Object.entries(children)) {
|
||||
str += ` ${index}: [`
|
||||
if (child.store) {
|
||||
str += `n${child.id}`
|
||||
}
|
||||
if (Object.keys(child.children).length) {
|
||||
str += `, {${genChildrens(child.children)}}`
|
||||
}
|
||||
str += '],'
|
||||
}
|
||||
return str
|
||||
}
|
||||
|
|
|
@ -1,17 +1,25 @@
|
|||
import {
|
||||
type NodeTypes,
|
||||
RootNode,
|
||||
Node,
|
||||
TemplateChildNode,
|
||||
ElementNode,
|
||||
AttributeNode,
|
||||
SourceLocation,
|
||||
NodeTypes,
|
||||
InterpolationNode,
|
||||
TransformOptions
|
||||
TransformOptions,
|
||||
DirectiveNode,
|
||||
} from '@vue/compiler-dom'
|
||||
|
||||
export const enum IRNodeTypes {
|
||||
ROOT,
|
||||
TEMPLATE_GENERATOR
|
||||
TEMPLATE_GENERATOR,
|
||||
SET_PROP,
|
||||
SET_TEXT,
|
||||
SET_EVENT,
|
||||
|
||||
INSERT_NODE,
|
||||
TEXT_NODE,
|
||||
}
|
||||
|
||||
export interface IRNode {
|
||||
|
@ -22,6 +30,9 @@ export interface IRNode {
|
|||
export interface RootIRNode extends IRNode {
|
||||
type: IRNodeTypes.ROOT
|
||||
template: Array<TemplateGeneratorIRNode>
|
||||
children: DynamicChildren
|
||||
effect: Record<string, EffectNode[]>
|
||||
opration: OprationNode[]
|
||||
helpers: Set<string>
|
||||
}
|
||||
|
||||
|
@ -30,89 +41,349 @@ export interface TemplateGeneratorIRNode extends IRNode {
|
|||
template: string
|
||||
}
|
||||
|
||||
export interface SetPropIRNode extends IRNode {
|
||||
type: IRNodeTypes.SET_PROP
|
||||
element: number
|
||||
name: string
|
||||
}
|
||||
|
||||
export interface SetTextIRNode extends IRNode {
|
||||
type: IRNodeTypes.SET_TEXT
|
||||
element: number
|
||||
}
|
||||
|
||||
export interface SetEventIRNode extends IRNode {
|
||||
type: IRNodeTypes.SET_EVENT
|
||||
element: number
|
||||
name: string
|
||||
}
|
||||
|
||||
export interface TextNodeIRNode extends IRNode {
|
||||
type: IRNodeTypes.TEXT_NODE
|
||||
id: number
|
||||
content: string
|
||||
}
|
||||
|
||||
export interface InsertNodeIRNode extends IRNode {
|
||||
type: IRNodeTypes.INSERT_NODE
|
||||
element: number
|
||||
parent: number
|
||||
anchor: number | 'first' | 'last'
|
||||
}
|
||||
|
||||
export type EffectNode = SetPropIRNode | SetTextIRNode | SetEventIRNode
|
||||
export type OprationNode = TextNodeIRNode | InsertNodeIRNode
|
||||
|
||||
export interface DynamicChild {
|
||||
id: number | null
|
||||
store: boolean
|
||||
children: DynamicChildren
|
||||
}
|
||||
export type DynamicChildren = Record<number, DynamicChild>
|
||||
|
||||
export interface TransformContext<T extends Node = Node> {
|
||||
node: T
|
||||
parent: TransformContext | null
|
||||
root: TransformContext<RootNode>
|
||||
index: number
|
||||
options: TransformOptions
|
||||
ir: RootIRNode
|
||||
template: string
|
||||
children: DynamicChildren
|
||||
store: boolean
|
||||
ghost: boolean
|
||||
|
||||
getElementId(): number
|
||||
registerEffect(expr: string, effectNode: EffectNode): void
|
||||
registerTemplate(): number
|
||||
}
|
||||
|
||||
function createRootContext(
|
||||
ir: RootIRNode,
|
||||
node: RootNode,
|
||||
options: TransformOptions,
|
||||
): TransformContext<RootNode> {
|
||||
let i = 0
|
||||
const { effect: bindings } = ir
|
||||
|
||||
const ctx: TransformContext<RootNode> = {
|
||||
node,
|
||||
parent: null,
|
||||
index: 0,
|
||||
root: undefined as any, // set later
|
||||
options,
|
||||
ir,
|
||||
children: {},
|
||||
store: false,
|
||||
ghost: false,
|
||||
|
||||
getElementId: () => i++,
|
||||
registerEffect(expr, effectNode) {
|
||||
if (!bindings[expr]) bindings[expr] = []
|
||||
bindings[expr].push(effectNode)
|
||||
},
|
||||
|
||||
template: '',
|
||||
registerTemplate() {
|
||||
if (!ctx.template) return -1
|
||||
|
||||
const idx = ir.template.findIndex((t) => t.template === ctx.template)
|
||||
if (idx !== -1) return idx
|
||||
|
||||
ir.template.push({
|
||||
type: IRNodeTypes.TEMPLATE_GENERATOR,
|
||||
template: ctx.template,
|
||||
loc: node.loc,
|
||||
})
|
||||
return ir.template.length - 1
|
||||
},
|
||||
}
|
||||
ctx.root = ctx
|
||||
return ctx
|
||||
}
|
||||
|
||||
function createContext<T extends TemplateChildNode>(
|
||||
node: T,
|
||||
parent: TransformContext,
|
||||
index: number,
|
||||
): TransformContext<T> {
|
||||
let id: number | undefined
|
||||
const getElementId = () => {
|
||||
if (id !== undefined) return id
|
||||
return (id = parent.root.getElementId())
|
||||
}
|
||||
const children = {}
|
||||
|
||||
const ctx: TransformContext<T> = {
|
||||
...parent,
|
||||
node,
|
||||
parent,
|
||||
index,
|
||||
get template() {
|
||||
return parent.template
|
||||
},
|
||||
set template(t) {
|
||||
parent.template = t
|
||||
},
|
||||
getElementId,
|
||||
|
||||
children,
|
||||
store: false,
|
||||
}
|
||||
return ctx
|
||||
}
|
||||
|
||||
// AST -> IR
|
||||
export function transform(
|
||||
root: RootNode,
|
||||
options: TransformOptions = {}
|
||||
options: TransformOptions = {},
|
||||
): RootIRNode {
|
||||
const template = transformChildren(root.children)
|
||||
// {
|
||||
// type: IRNodeTypes.TEMPLATE_GENERATOR,
|
||||
// template,
|
||||
// loc: root.loc
|
||||
// }
|
||||
|
||||
return {
|
||||
const ir: RootIRNode = {
|
||||
type: IRNodeTypes.ROOT,
|
||||
loc: root.loc,
|
||||
template: [
|
||||
{
|
||||
type: IRNodeTypes.TEMPLATE_GENERATOR,
|
||||
template,
|
||||
loc: root.loc
|
||||
}
|
||||
],
|
||||
helpers: new Set(['template'])
|
||||
template: [],
|
||||
children: {},
|
||||
effect: Object.create(null),
|
||||
opration: [],
|
||||
helpers: new Set(['template']),
|
||||
}
|
||||
const ctx = createRootContext(ir, root, options)
|
||||
transformChildren(ctx, true)
|
||||
ctx.registerTemplate()
|
||||
ir.children = ctx.children
|
||||
|
||||
console.log(JSON.stringify(ir, undefined, 2))
|
||||
|
||||
return ir
|
||||
}
|
||||
|
||||
function transformChildren(children: TemplateChildNode[]) {
|
||||
let template: string = ''
|
||||
children.forEach((child, i) => walkNode(child))
|
||||
return template
|
||||
function transformChildren(
|
||||
ctx: TransformContext<RootNode | ElementNode>,
|
||||
root?: boolean,
|
||||
) {
|
||||
const {
|
||||
node: { children },
|
||||
} = ctx
|
||||
let index = 0
|
||||
children.forEach((child, i) => walkNode(child, i))
|
||||
|
||||
function walkNode(node: TemplateChildNode, i: number) {
|
||||
const child = createContext(node, ctx, index)
|
||||
const isFirst = i === 0
|
||||
const isLast = i === children.length - 1
|
||||
|
||||
function walkNode(node: TemplateChildNode) {
|
||||
switch (node.type) {
|
||||
case 1 satisfies NodeTypes.ELEMENT: {
|
||||
template += transformElement(node)
|
||||
transformElement(child as TransformContext<ElementNode>)
|
||||
break
|
||||
}
|
||||
case 2 satisfies NodeTypes.TEXT:
|
||||
template += node.content
|
||||
case 2 satisfies NodeTypes.TEXT: {
|
||||
ctx.template += node.content
|
||||
break
|
||||
case 3 satisfies NodeTypes.COMMENT:
|
||||
template += `<!--${node.content}-->`
|
||||
}
|
||||
case 3 satisfies NodeTypes.COMMENT: {
|
||||
ctx.template += `<!--${node.content}-->`
|
||||
break
|
||||
case 5 satisfies NodeTypes.INTERPOLATION:
|
||||
template += transformInterpolation(node)
|
||||
}
|
||||
case 5 satisfies NodeTypes.INTERPOLATION: {
|
||||
transformInterpolation(
|
||||
child as TransformContext<InterpolationNode>,
|
||||
isFirst,
|
||||
isLast,
|
||||
)
|
||||
break
|
||||
// case 12 satisfies NodeTypes.TEXT_CALL:
|
||||
// template += node.content
|
||||
default:
|
||||
template += `[${node.type}]`
|
||||
}
|
||||
default: {
|
||||
ctx.template += `[type: ${node.type}]`
|
||||
}
|
||||
}
|
||||
|
||||
if (Object.keys(child.children).length > 0 || child.store)
|
||||
ctx.children[index] = {
|
||||
id: child.store ? child.getElementId() : null,
|
||||
store: child.store,
|
||||
children: child.children,
|
||||
}
|
||||
|
||||
if (!child.ghost) index++
|
||||
}
|
||||
}
|
||||
|
||||
function transformInterpolation(node: InterpolationNode) {
|
||||
// TODO
|
||||
if (node.content.type === (4 satisfies NodeTypes.SIMPLE_EXPRESSION)) {
|
||||
return `{{ ${node.content.content} }}`
|
||||
}
|
||||
return '[EXP]'
|
||||
// return `{{${node.content.content}}}`
|
||||
}
|
||||
|
||||
function transformElement(node: ElementNode) {
|
||||
function transformElement(ctx: TransformContext<ElementNode>) {
|
||||
const { node } = ctx
|
||||
const { tag, props, children } = node
|
||||
let template = `<${tag}`
|
||||
const propsTemplate = props
|
||||
.filter(
|
||||
(prop): prop is AttributeNode =>
|
||||
prop.type === (6 satisfies NodeTypes.ATTRIBUTE)
|
||||
)
|
||||
.map(prop => transformProp(prop))
|
||||
.join(' ')
|
||||
|
||||
if (propsTemplate) template += ' ' + propsTemplate
|
||||
template += `>`
|
||||
ctx.template += `<${tag}`
|
||||
|
||||
props.forEach((prop) => transformProp(prop, ctx))
|
||||
ctx.template += node.isSelfClosing ? '/>' : `>`
|
||||
|
||||
if (children.length > 0) {
|
||||
template += transformChildren(children)
|
||||
transformChildren(ctx)
|
||||
}
|
||||
if (!node.isSelfClosing) ctx.template += `</${tag}>`
|
||||
}
|
||||
|
||||
function transformInterpolation(
|
||||
ctx: TransformContext<InterpolationNode>,
|
||||
isFirst: boolean,
|
||||
isLast: boolean,
|
||||
) {
|
||||
const { node } = ctx
|
||||
|
||||
if (node.content.type === (4 satisfies NodeTypes.SIMPLE_EXPRESSION)) {
|
||||
const expr = processExpression(ctx, node.content.content)
|
||||
|
||||
const parent = ctx.parent!
|
||||
const parentId = parent.getElementId()
|
||||
parent.store = true
|
||||
|
||||
if (isFirst && isLast) {
|
||||
ctx.registerEffect(expr, {
|
||||
type: IRNodeTypes.SET_TEXT,
|
||||
loc: node.loc,
|
||||
element: parentId,
|
||||
})
|
||||
} else {
|
||||
let id: number
|
||||
let anchor: number | 'first' | 'last'
|
||||
|
||||
if (!isFirst && !isLast) {
|
||||
id = ctx.root.getElementId()
|
||||
anchor = ctx.getElementId()
|
||||
ctx.template += '<!>'
|
||||
ctx.store = true
|
||||
} else {
|
||||
id = ctx.getElementId()
|
||||
ctx.ghost = true
|
||||
anchor = isFirst ? 'first' : 'last'
|
||||
}
|
||||
|
||||
ctx.ir.opration.push(
|
||||
{
|
||||
type: IRNodeTypes.TEXT_NODE,
|
||||
loc: node.loc,
|
||||
id,
|
||||
content: expr,
|
||||
},
|
||||
{
|
||||
type: IRNodeTypes.INSERT_NODE,
|
||||
loc: node.loc,
|
||||
element: id,
|
||||
parent: parentId,
|
||||
anchor,
|
||||
},
|
||||
)
|
||||
|
||||
ctx.registerEffect(expr, {
|
||||
type: IRNodeTypes.SET_TEXT,
|
||||
loc: node.loc,
|
||||
element: id,
|
||||
})
|
||||
}
|
||||
} else {
|
||||
// TODO
|
||||
}
|
||||
// TODO
|
||||
}
|
||||
|
||||
function transformProp(
|
||||
node: DirectiveNode | AttributeNode,
|
||||
ctx: TransformContext<ElementNode>,
|
||||
): void {
|
||||
const { name } = node
|
||||
|
||||
if (node.type === (6 satisfies NodeTypes.ATTRIBUTE)) {
|
||||
if (node.value) {
|
||||
ctx.template += ` ${name}="${node.value.content}"`
|
||||
} else {
|
||||
ctx.template += ` ${name}`
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
template += `</${tag}>`
|
||||
if (!node.exp) {
|
||||
// TODO
|
||||
return
|
||||
} else if (node.exp.type === (8 satisfies NodeTypes.COMPOUND_EXPRESSION)) {
|
||||
// TODO
|
||||
return
|
||||
} else if (
|
||||
!node.arg ||
|
||||
node.arg.type === (8 satisfies NodeTypes.COMPOUND_EXPRESSION)
|
||||
) {
|
||||
// TODO
|
||||
return
|
||||
}
|
||||
|
||||
return template
|
||||
const expr = processExpression(ctx, node.exp.content)
|
||||
ctx.store = true
|
||||
if (name === 'bind') {
|
||||
ctx.registerEffect(expr, {
|
||||
type: IRNodeTypes.SET_PROP,
|
||||
loc: node.loc,
|
||||
element: ctx.getElementId(),
|
||||
name: node.arg.content,
|
||||
})
|
||||
} else if (name === 'on') {
|
||||
ctx.registerEffect(expr, {
|
||||
type: IRNodeTypes.SET_EVENT,
|
||||
loc: node.loc,
|
||||
element: ctx.getElementId(),
|
||||
name: node.arg.content,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
function transformProp(prop: AttributeNode) {
|
||||
const { name, value } = prop
|
||||
if (value) return `${name}="${value.content}"`
|
||||
return name
|
||||
function processExpression(ctx: TransformContext, expr: string) {
|
||||
if (ctx.options.bindingMetadata?.[expr] === 'setup-ref') {
|
||||
expr += '.value'
|
||||
}
|
||||
return expr
|
||||
}
|
||||
|
|
|
@ -1,2 +1,8 @@
|
|||
export { template } from './template'
|
||||
export { render } from './render'
|
||||
export * from './render'
|
||||
export * from './on'
|
||||
|
||||
type Children = Record<number, [ChildNode, Children]>
|
||||
export function children(n: ChildNode): Children {
|
||||
return { ...Array.from(n.childNodes).map(n => [n, children(n)]) }
|
||||
}
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
export const on = (
|
||||
el: any,
|
||||
event: string,
|
||||
handler: () => any,
|
||||
options?: EventListenerOptions
|
||||
) => {
|
||||
el.addEventListener(event, handler, options)
|
||||
}
|
|
@ -29,11 +29,22 @@ export function normalizeContainer(container: string | ParentNode): ParentNode {
|
|||
: container
|
||||
}
|
||||
|
||||
export const enum InsertPosition {
|
||||
FIRST,
|
||||
LAST
|
||||
}
|
||||
|
||||
export function insert(
|
||||
block: Block,
|
||||
parent: ParentNode,
|
||||
anchor: Node | null = null
|
||||
anchor: Node | InsertPosition | null = null
|
||||
) {
|
||||
anchor =
|
||||
typeof anchor === 'number'
|
||||
? anchor === InsertPosition.FIRST
|
||||
? parent.firstChild
|
||||
: null
|
||||
: anchor
|
||||
// if (!isHydrating) {
|
||||
if (block instanceof Node) {
|
||||
parent.insertBefore(block, anchor)
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
"enableNonBrowserBranches": true
|
||||
},
|
||||
"dependencies": {
|
||||
"@vue/compiler-vapor": "workspace:^",
|
||||
"monaco-editor": "^0.44.0",
|
||||
"source-map-js": "^1.0.2"
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import * as m from 'monaco-editor'
|
||||
import { compile, CompilerError, CompilerOptions } from '@vue/compiler-dom'
|
||||
import { CompilerError, CompilerOptions } from '@vue/compiler-dom'
|
||||
import { compile } from '@vue/compiler-vapor'
|
||||
import { compile as ssrCompile } from '@vue/compiler-ssr'
|
||||
import {
|
||||
defaultOptions,
|
||||
|
@ -92,8 +93,8 @@ window.init = () => {
|
|||
console.log(`AST: `, ast)
|
||||
console.log(`Options: `, toRaw(compilerOptions))
|
||||
lastSuccessfulCode = code + `\n\n// Check the console for the AST`
|
||||
lastSuccessfulMap = new SourceMapConsumer(map!)
|
||||
lastSuccessfulMap!.computeColumnSpans()
|
||||
// lastSuccessfulMap = new SourceMapConsumer(map!)
|
||||
// lastSuccessfulMap!.computeColumnSpans()
|
||||
} catch (e: any) {
|
||||
lastSuccessfulCode = `/* ERROR: ${e.message} (see console for more info) */`
|
||||
console.error(e)
|
||||
|
|
|
@ -10,8 +10,8 @@
|
|||
"vue": "workspace:*"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vitejs/plugin-vue": "^4.4.0",
|
||||
"vite": "^4.5.0",
|
||||
"@vitejs/plugin-vue": "link:/Users/kevin/Developer/open-source/vite-plugin-vue/packages/plugin-vue",
|
||||
"vite": "^5.0.2",
|
||||
"vite-plugin-inspect": "^0.7.42"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,14 +1,31 @@
|
|||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { ref, computed } from 'vue'
|
||||
|
||||
const count = ref(0)
|
||||
const double = computed(() => count.value * 2)
|
||||
|
||||
const inc = () => count.value++
|
||||
const dec = () => count.value--
|
||||
|
||||
// @ts-expect-error
|
||||
globalThis.count = count
|
||||
// @ts-expect-error
|
||||
globalThis.double = double
|
||||
// @ts-expect-error
|
||||
globalThis.inc = inc
|
||||
// @ts-expect-error
|
||||
globalThis.dec = dec
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<h1 class="red">Hello world</h1>
|
||||
<!-- {{ count }} -->
|
||||
<button style="font-weight: bold">Inc</button>
|
||||
<h1 class="red">Counter</h1>
|
||||
<div>The number is {{ count }}.</div>
|
||||
<div>{{ count }} * 2 = {{ double }}</div>
|
||||
<div style="display: flex; gap: 8px">
|
||||
<button @click="inc">inc</button>
|
||||
<button @click="dec">dec</button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -16,4 +33,10 @@ const count = ref(0)
|
|||
.red {
|
||||
color: red;
|
||||
}
|
||||
|
||||
html {
|
||||
color-scheme: dark;
|
||||
background-color: #000;
|
||||
padding: 10px;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
import { render } from 'vue/vapor'
|
||||
import App from './App.vue'
|
||||
|
||||
// @ts-expect-error
|
||||
render(App.render, '#app')
|
||||
render(() => {
|
||||
// @ts-expect-error
|
||||
const returned = App.setup({}, { expose() {} })
|
||||
return App.render(returned)
|
||||
}, '#app')
|
||||
|
|
|
@ -7,8 +7,10 @@ export default defineConfig({
|
|||
build: {
|
||||
target: 'esnext'
|
||||
},
|
||||
clearScreen: false,
|
||||
plugins: [
|
||||
Vue({
|
||||
isProduction: true,
|
||||
template: {
|
||||
compiler: CompilerVapor
|
||||
}
|
||||
|
|
|
@ -395,6 +395,9 @@ importers:
|
|||
|
||||
packages/template-explorer:
|
||||
dependencies:
|
||||
'@vue/compiler-vapor':
|
||||
specifier: workspace:^
|
||||
version: link:../compiler-vapor
|
||||
monaco-editor:
|
||||
specifier: ^0.44.0
|
||||
version: 0.44.0
|
||||
|
@ -451,14 +454,14 @@ importers:
|
|||
version: link:../packages/vue
|
||||
devDependencies:
|
||||
'@vitejs/plugin-vue':
|
||||
specifier: ^4.4.0
|
||||
version: 4.4.0(vite@4.5.0)(vue@packages+vue)
|
||||
specifier: link:/Users/kevin/Developer/open-source/vite-plugin-vue/packages/plugin-vue
|
||||
version: link:../../../vite-plugin-vue/packages/plugin-vue
|
||||
vite:
|
||||
specifier: ^4.5.0
|
||||
version: 4.5.0(@types/node@20.9.0)(terser@5.22.0)
|
||||
specifier: ^5.0.2
|
||||
version: 5.0.2(@types/node@20.9.0)(terser@5.22.0)
|
||||
vite-plugin-inspect:
|
||||
specifier: ^0.7.42
|
||||
version: 0.7.42(rollup@4.1.4)(vite@4.5.0)
|
||||
version: 0.7.42(rollup@4.1.4)(vite@5.0.2)
|
||||
|
||||
packages:
|
||||
|
||||
|
@ -1728,17 +1731,6 @@ packages:
|
|||
resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==}
|
||||
dev: true
|
||||
|
||||
/@vitejs/plugin-vue@4.4.0(vite@4.5.0)(vue@packages+vue):
|
||||
resolution: {integrity: sha512-xdguqb+VUwiRpSg+nsc2HtbAUSGak25DXYvpQQi4RVU1Xq1uworyoH/md9Rfd8zMmPR/pSghr309QNcftUVseg==}
|
||||
engines: {node: ^14.18.0 || >=16.0.0}
|
||||
peerDependencies:
|
||||
vite: ^4.0.0
|
||||
vue: ^3.2.25
|
||||
dependencies:
|
||||
vite: 4.5.0(@types/node@20.9.0)(terser@5.22.0)
|
||||
vue: link:packages/vue
|
||||
dev: true
|
||||
|
||||
/@vitejs/plugin-vue@4.4.0(vite@5.0.0)(vue@packages+vue):
|
||||
resolution: {integrity: sha512-xdguqb+VUwiRpSg+nsc2HtbAUSGak25DXYvpQQi4RVU1Xq1uworyoH/md9Rfd8zMmPR/pSghr309QNcftUVseg==}
|
||||
engines: {node: ^14.18.0 || >=16.0.0}
|
||||
|
@ -5337,14 +5329,6 @@ packages:
|
|||
rollup: 4.1.4
|
||||
dev: true
|
||||
|
||||
/rollup@3.29.4:
|
||||
resolution: {integrity: sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw==}
|
||||
engines: {node: '>=14.18.0', npm: '>=8.0.0'}
|
||||
hasBin: true
|
||||
optionalDependencies:
|
||||
fsevents: 2.3.3
|
||||
dev: true
|
||||
|
||||
/rollup@4.1.4:
|
||||
resolution: {integrity: sha512-U8Yk1lQRKqCkDBip/pMYT+IKaN7b7UesK3fLSTuHBoBJacCE+oBqo/dfG/gkUdQNNB2OBmRP98cn2C2bkYZkyw==}
|
||||
engines: {node: '>=18.0.0', npm: '>=8.0.0'}
|
||||
|
@ -6187,7 +6171,7 @@ packages:
|
|||
mlly: 1.4.2
|
||||
pathe: 1.1.1
|
||||
picocolors: 1.0.0
|
||||
vite: 5.0.0(@types/node@20.9.0)(terser@5.22.0)
|
||||
vite: 5.0.2(@types/node@20.9.0)(terser@5.22.0)
|
||||
transitivePeerDependencies:
|
||||
- '@types/node'
|
||||
- less
|
||||
|
@ -6199,7 +6183,7 @@ packages:
|
|||
- terser
|
||||
dev: true
|
||||
|
||||
/vite-plugin-inspect@0.7.42(rollup@4.1.4)(vite@4.5.0):
|
||||
/vite-plugin-inspect@0.7.42(rollup@4.1.4)(vite@5.0.2):
|
||||
resolution: {integrity: sha512-JCyX86wr3siQc+p9Kd0t8VkFHAJag0RaQVIpdFGSv5FEaePEVB6+V/RGtz2dQkkGSXQzRWrPs4cU3dRKg32bXw==}
|
||||
engines: {node: '>=14'}
|
||||
peerDependencies:
|
||||
|
@ -6217,18 +6201,18 @@ packages:
|
|||
open: 9.1.0
|
||||
picocolors: 1.0.0
|
||||
sirv: 2.0.3
|
||||
vite: 4.5.0(@types/node@20.9.0)(terser@5.22.0)
|
||||
vite: 5.0.2(@types/node@20.9.0)(terser@5.22.0)
|
||||
transitivePeerDependencies:
|
||||
- rollup
|
||||
- supports-color
|
||||
dev: true
|
||||
|
||||
/vite@4.5.0(@types/node@20.9.0)(terser@5.22.0):
|
||||
resolution: {integrity: sha512-ulr8rNLA6rkyFAlVWw2q5YJ91v098AFQ2R0PRFwPzREXOUJQPtFUG0t+/ZikhaOCDqFoDhN6/v8Sq0o4araFAw==}
|
||||
engines: {node: ^14.18.0 || >=16.0.0}
|
||||
/vite@5.0.0(@types/node@20.9.0)(terser@5.22.0):
|
||||
resolution: {integrity: sha512-ESJVM59mdyGpsiNAeHQOR/0fqNoOyWPYesFto8FFZugfmhdHx8Fzd8sF3Q/xkVhZsyOxHfdM7ieiVAorI9RjFw==}
|
||||
engines: {node: ^18.0.0 || >=20.0.0}
|
||||
hasBin: true
|
||||
peerDependencies:
|
||||
'@types/node': '>= 14'
|
||||
'@types/node': ^18.0.0 || >=20.0.0
|
||||
less: '*'
|
||||
lightningcss: ^1.21.0
|
||||
sass: '*'
|
||||
|
@ -6252,16 +6236,16 @@ packages:
|
|||
optional: true
|
||||
dependencies:
|
||||
'@types/node': 20.9.0
|
||||
esbuild: 0.18.20
|
||||
esbuild: 0.19.5
|
||||
postcss: 8.4.31
|
||||
rollup: 3.29.4
|
||||
rollup: 4.4.1
|
||||
terser: 5.22.0
|
||||
optionalDependencies:
|
||||
fsevents: 2.3.3
|
||||
dev: true
|
||||
|
||||
/vite@5.0.0(@types/node@20.9.0)(terser@5.22.0):
|
||||
resolution: {integrity: sha512-ESJVM59mdyGpsiNAeHQOR/0fqNoOyWPYesFto8FFZugfmhdHx8Fzd8sF3Q/xkVhZsyOxHfdM7ieiVAorI9RjFw==}
|
||||
/vite@5.0.2(@types/node@20.9.0)(terser@5.22.0):
|
||||
resolution: {integrity: sha512-6CCq1CAJCNM1ya2ZZA7+jS2KgnhbzvxakmlIjN24cF/PXhRMzpM/z8QgsVJA/Dm5fWUWnVEsmtBoMhmerPxT0g==}
|
||||
engines: {node: ^18.0.0 || >=20.0.0}
|
||||
hasBin: true
|
||||
peerDependencies:
|
||||
|
|
Loading…
Reference in New Issue