Skip to content

Commit

Permalink
refactor: support browser environments
Browse files Browse the repository at this point in the history
  • Loading branch information
zhiyuanzmj committed Jan 20, 2025
1 parent ba64de1 commit ca22bf4
Show file tree
Hide file tree
Showing 14 changed files with 308 additions and 136 deletions.
9 changes: 2 additions & 7 deletions packages/compiler/src/transforms/transformText.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,14 +65,11 @@ function processTextLike(context: TransformContext<JSXExpressionContainer>) {
const idx = nexts.findIndex((n) => !isTextLike(n))
const nodes = (idx > -1 ? nexts.slice(0, idx) : nexts) as Array<TextLike>

const values = createTextLikeExpressions(nodes, context)
if (!values.length) return

context.dynamic.flags |= DynamicFlag.INSERT | DynamicFlag.NON_TEMPLATE
context.registerOperation({
type: IRNodeTypes.CREATE_TEXT_NODE,
id: context.reference(),
values,
values: createTextLikeExpressions(nodes, context),
effect: false,
})
}
Expand All @@ -82,8 +79,6 @@ function processTextLikeContainer(
context: TransformContext<JSXElement>,
) {
const values = createTextLikeExpressions(children, context)
if (!values.length) return

const literals = values.map(getLiteralExpressionValue)
if (literals.every((l) => l != null)) {
context.childrenTemplate = literals.map((l) => String(l))
Expand All @@ -102,8 +97,8 @@ function createTextLikeExpressions(
) {
const values = []
for (const node of nodes) {
if (isEmptyText(node)) continue
seen.get(context.root)!.add(node)
if (isEmptyText(node)) continue
values.push(resolveExpression(node, context, true))
}
return values
Expand Down
11 changes: 7 additions & 4 deletions packages/compiler/test/transforms/transformChildren.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,17 @@ describe('compiler: children transform', () => {
})

test('comments', () => {
const { code } = compileWithElementTransform('<div>{/*bar*/}</div>')
const { code } = compileWithElementTransform(
'<>{/*foo*/}<div>{/*bar*/}</div></>',
)
expect(code).toMatchInlineSnapshot(`
"import { template as _template } from 'vue/vapor';
"import { createTextNode as _createTextNode, template as _template } from 'vue/vapor';
const t0 = _template("<div></div>")
export function render(_ctx) {
const n0 = t0()
return n0
const n1 = t0()
const n0 = _createTextNode([])
return [n0, n1]
}"
`)
})
Expand Down
11 changes: 10 additions & 1 deletion packages/unplugin/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,11 @@
"require": "./dist/nuxt.cjs",
"import": "./dist/nuxt.js"
},
"./core": {
"dev": "./src/core/index.ts",
"require": "./dist/core/index.cjs",
"import": "./dist/core/index.js"
},
"./*": "./*"
},
"typesVersions": {
Expand Down Expand Up @@ -110,6 +115,10 @@
"require": "./dist/nuxt.cjs",
"import": "./dist/nuxt.js"
},
"./core": {
"require": "./dist/core/index.cjs",
"import": "./dist/core/index.js"
},
"./*": "./*"
},
"scripts": {
Expand Down Expand Up @@ -151,7 +160,7 @@
},
"dependencies": {
"@vue-jsx-vapor/compiler": "workspace:*",
"@vue-macros/common": "^1.10.4",
"@vue-macros/common": "^1.16.1",
"magic-string-stack": "^0.1.1",
"unplugin": "^1.11.0"
},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,27 +1,25 @@
import { effectScope, insert, remove, renderEffect } from 'vue/vapor'
import { toDisplayString } from 'vue'

const fragmentKey = Symbol('')
function createFragment(nodes) {
const fragment = [nodes, document.createTextNode('')]
fragment[fragmentKey] = true
fragment._fragmentKey = true
return fragment
}

function isFragment(node) {
return (
node &&
typeof node === 'object' &&
(node[fragmentKey] || (node.nodes && node.anchor))
(node._fragmentKey || (node.nodes && node.anchor))
)
}

function getFragmentNodes(fragment) {
return fragment[fragmentKey] ? fragment[0] : fragment.nodes
return fragment._fragmentKey ? fragment[0] : fragment.nodes
}

function getFragmentAnchor(fragment) {
return fragment[fragmentKey] ? fragment[1] : fragment.anchor
return fragment._fragmentKey ? fragment[1] : fragment.anchor
}

