diff --git a/build/config.js b/build/config.js index 5ef6b385..20fefa85 100644 --- a/build/config.js +++ b/build/config.js @@ -1,7 +1,9 @@ const path = require('path') const buble = require('rollup-plugin-buble') const alias = require('rollup-plugin-alias') +const cjs = require('rollup-plugin-commonjs') const replace = require('rollup-plugin-replace') +const node = require('rollup-plugin-node-resolve') const flow = require('rollup-plugin-flow-no-whitespace') const version = process.env.VERSION || require('../package.json').version const weexVersion = process.env.WEEX_VERSION || require('../packages/weex-vue-framework/package.json').version @@ -112,6 +114,14 @@ const builds = { format: 'cjs', external: Object.keys(require('../packages/vue-server-renderer/package.json').dependencies) }, + 'web-server-basic-renderer': { + entry: resolve('web/entry-server-basic-renderer.js'), + dest: resolve('packages/vue-server-renderer/basic.js'), + format: 'umd', + env: 'development', + moduleName: 'renderVueComponentToString', + plugins: [node(), cjs()] + }, 'web-server-renderer-webpack-server-plugin': { entry: resolve('server/webpack-plugin/server.js'), dest: resolve('packages/vue-server-renderer/server-plugin.js'), @@ -156,7 +166,7 @@ function genConfig (opts) { external: opts.external, format: opts.format, banner: opts.banner, - moduleName: 'Vue', + moduleName: opts.moduleName || 'Vue', plugins: [ replace({ __WEEX__: !!opts.weex, diff --git a/package.json b/package.json index c307fbcd..285ad658 100644 --- a/package.json +++ b/package.json @@ -105,7 +105,9 @@ "rollup-plugin-alias": "^1.2.0", "rollup-plugin-babel": "^2.4.0", "rollup-plugin-buble": "^0.15.0", + "rollup-plugin-commonjs": "^8.0.2", "rollup-plugin-flow-no-whitespace": "^1.0.0", + "rollup-plugin-node-resolve": "^3.0.0", "rollup-plugin-replace": "^1.1.0", "rollup-watch": "^3.2.2", "selenium-server": "^2.53.1", diff --git a/src/compiler/parser/entity-decoder.js b/src/compiler/parser/entity-decoder.js index 8e360b00..2836294f 100644 --- a/src/compiler/parser/entity-decoder.js +++ b/src/compiler/parser/entity-decoder.js @@ -2,8 +2,10 @@ let decoder -export function decode (html: string): string { - decoder = decoder || document.createElement('div') - decoder.innerHTML = html - return decoder.textContent +export default { + decode (html: string): string { + decoder = decoder || document.createElement('div') + decoder.innerHTML = html + return decoder.textContent + } } diff --git a/src/compiler/parser/index.js b/src/compiler/parser/index.js index 2da48b75..f1ec1e18 100644 --- a/src/compiler/parser/index.js +++ b/src/compiler/parser/index.js @@ -1,6 +1,6 @@ /* @flow */ -import { decode } from 'he' +import he from 'he' import { parseHTML } from './html-parser' import { parseText } from './text-parser' import { parseFilters } from './filter-parser' @@ -28,7 +28,7 @@ const argRE = /:(.*)$/ const bindRE = /^:|^v-bind:/ const modifierRE = /\.[^.]+/g -const decodeHTMLCached = cached(decode) +const decodeHTMLCached = cached(he.decode) // configurable state export let warn diff --git a/src/platforms/web/entry-server-basic-renderer.js b/src/platforms/web/entry-server-basic-renderer.js new file mode 100644 index 00000000..c4b973bd --- /dev/null +++ b/src/platforms/web/entry-server-basic-renderer.js @@ -0,0 +1,13 @@ +/* @flow */ + +import modules from './server/modules/index' +import directives from './server/directives/index' +import { isUnaryTag, canBeLeftOpenTag } from './compiler/util' +import { createBasicRenderer } from 'server/create-basic-renderer' + +export default createBasicRenderer({ + modules, + directives, + isUnaryTag, + canBeLeftOpenTag +}) diff --git a/src/server/create-basic-renderer.js b/src/server/create-basic-renderer.js new file mode 100644 index 00000000..2d53976d --- /dev/null +++ b/src/server/create-basic-renderer.js @@ -0,0 +1,37 @@ +/* @flow */ + +import { createWriteFunction } from './write' +import { createRenderFunction } from './render' +import type { RenderOptions } from './create-renderer' + +export function createBasicRenderer ({ + modules = [], + directives = {}, + isUnaryTag = (() => false), + cache +}: RenderOptions = {}) { + const render = createRenderFunction(modules, directives, isUnaryTag, cache) + + return function renderToString ( + component: Component, + context: any, + done: any + ): void { + if (typeof context === 'function') { + done = context + context = {} + } + let result = '' + const write = createWriteFunction(text => { + result += text + return false + }, done) + try { + render(component, write, context, () => { + done(null, result) + }) + } catch (e) { + done(e) + } + } +} diff --git a/test/ssr/ssr-basic-renderer.spec.js b/test/ssr/ssr-basic-renderer.spec.js new file mode 100644 index 00000000..053bde1a --- /dev/null +++ b/test/ssr/ssr-basic-renderer.spec.js @@ -0,0 +1,53 @@ +import Vue from '../../dist/vue.runtime.common.js' +import renderToString from '../../packages/vue-server-renderer/basic' + +describe('SSR: basicRenderer', () => { + it('should work', done => { + renderToString(new Vue({ + template: ` +
+

yoyo

+
+ {{ test }} + + + + +
+ `, + data: { + test: 'hi', + isRed: true, + imageUrl: 'https://vuejs.org/images/logo.png' + }, + components: { + test: { + render () { + return this.$createElement('div', { class: ['a'] }, 'test') + } + }, + testAsync (resolve) { + resolve({ + render () { + return this.$createElement('span', { class: ['b'] }, 'testAsync') + } + }) + } + } + }), (err, result) => { + expect(err).toBeNull() + expect(result).toContain( + '
' + + '

yoyo

' + + '
' + + 'hi ' + + ' ' + + ' ' + + '
test
' + + 'testAsync' + + '
' + ) + done() + }) + }) +}) diff --git a/yarn.lock b/yarn.lock index b68a64c0..539ff35d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -35,7 +35,7 @@ acorn@^3.0.4, acorn@^3.1.0, acorn@^3.3.0: version "3.3.0" resolved "https://registry.yarnpkg.com/acorn/-/acorn-3.3.0.tgz#45e37fb39e8da3f25baee3ff5369e2bb5f22017a" -acorn@^4.0.3: +acorn@^4.0.1, acorn@^4.0.3: version "4.0.13" resolved "https://registry.yarnpkg.com/acorn/-/acorn-4.0.13.tgz#105495ae5361d697bd195c825192e1ad7f253787" @@ -890,6 +890,12 @@ brorand@^1.0.1: version "1.1.0" resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" +browser-resolve@^1.11.0: + version "1.11.2" + resolved "https://registry.yarnpkg.com/browser-resolve/-/browser-resolve-1.11.2.tgz#8ff09b0a2c421718a1051c260b32e48f442938ce" + dependencies: + resolve "1.1.7" + browser-stdout@1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.0.tgz#f351d32969d32fa5d7a5567154263d928ae3bd1f" @@ -977,7 +983,7 @@ buffer@^4.3.0: ieee754 "^1.1.4" isarray "^1.0.0" -builtin-modules@^1.0.0: +builtin-modules@^1.0.0, builtin-modules@^1.1.0: version "1.1.1" resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" @@ -1920,6 +1926,10 @@ estree-walker@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-0.2.1.tgz#bdafe8095383d8414d5dc2ecf4c9173b6db9412e" +estree-walker@^0.3.0: + version "0.3.1" + resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-0.3.1.tgz#e6b1a51cf7292524e7237c312e5fe6660c1ce1aa" + esutils@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" @@ -2654,6 +2664,10 @@ is-glob@^2.0.0, is-glob@^2.0.1: dependencies: is-extglob "^1.0.0" +is-module@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-module/-/is-module-1.0.0.tgz#3258fb69f78c14d5b815d664336b4cffb6441591" + is-my-json-valid@^2.10.0, is-my-json-valid@^2.12.4: version "2.16.0" resolved "https://registry.yarnpkg.com/is-my-json-valid/-/is-my-json-valid-2.16.0.tgz#f079dd9bfdae65ee2038aae8acbc86ab109e3693" @@ -3266,6 +3280,12 @@ magic-string@^0.16.0: dependencies: vlq "^0.2.1" +magic-string@^0.19.0: + version "0.19.1" + resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.19.1.tgz#14d768013caf2ec8fdea16a49af82fc377e75201" + dependencies: + vlq "^0.2.1" + map-obj@^1.0.0, map-obj@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d" @@ -4245,11 +4265,11 @@ resolve-from@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-1.0.1.tgz#26cbfe935d1aeeeabb29bc3fe5aeb01e93d44226" -resolve@1.1.x: +resolve@1.1.7, resolve@1.1.x: version "1.1.7" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" -resolve@^1.1.6, resolve@^1.2.0: +resolve@^1.1.6, resolve@^1.1.7, resolve@^1.2.0: version "1.3.3" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.3.3.tgz#655907c3469a8680dc2de3a275a8fdd69691f0e5" dependencies: @@ -4315,6 +4335,16 @@ rollup-plugin-buble@^0.15.0: buble "^0.15.0" rollup-pluginutils "^1.5.0" +rollup-plugin-commonjs@^8.0.2: + version "8.0.2" + resolved "https://registry.yarnpkg.com/rollup-plugin-commonjs/-/rollup-plugin-commonjs-8.0.2.tgz#98b1589bfe32a6c0f67790b60c0b499972afed89" + dependencies: + acorn "^4.0.1" + estree-walker "^0.3.0" + magic-string "^0.19.0" + resolve "^1.1.7" + rollup-pluginutils "^2.0.1" + rollup-plugin-flow-no-whitespace@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/rollup-plugin-flow-no-whitespace/-/rollup-plugin-flow-no-whitespace-1.0.0.tgz#bd4ba1bcd99ad5b88234d72e6e2dacea9aa02d16" @@ -4322,6 +4352,15 @@ rollup-plugin-flow-no-whitespace@^1.0.0: flow-remove-types-no-whitespace "^1.0.3" rollup-pluginutils "^1.5.2" +rollup-plugin-node-resolve@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/rollup-plugin-node-resolve/-/rollup-plugin-node-resolve-3.0.0.tgz#8b897c4c3030d5001277b0514b25d2ca09683ee0" + dependencies: + browser-resolve "^1.11.0" + builtin-modules "^1.1.0" + is-module "^1.0.0" + resolve "^1.1.6" + rollup-plugin-replace@^1.1.0: version "1.1.1" resolved "https://registry.yarnpkg.com/rollup-plugin-replace/-/rollup-plugin-replace-1.1.1.tgz#396315ded050a6ce43b9518a886a3f60efb1ea33" @@ -4337,6 +4376,13 @@ rollup-pluginutils@^1.5.0, rollup-pluginutils@^1.5.2: estree-walker "^0.2.1" minimatch "^3.0.2" +rollup-pluginutils@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/rollup-pluginutils/-/rollup-pluginutils-2.0.1.tgz#7ec95b3573f6543a46a6461bd9a7c544525d0fc0" + dependencies: + estree-walker "^0.3.0" + micromatch "^2.3.11" + rollup-watch@^3.2.2: version "3.2.2" resolved "https://registry.yarnpkg.com/rollup-watch/-/rollup-watch-3.2.2.tgz#5e574232e9ef36da9177f46946d8080cb267354b"