Skip to content

Commit

Permalink
feat: babel option customization
Browse files Browse the repository at this point in the history
  • Loading branch information
JuniorTour committed Jan 9, 2022
1 parent b49006b commit 45a1a87
Show file tree
Hide file tree
Showing 11 changed files with 163 additions and 16 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ Enable `Optional Chaining(?.)`, `Nullish Coalescing(??)` and many new ES syntax
## Features
- All features of [vue-template-compiler](https://github.com/vuejs/vue/tree/dev/packages/vue-template-compiler#readme) && [vue-template-es2015-compiler](https://github.com/vuejs/vue-template-es2015-compiler)
- new ES syntax: `Optional Chaining`, `Bigint`, `Nullish Coalescing` and more
- Customization syntax, babel options...
- use babel to transpile vue render function, customization syntax, babel options customization

## Usage
### 1. Install
Expand Down Expand Up @@ -78,6 +78,7 @@ export default {
- [vue-jest Usage](https://github.com/JuniorTour/vue-template-babel-compiler/blob/main/doc/Usage.md#1-vue-jest)
- [Webpack Usage](https://github.com/JuniorTour/vue-template-babel-compiler/blob/main/doc/Usage.md#2-webpack)
- [VueUse && `<script setup>` Usage](https://github.com/JuniorTour/vue-template-babel-compiler/blob/main/doc/Usage.md#3-vueuse--script-setup)
- [babel options customization](https://github.com/JuniorTour/vue-template-babel-compiler/blob/main/doc/Usage.md#1-babel-options-customization)
- [Functional Component Usage](https://github.com/JuniorTour/vue-template-babel-compiler/blob/main/doc/Usage.md#1-functional-component-usage)

## [API](https://github.com/JuniorTour/vue-template-babel-compiler/blob/main/doc/API.md)
Expand Down
50 changes: 50 additions & 0 deletions doc/Usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
- [vue-jest Usage](#1-vue-jest)
- [Webpack Usage](#2-Webpack)
- [VueUse && `<script setup>`](#3-vueuse--script-setup)
- [Options](#Options)
- [babel options customization](#1-babel-options-customization)
- [Caveats](#Caveats)
- [Functional Component Usage](#1-Functional-Component-Usage)
- [Only Substitute `vue-template-es2015-compiler`](#2-only-substitute-vue-template-es2015-compiler)
Expand Down Expand Up @@ -64,6 +66,54 @@ module.exports = {

Example Project: https://github.com/JuniorTour/vue-template-babel-compiler-VueUse-Example

## Options

### 1. babel options customization

We can customize babel options for this compiler by `babelOptions` property:
```js
// vue.config.js
module.exports = {
chainWebpack: config => {
config.module
.rule('vue')
.use('vue-loader')
.tap(options => {
options.babelOptions = {
filename: 'newFilename',
newProp: true,
assumptions: {
additional: 'additional'
},
plugins: [
'newPlugin'
]
}
options.compiler = require('vue-template-babel-compiler')
return options
})
}
}

// nuxt.config.js
export default {
// Build Configuration: https://go.nuxtjs.dev/config-build
build: {
loaders: {
vue: {
babelOptions: {
/* ... */
},
compiler: require('vue-template-babel-compiler')
}
},
},
// ...
}
```

This `babelOptions` property will merge with [default options](https://github.com/JuniorTour/vue-template-babel-compiler/blob/b49006bbf3913230bc604203452404b011a443f0/src/renderCompiler.js#L15-L35)


## Caveats

Expand Down
31 changes: 21 additions & 10 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,12 @@ function escapeRegExp(string) {
return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
}

const merge = require('deepmerge');

function mergeOptions(oldOptions, newOptions) {
return merge(oldOptions, newOptions);
}

const babel = require('@babel/core');

const matchWithRegex = new RegExp(escapeRegExp(`/*${WithStatementReplaceComment}*/`), 'g');
Expand All @@ -95,7 +101,7 @@ function renderCompiler(code, options) {

// TODO add customize individual options
const isFunctional = options === null || options === void 0 ? void 0 : (_options$transforms = options.transforms) === null || _options$transforms === void 0 ? void 0 : _options$transforms.stripWithFunctional;
const output = babel.transformSync(code, {
const output = babel.transformSync(code, mergeOptions({
filename: 'VueTemplateBabelCompiler',
// not enable strict mode, in order to parse WithStatement
sourceType: 'script',
Expand All @@ -107,7 +113,7 @@ function renderCompiler(code, options) {
loose: true,
useBuiltIns: true
}], '@babel/plugin-transform-arrow-functions', '@babel/plugin-transform-parameters', parseWithStatementToVm]
});
}, (options === null || options === void 0 ? void 0 : options.babelOptions) || {}));
return output.code.replace(matchWithRegex, isFunctional ? functionalWithReplacement : withReplacement);
}

Expand Down Expand Up @@ -141,9 +147,9 @@ function getArrayItems(code) {

const renderSeparator = '/* renderSeparator */';
function compileTemplate(source, options) {
var _options$filename;
var _options, _options$filename, _options2;

const isFunctional = options === null || options === void 0 ? void 0 : (_options$filename = options.filename) === null || _options$filename === void 0 ? void 0 : _options$filename.includes((options === null || options === void 0 ? void 0 : options.functionalComponentFileIdentifier) || '.functional');
const isFunctional = (_options = options) === null || _options === void 0 ? void 0 : (_options$filename = _options.filename) === null || _options$filename === void 0 ? void 0 : _options$filename.includes(((_options2 = options) === null || _options2 === void 0 ? void 0 : _options2.functionalComponentFileIdentifier) || '.functional');
const {
ast,
render,
Expand All @@ -159,11 +165,14 @@ function compileTemplate(source, options) {
code += `var staticRenderFns = [${staticRenderFns.map(render => toFunction(render, isFunctional))}]`;
}

const [compiledRender, compiledStaticRenders] = renderCompiler(code, {
transforms: {
stripWithFunctional: isFunctional
}
}).split(renderSeparator);
if (!options) {
options = {};
}

options.transforms = {
stripWithFunctional: isFunctional
};
const [compiledRender, compiledStaticRenders] = renderCompiler(code, options).split(renderSeparator);
return {
ast,
render: getFunctionBody(compiledRender),
Expand All @@ -183,5 +192,7 @@ function extendTemplateCompiler(obj) {

const transpile = renderCompiler; // enhance vue-template-compiler with babel:

extendTemplateCompiler(transpile);
extendTemplateCompiler(transpile); // babel prepend vm plugin:

transpile.parseWithStatementToVmPlugin = parseWithStatementToVm;
module.exports = transpile;
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@
"@babel/plugin-transform-destructuring": "^7.14.5",
"@babel/plugin-transform-parameters": "^7.14.5",
"@babel/plugin-transform-spread": "^7.14.5",
"@babel/types": "^7.14.5"
"@babel/types": "^7.14.5",
"deepmerge": "^4.2.2"
},
"keywords": [
"vuejs",
Expand Down
4 changes: 4 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
import {renderCompiler} from "./renderCompiler"
import {extendTemplateCompiler} from "./templateCompiler"
import parseWithStatementToVm from "./plugins/parse-with-statement";

// vue-es2015-compiler substitution:
const transpile = renderCompiler

// enhance vue-template-compiler with babel:
extendTemplateCompiler(transpile)

// babel prepend vm plugin:
transpile.parseWithStatementToVmPlugin = parseWithStatementToVm

module.exports = transpile
7 changes: 5 additions & 2 deletions src/renderCompiler.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import parseWithStatementToVm from './plugins/parse-with-statement'
import {WithStatementReplaceComment} from "./plugins/constants/preservedNames"
import {escapeRegExp} from "./utils/string"
import {mergeOptions} from "./utils/merge";

const babel = require('@babel/core')

Expand All @@ -12,7 +13,7 @@ export function renderCompiler(code, options) {
// TODO add customize individual options
const isFunctional = options?.transforms?.stripWithFunctional

const output = babel.transformSync(code, {
const output = babel.transformSync(code, mergeOptions({
filename: 'VueTemplateBabelCompiler',
// not enable strict mode, in order to parse WithStatement
sourceType: 'script',
Expand All @@ -32,7 +33,9 @@ export function renderCompiler(code, options) {
'@babel/plugin-transform-parameters',
parseWithStatementToVm,
],
})
},
options?.babelOptions || {})
)

return output.code.replace(matchWithRegex, isFunctional ? functionalWithReplacement : withReplacement)
}
9 changes: 8 additions & 1 deletion src/templateCompiler.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,14 @@ export function compileTemplate(source, options) {
code += `var staticRenderFns = [${staticRenderFns.map((render) => toFunction(render, isFunctional))}]`
}

const [compiledRender, compiledStaticRenders] = renderCompiler(code, {transforms: {stripWithFunctional: isFunctional}}).split(renderSeparator)
if (!options) {
options = {}
}
options.transforms = {
stripWithFunctional: isFunctional
}
const [compiledRender, compiledStaticRenders] = renderCompiler(code, options)
.split(renderSeparator)

return {
ast,
Expand Down
5 changes: 5 additions & 0 deletions src/utils/merge.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
const merge = require('deepmerge')

export function mergeOptions(oldOptions, newOptions) {
return merge(oldOptions, newOptions)
}
15 changes: 15 additions & 0 deletions test/compileTemplate.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -116,3 +116,18 @@ test('should prepend vm to computed property', () => {
expect(errors.length === 0).toBeTruthy()
expect(vm.$el.innerHTML).toMatch('<div class="firstClass"')
})

test('babelOptions should work for assumptions', () => {
const {ast, render, staticRenderFns, tips, errors} = templateCompiler.compile(
'<div :class="{[`${foo}_single`]: true}"></div>',
{
babelOptions: {
assumptions: {
setComputedProperties: false,
},
}
}
)

expect(render).toMatch('class: _defineProperty({}, `${_vm.foo}_single`, true)')
})
50 changes: 50 additions & 0 deletions test/options.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import {mergeOptions} from "../src/utils/merge";

const parseWithStatementToVm = () => {}

// #30
test('should merge options for babel', () => {
const oldOptions = {
filename: 'VueTemplateBabelCompiler',
// not enable strict mode, in order to parse WithStatement
sourceType: 'script',
assumptions: {
setComputedProperties: true,
arrayLikeIsIterable: true,
},
plugins: [
'@babel/plugin-transform-computed-properties',
'@babel/plugin-proposal-nullish-coalescing-operator',
'@babel/plugin-proposal-optional-chaining',
'@babel/plugin-transform-block-scoping',
'@babel/plugin-transform-destructuring',
"@babel/plugin-transform-spread",
["@babel/plugin-proposal-object-rest-spread", { loose: true, useBuiltIns: true }],
'@babel/plugin-transform-arrow-functions',
'@babel/plugin-transform-parameters',
parseWithStatementToVm,
],
}

const additionalOptions = {
filename: 'newFilename',
newProp: true,
assumptions: {
additional: 'additional'
},
plugins: [
'newPlugin'
]
}

const newOptions = mergeOptions(
oldOptions,
additionalOptions,
)

expect(newOptions.assumptions.additional).toMatch(additionalOptions.assumptions.additional)
expect(newOptions.plugins.length).toEqual(oldOptions.plugins.length+1)
expect(newOptions.plugins[9]).toEqual(oldOptions.plugins[9])
expect(newOptions.filename).toEqual(additionalOptions.filename)
expect(newOptions.newProp).toEqual(additionalOptions.newProp)
})
2 changes: 1 addition & 1 deletion yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1494,7 +1494,7 @@ deep-is@~0.1.3:

deepmerge@^4.2.2:
version "4.2.2"
resolved "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz"
resolved "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz#44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955"
integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==

default-require-extensions@^2.0.0:
Expand Down

0 comments on commit 45a1a87

Please sign in to comment.