├── .gitignore ├── .gitmodules ├── README.md ├── index.js ├── package.json ├── test.js └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | buble.js 3 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "buble"] 2 | path = buble 3 | url = git@github.com:yyx990803/buble.git 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | This is an internal package used by `vue-loader` and `vueify`. It processes the raw render functions generated by `vue-template-compiler` to: 2 | 3 | 1. add support to ES2015 features in template expressions via Buble. (see [supported features here](https://buble.surge.sh/guide/#supported-features)). 4 | 5 | **Note:** since version 1.8.0, object rest spread usage inside templates are transpiled to `Object.assign` calls by default. This means if you need to support IE, you will need to polyfill `Object.assign`. (Latest version of Vue CLI will do this for you). 6 | 7 | 2. remove the `with` block inside render functions to make it strict-mode compliant. This is performed only at build time so that the base template compiler can be extremely small and lightweight. 8 | 9 | The buble implementation is built from a fork at https://github.com/yyx990803/buble 10 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | var buble = require('./buble.js') 2 | 3 | // selectively support some handy ES2015 features in templates. 4 | var defaultOptions = { 5 | transforms: { 6 | modules: false, 7 | // this is a custom feature for stripping with from Vue render functions. 8 | stripWith: true, 9 | // custom feature ensures with context targets functional render 10 | stripWithFunctional: false 11 | }, 12 | // allow spread... 13 | objectAssign: 'Object.assign' 14 | } 15 | 16 | module.exports = function transpile (code, opts) { 17 | if (opts) { 18 | opts = Object.assign({}, defaultOptions, opts) 19 | opts.transforms = Object.assign({}, defaultOptions.transforms, opts.transforms) 20 | } else { 21 | opts = defaultOptions 22 | } 23 | var code = buble.transform(code, opts).code 24 | // console.log(code) 25 | return code 26 | } 27 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue-template-es2015-compiler", 3 | "version": "1.9.1", 4 | "description": "Post compiler for Vue template render functions to support ES2015+ features", 5 | "main": "index.js", 6 | "author": "Evan You", 7 | "license": "MIT", 8 | "files": [ 9 | "index.js", 10 | "buble.js" 11 | ], 12 | "scripts": { 13 | "build": "cd buble && npm run build && cp dist/buble-browser-deps.umd.js ../buble.js", 14 | "test": "jest", 15 | "prepublishOnly": "jest && npm run build" 16 | }, 17 | "devDependencies": { 18 | "jest": "^24.1.0", 19 | "vue": "^2.6.0", 20 | "vue-template-compiler": "^2.6.0" 21 | }, 22 | "repository": { 23 | "type": "git", 24 | "url": "https://github.com/vuejs/vue-template-es2015-compiler" 25 | }, 26 | "jest": { 27 | "testPathIgnorePatterns": [ 28 | "/node_modules/", 29 | "/buble/" 30 | ] 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /test.js: -------------------------------------------------------------------------------- 1 | const transpile = require('./index') 2 | const Vue = require('vue') 3 | const { compile } = require('vue-template-compiler') 4 | 5 | const toFunction = code => { 6 | code = transpile(`function render(){${code}}`) 7 | code = code.replace(/function render\(\)\{|\}$/g, '') 8 | return new Function(code) 9 | } 10 | 11 | const compileAsFunctions = template => { 12 | const { render, staticRenderFns } = compile(template) 13 | return { 14 | render: toFunction(render), 15 | staticRenderFns: staticRenderFns.map(toFunction) 16 | } 17 | } 18 | 19 | test('should work', () => { 20 | const vm = new Vue({ 21 | ...compileAsFunctions(` 22 |
23 |
{{ foo }}
24 |
{{ name }}
25 |
26 |
27 | `), 28 | data: { 29 | foo: 'hello', 30 | items: [ 31 | { name: 'foo' }, 32 | { name: 'bar' } 33 | ], 34 | a: { id: 'foo' }, 35 | b: { class: 'bar' } 36 | } 37 | }).$mount() 38 | 39 | expect(vm.$el.innerHTML).toMatch( 40 | `
hello
` + 41 | `
foo
bar
` + 42 | `
` 43 | ) 44 | }) 45 | 46 | test('arg spread', () => { 47 | const res = compile(` 48 | 49 | `) 50 | const code = transpile(`function render() {${res.render}}`) 51 | expect(code).toMatch(`_vm.store.foo.apply(_vm.store, args)`) 52 | }) 53 | 54 | test('rest spread in scope position', () => { 55 | const vm = new Vue({ 56 | ...compileAsFunctions(` 57 | {{ rest }} 58 | `), 59 | components: { 60 | foo: { 61 | render(h) { 62 | return h('div', this.$scopedSlots.default({ 63 | foo: 1, 64 | bar: 2, 65 | baz: 3 66 | })) 67 | } 68 | } 69 | } 70 | }).$mount() 71 | 72 | expect(vm.$el.innerHTML).toMatch( 73 | JSON.stringify({ bar: 2, baz: 3 }, null, 2) 74 | ) 75 | }) 76 | 77 | test('trailing function comma', () => { 78 | const spy = jest.fn() 79 | const vm = new Vue({ 80 | ...compileAsFunctions(` 81 |