function normalizeValue(value) {
Expand All @@ -31,7 +29,7 @@ function normalizeValue(value) {
? value
: Array.isArray(value)
? createFragment(value.map(normalizeValue))
: document.createTextNode(toDisplayString(value))
: document.createTextNode(String(value))
}

function resolveValue(current, value) {
Expand Down
4 changes: 2 additions & 2 deletions packages/unplugin/src/core/helper/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
export const helperPrefix = `unplugin-vue-jsx-vapor/helper` as const
export const setTextId = `${helperPrefix}/setText` as const
export { default as setTextCode } from './setText.js?raw'
export const helperId = `${helperPrefix}.js` as const
export { default as helperCode } from './code.js?raw'
25 changes: 15 additions & 10 deletions packages/unplugin/src/core/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,14 @@ import {
getLang,
walkAST,
} from '@vue-macros/common'
import MagicStringStack from 'magic-string-stack'
import { compile } from '@vue-jsx-vapor/compiler'
import MagicStringStack from 'magic-string-stack'
import { helperId } from './helper'
import type { JSXElement, JSXFragment, Node } from '@babel/types'
import type { Options } from '../types'

export * from './helper'

export function transformVueJsxVapor(
code: string,
id: string,
Expand Down Expand Up @@ -51,13 +54,15 @@ export function transformVueJsxVapor(

preamble = preamble.replaceAll(
/(?<=const )t(?=(\d))/g,
`_${preambleIndex}`,
`_t${preambleIndex}`,
)
code = code.replaceAll(/(?<== )t(?=\d)/g, `_${preambleIndex}`)
code = code
.replaceAll(/(?<== )t(?=\d)/g, `_t${preambleIndex}`)
.replaceAll('_ctx: any', '')
preambleIndex++

for (const [, key, value] of preamble.matchAll(
/const (_\d+) = (_template\(.*\))/g,
/const (_t\d+) = (_template\(.*\))/g,
)) {
const result = preambleMap.get(value)
if (result) {
Expand Down Expand Up @@ -100,19 +105,19 @@ export function transformVueJsxVapor(
})
if (helpers.length) {
s.prepend(
`import { ${helpers.map((i) => `${i} as _${i}`)} } from 'unplugin-vue-jsx-vapor/helper/setText';\n`,
`import { ${helpers.map((i) => `${i} as _${i}`).join(', ')} } from '${helperId}';\n`,
)
}

const importResult = Array.from(importSet).map((i) => `${i} as _${i}`)
const importResult = Array.from(importSet)
.map((i) => `${i} as _${i}`)
.join(', ')
if (importResult.length)
s.prepend(`import { ${importResult} } from 'vue/vapor';\n`)

return generateTransform(s, id)
return generateTransform(s as any, id)
}

export function isJSXElement(
node?: Node | null,
): node is JSXElement | JSXFragment {
function isJSXElement(node?: Node | null): node is JSXElement | JSXFragment {
return !!node && (node.type === 'JSXElement' || node.type === 'JSXFragment')
}
7 changes: 3 additions & 4 deletions packages/unplugin/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { type UnpluginFactory, createUnplugin } from 'unplugin'
import { createFilter, transformWithEsbuild } from 'vite'
import { normalizePath } from '@vue-macros/common'
import { createFilter, normalizePath, transformWithEsbuild } from 'vite'
import { transformVueJsxVapor } from './core'
import { helperPrefix, setTextCode, setTextId } from './core/helper'
import { helperCode, helperId, helperPrefix } from './core/helper'
import type { Options } from './types'

export const unpluginFactory: UnpluginFactory<Options | undefined> = (
Expand Down Expand Up @@ -40,7 +39,7 @@ export const unpluginFactory: UnpluginFactory<Options | undefined> = (
return normalizePath(id).startsWith(helperPrefix)
},
load(id) {
if (normalizePath(id) === setTextId) return setTextCode
if (normalizePath(id) === helperId) return helperCode
},
transformInclude,
transform(code, id) {
Expand Down
16 changes: 8 additions & 8 deletions packages/unplugin/test/transform.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,22 @@ describe('transform', () => {
'index.tsx',
)!
expect(code).toMatchInlineSnapshot(`
"import { delegate as _delegate,delegateEvents as _delegateEvents,template as _template,createIf as _createIf } from 'vue/vapor';
const _00 = _template("<div>Hello</div>")
const _11 = _template("<div>World</div>")
"import { delegate as _delegate, delegateEvents as _delegateEvents, template as _template, createIf as _createIf } from 'vue/vapor';
const _t00 = _template("<div>Hello</div>")
const _t11 = _template("<div>World</div>")
_delegateEvents("click", "dblclick");
const a = ((_ctx: any) => {
const n0 = _00()
const a = (() => {
const n0 = _t00()
_delegate(n0, "click", () => onClick)
return n0
})()
const b = ((_ctx: any) => {
const b = (() => {
const n0 = _createIf(() => (foo), () => {
const n2 = _00()
const n2 = _t00()
_delegate(n2, "click", () => onClick)
return n2
}, () => {
const n4 = _11()
const n4 = _t11()
_delegate(n4, "dblclick", () => onDblclick)
return n4
})
Expand Down
2 changes: 1 addition & 1 deletion packages/unplugin/tsup.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import Raw from 'unplugin-raw/esbuild'
import type { Options } from 'tsup'

export default {
entry: ['./src/*.ts'],
entry: ['./src/*.ts', './src/core/index.ts', './src/core/helper/index.ts'],
clean: true,
format: ['cjs', 'esm'],
watch: !!process.env.DEV,
Expand Down
3 changes: 2 additions & 1 deletion playground/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@
"private": true,
"type": "module",
"scripts": {
"dev": "vite --port 5174"
"dev": "node vite.js --port 5174"
},
"devDependencies": {
"unplugin-vue-jsx-vapor": "workspace:*",
"unplugin-vue-macros": "https://pkg.pr.new/vue-macros/vue-macros/unplugin-vue-macros@f4ebeab",
"vite": "^6.0.0",
"vite-hyper-config": "^0.5.0",
"vite-plugin-inspect": "^0.8.4",
"vue": "catalog:"
}
Expand Down
2 changes: 1 addition & 1 deletion playground/src/show.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export default () => {
return (
<>
<input v-model={show.value} type="checkbox" />
<span v-show={show.value}>{show.value}</span>
<span v-show={show.value}>{String(show.value)}</span>
</>
)
}
3 changes: 0 additions & 3 deletions playground/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,6 @@ import VueMacros from 'unplugin-vue-macros/vite'
import VueJsxVapor from 'unplugin-vue-jsx-vapor/vite'

export default defineConfig({
resolve: {
conditions: ['dev'],
},
plugins: [
VueMacros({
plugins: {
Expand Down
7 changes: 7 additions & 0 deletions playground/vite.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { startVite } from 'vite-hyper-config'

startVite(undefined, {
resolve: {
conditions: ['dev'],
},
})
Loading

0 comments on commit ca22bf4

Please sign in to comment.