From d1eed3645281bc8180a1eac51e9b098cfa8870af Mon Sep 17 00:00:00 2001 From: Evan You Date: Sun, 2 Feb 2020 22:08:20 -0500 Subject: [PATCH] refactor(ssr): move escapeHtml to shared --- ...srTransformElement.spec.ts => ssrCompile.spec.ts} | 12 ++++++++++-- packages/compiler-ssr/src/ssrCodegenTransform.ts | 4 ++-- .../src/transforms/ssrTransformElement.ts | 2 +- .../{ssrUtils.spec.ts => interpolate.spec.ts} | 10 ---------- packages/server-renderer/src/index.ts | 11 ++++++++++- packages/server-renderer/src/renderProps.ts | 2 +- packages/server-renderer/src/renderToString.ts | 2 +- packages/shared/__tests__/escapeHtml.spec.ts | 11 +++++++++++ .../src/ssrUtils.ts => shared/src/escapeHtml.ts} | 6 ------ packages/shared/src/index.ts | 1 + 10 files changed, 37 insertions(+), 24 deletions(-) rename packages/compiler-ssr/__tests__/{transforms/ssrTransformElement.spec.ts => ssrCompile.spec.ts} (65%) rename packages/server-renderer/__tests__/{ssrUtils.spec.ts => interpolate.spec.ts} (60%) create mode 100644 packages/shared/__tests__/escapeHtml.spec.ts rename packages/{server-renderer/src/ssrUtils.ts => shared/src/escapeHtml.ts} (86%) diff --git a/packages/compiler-ssr/__tests__/transforms/ssrTransformElement.spec.ts b/packages/compiler-ssr/__tests__/ssrCompile.spec.ts similarity index 65% rename from packages/compiler-ssr/__tests__/transforms/ssrTransformElement.spec.ts rename to packages/compiler-ssr/__tests__/ssrCompile.spec.ts index f8b280a322..14dd767ec3 100644 --- a/packages/compiler-ssr/__tests__/transforms/ssrTransformElement.spec.ts +++ b/packages/compiler-ssr/__tests__/ssrCompile.spec.ts @@ -1,10 +1,10 @@ -import { compile } from '../../src' +import { compile } from '../src' function getElementString(src: string): string { return compile(src).code.match(/_push\((.*)\)/)![1] } -describe('ssr transform element', () => { +describe('ssr compile integration test', () => { test('basic elements', () => { expect(getElementString(`
`)).toMatchInlineSnapshot( `"\`
\`"` @@ -22,4 +22,12 @@ describe('ssr transform element', () => { getElementString(`
`) ).toMatchInlineSnapshot(`"\`
\`"`) }) + + test('nested elements with static text', () => { + expect( + getElementString(`
hello>bye
`) + ).toMatchInlineSnapshot( + `"\`
hello>bye
\`"` + ) + }) }) diff --git a/packages/compiler-ssr/src/ssrCodegenTransform.ts b/packages/compiler-ssr/src/ssrCodegenTransform.ts index c60ba2bfdf..30cf872f52 100644 --- a/packages/compiler-ssr/src/ssrCodegenTransform.ts +++ b/packages/compiler-ssr/src/ssrCodegenTransform.ts @@ -10,7 +10,7 @@ import { ElementTypes, createBlockStatement } from '@vue/compiler-dom' -import { isString } from '@vue/shared' +import { isString, escapeHtml } from '@vue/shared' // Because SSR codegen output is completely different from client-side output // (e.g. multiple elements can be concatenated into a single template literal @@ -85,7 +85,7 @@ function processChildren( // TODO } } else if (child.type === NodeTypes.TEXT) { - // TODO + context.pushStringPart(escapeHtml(child.content)) } else if (child.type === NodeTypes.IF) { // TODO } else if (child.type === NodeTypes.FOR) { diff --git a/packages/compiler-ssr/src/transforms/ssrTransformElement.ts b/packages/compiler-ssr/src/transforms/ssrTransformElement.ts index e522b350fd..89b514d957 100644 --- a/packages/compiler-ssr/src/transforms/ssrTransformElement.ts +++ b/packages/compiler-ssr/src/transforms/ssrTransformElement.ts @@ -5,7 +5,7 @@ import { TemplateLiteral, createTemplateLiteral } from '@vue/compiler-dom' -import { escapeHtml } from '@vue/server-renderer' +import { escapeHtml } from '@vue/shared' /* ## Simple Element diff --git a/packages/server-renderer/__tests__/ssrUtils.spec.ts b/packages/server-renderer/__tests__/interpolate.spec.ts similarity index 60% rename from packages/server-renderer/__tests__/ssrUtils.spec.ts rename to packages/server-renderer/__tests__/interpolate.spec.ts index 191f915c59..9de4bb4a0e 100644 --- a/packages/server-renderer/__tests__/ssrUtils.spec.ts +++ b/packages/server-renderer/__tests__/interpolate.spec.ts @@ -1,15 +1,5 @@ import { escapeHtml, interpolate } from '../src' -test('ssr: escapeHTML', () => { - expect(escapeHtml(`foo`)).toBe(`foo`) - expect(escapeHtml(true)).toBe(`true`) - expect(escapeHtml(false)).toBe(`false`) - expect(escapeHtml(`a && b`)).toBe(`a && b`) - expect(escapeHtml(`"foo"`)).toBe(`"foo"`) - expect(escapeHtml(`'bar'`)).toBe(`'bar'`) - expect(escapeHtml(`
`)).toBe(`<div>`) -}) - test('ssr: interpolate', () => { expect(interpolate(0)).toBe(`0`) expect(interpolate(`foo`)).toBe(`foo`) diff --git a/packages/server-renderer/src/index.ts b/packages/server-renderer/src/index.ts index 1eb03e43bf..0b4be1ce52 100644 --- a/packages/server-renderer/src/index.ts +++ b/packages/server-renderer/src/index.ts @@ -4,4 +4,13 @@ export { renderToString } from './renderToString' // internal export { renderComponent, renderSlot } from './renderToString' export { renderClass, renderStyle, renderProps } from './renderProps' -export { escapeHtml, interpolate } from './ssrUtils' + +// utils +import { escapeHtml as _escapeHtml, toDisplayString } from '@vue/shared' + +// cast type to avoid dts dependency on @vue/shared (which is inlined) +export const escapeHtml = _escapeHtml as (raw: string) => string + +export function interpolate(value: unknown): string { + return escapeHtml(toDisplayString(value)) +} diff --git a/packages/server-renderer/src/renderProps.ts b/packages/server-renderer/src/renderProps.ts index 53536f7013..4830aca352 100644 --- a/packages/server-renderer/src/renderProps.ts +++ b/packages/server-renderer/src/renderProps.ts @@ -1,4 +1,4 @@ -import { escapeHtml } from './ssrUtils' +import { escapeHtml } from '@vue/shared' import { normalizeClass, normalizeStyle, diff --git a/packages/server-renderer/src/renderToString.ts b/packages/server-renderer/src/renderToString.ts index f19ab09d99..b649e4db78 100644 --- a/packages/server-renderer/src/renderToString.ts +++ b/packages/server-renderer/src/renderToString.ts @@ -22,7 +22,7 @@ import { isVoidTag } from '@vue/shared' import { renderProps } from './renderProps' -import { escapeHtml } from './ssrUtils' +import { escapeHtml } from '@vue/shared' const { isVNode, diff --git a/packages/shared/__tests__/escapeHtml.spec.ts b/packages/shared/__tests__/escapeHtml.spec.ts new file mode 100644 index 0000000000..34505d3ead --- /dev/null +++ b/packages/shared/__tests__/escapeHtml.spec.ts @@ -0,0 +1,11 @@ +import { escapeHtml } from '../src' + +test('ssr: escapeHTML', () => { + expect(escapeHtml(`foo`)).toBe(`foo`) + expect(escapeHtml(true)).toBe(`true`) + expect(escapeHtml(false)).toBe(`false`) + expect(escapeHtml(`a && b`)).toBe(`a && b`) + expect(escapeHtml(`"foo"`)).toBe(`"foo"`) + expect(escapeHtml(`'bar'`)).toBe(`'bar'`) + expect(escapeHtml(`
`)).toBe(`<div>`) +}) diff --git a/packages/server-renderer/src/ssrUtils.ts b/packages/shared/src/escapeHtml.ts similarity index 86% rename from packages/server-renderer/src/ssrUtils.ts rename to packages/shared/src/escapeHtml.ts index 9c71e90204..7546471a9c 100644 --- a/packages/server-renderer/src/ssrUtils.ts +++ b/packages/shared/src/escapeHtml.ts @@ -1,5 +1,3 @@ -import { toDisplayString } from '@vue/shared' - const escapeRE = /["'&<>]/ export function escapeHtml(string: unknown) { @@ -45,7 +43,3 @@ export function escapeHtml(string: unknown) { return lastIndex !== index ? html + str.substring(lastIndex, index) : html } - -export function interpolate(value: unknown) { - return escapeHtml(toDisplayString(value)) -} diff --git a/packages/shared/src/index.ts b/packages/shared/src/index.ts index 59b5bb648e..3a1c07f2d6 100644 --- a/packages/shared/src/index.ts +++ b/packages/shared/src/index.ts @@ -8,6 +8,7 @@ export * from './mockWarn' export * from './normalizeProp' export * from './domTagConfig' export * from './domAttrConfig' +export * from './escapeHtml' export const EMPTY_OBJ: { readonly [key: string]: any } = __DEV__ ? Object.freeze({}) -- 2.47.3