From 7a1a39a4cbce8e223d86eacf3bea992077cca074 Mon Sep 17 00:00:00 2001 From: Amour1688 Date: Tue, 26 May 2020 21:04:56 +0800 Subject: [PATCH] refactor: support transformOn --- .babelrc | 8 --- lerna.json | 6 ++ package.json | 36 +--------- .../babel-helper-vue-transform-on/README.md | 11 +++ .../babel-helper-vue-transform-on/index.js | 9 +++ .../package.json | 9 +++ packages/babel-plugin-jsx/.babelrc | 13 ++++ .../babel-plugin-jsx/.jest.js | 0 packages/babel-plugin-jsx/README.md | 11 +++ .../babel-plugin-jsx/example}/index.js | 39 +++++++---- .../babel-plugin-jsx/index.html | 0 packages/babel-plugin-jsx/package.json | 42 ++++++++++++ .../babel-plugin-jsx/src}/index.js | 4 +- .../babel-plugin-jsx/src}/sugar-fragment.js | 0 .../babel-plugin-jsx/src}/sugar-v-model.js | 0 .../src}/transform-vue-jsx.js | 68 ++++++++----------- .../babel-plugin-jsx/test}/index.test.js | 0 .../babel-plugin-jsx/test}/setup.js | 0 .../babel-plugin-jsx/webpack.config.js | 0 19 files changed, 161 insertions(+), 95 deletions(-) delete mode 100644 .babelrc create mode 100644 lerna.json create mode 100644 packages/babel-helper-vue-transform-on/README.md create mode 100644 packages/babel-helper-vue-transform-on/index.js create mode 100644 packages/babel-helper-vue-transform-on/package.json create mode 100644 packages/babel-plugin-jsx/.babelrc rename .jest.js => packages/babel-plugin-jsx/.jest.js (100%) create mode 100644 packages/babel-plugin-jsx/README.md rename {example => packages/babel-plugin-jsx/example}/index.js (52%) rename index.html => packages/babel-plugin-jsx/index.html (100%) create mode 100644 packages/babel-plugin-jsx/package.json rename {src => packages/babel-plugin-jsx/src}/index.js (80%) rename {src => packages/babel-plugin-jsx/src}/sugar-fragment.js (100%) rename {src => packages/babel-plugin-jsx/src}/sugar-v-model.js (100%) rename {src => packages/babel-plugin-jsx/src}/transform-vue-jsx.js (83%) rename {test => packages/babel-plugin-jsx/test}/index.test.js (100%) rename {test => packages/babel-plugin-jsx/test}/setup.js (100%) rename webpack.config.js => packages/babel-plugin-jsx/webpack.config.js (100%) diff --git a/.babelrc b/.babelrc deleted file mode 100644 index 87db373..0000000 --- a/.babelrc +++ /dev/null @@ -1,8 +0,0 @@ -{ - "presets": [ - "@babel/env" - ], - "plugins": [ - "./src/index.js" - ] -} diff --git a/lerna.json b/lerna.json new file mode 100644 index 0000000..d6707ca --- /dev/null +++ b/lerna.json @@ -0,0 +1,6 @@ +{ + "packages": [ + "packages/*" + ], + "version": "0.0.0" +} diff --git a/package.json b/package.json index 5555d37..8f75fc0 100644 --- a/package.json +++ b/package.json @@ -1,49 +1,17 @@ { - "name": "@ant-design-vue/babel-plugin-jsx", - "version": "1.0.0-alpha.2", - "description": "Babel plugin for Vue 3.0 JSX", - "main": "src/index.js", "scripts": { - "dev": "webpack-dev-server", - "lint": "eslint --ext .js src", - "test": "jest --config .jest.js" + "publish": "lerna publish" }, - "repository": { - "type": "git", - "url": "git+https://github.com/vueComponent/jsx.git" - }, - "author": "", "license": "MIT", - "bugs": { - "url": "https://github.com/vueComponent/jsx/issues" - }, - "homepage": "https://github.com/vueComponent/jsx#readme", "keywords": [ "vue", "jsx" ], - "dependencies": { - "@babel/helper-module-imports": "^7.0.0", - "@babel/plugin-syntax-jsx": "^7.0.0", - "camelcase": "^6.0.0", - "html-tags": "^3.1.0", - "svg-tags": "^1.0.0" - }, "devDependencies": { - "@babel/core": "^7.9.6", - "@babel/preset-env": "^7.9.6", - "@vue/test-utils": "^2.0.0-alpha.6", "babel-eslint": "^10.1.0", - "babel-jest": "^26.0.1", - "babel-loader": "^8.1.0", "eslint": "^7.0.0", "eslint-config-airbnb": "^18.1.0", "eslint-plugin-import": "^2.20.2", - "jest": "^26.0.1", - "regenerator-runtime": "^0.13.5", - "vue": "^3.0.0-beta.14", - "webpack": "^4.43.0", - "webpack-cli": "^3.3.11", - "webpack-dev-server": "^3.10.3" + "lerna": "^3.19.0" } } diff --git a/packages/babel-helper-vue-transform-on/README.md b/packages/babel-helper-vue-transform-on/README.md new file mode 100644 index 0000000..f80b56b --- /dev/null +++ b/packages/babel-helper-vue-transform-on/README.md @@ -0,0 +1,11 @@ +# @ant-design-vue/babel-helper-vue-transform-on + +A package used internally by vue jsx transformer to merge props spread. It is required to merge some prop trees like this: + +## Usage + +``` +const babelHelperVueTransformOn = require('babel-helper-vue-transform-on'); + +// TODO: DEMONSTRATE API +``` diff --git a/packages/babel-helper-vue-transform-on/index.js b/packages/babel-helper-vue-transform-on/index.js new file mode 100644 index 0000000..88e3b49 --- /dev/null +++ b/packages/babel-helper-vue-transform-on/index.js @@ -0,0 +1,9 @@ +const transformOn = (obj) => { + const result = {}; + Object.keys(obj).forEach((evt) => { + result[`on${evt[0].toUpperCase()}${evt.substr(1)}`] = obj[evt]; + }); + return result; +}; + +module.exports = transformOn; diff --git a/packages/babel-helper-vue-transform-on/package.json b/packages/babel-helper-vue-transform-on/package.json new file mode 100644 index 0000000..b9ab752 --- /dev/null +++ b/packages/babel-helper-vue-transform-on/package.json @@ -0,0 +1,9 @@ +{ + "name": "@ant-design-vue/babel-helper-vue-transform-on", + "version": "1.0.0", + "description": "> TODO: description", + "author": "Amour1688 ", + "license": "MIT", + "main": "index.js", + "private": true +} diff --git a/packages/babel-plugin-jsx/.babelrc b/packages/babel-plugin-jsx/.babelrc new file mode 100644 index 0000000..3bd692d --- /dev/null +++ b/packages/babel-plugin-jsx/.babelrc @@ -0,0 +1,13 @@ +{ + "presets": [ + [ + "@babel/env", + { + // "modules": "cjs" + } + ] + ], + "plugins": [ + ["./src/index.js", { "transformOn": true }] + ] +} diff --git a/.jest.js b/packages/babel-plugin-jsx/.jest.js similarity index 100% rename from .jest.js rename to packages/babel-plugin-jsx/.jest.js diff --git a/packages/babel-plugin-jsx/README.md b/packages/babel-plugin-jsx/README.md new file mode 100644 index 0000000..1cf44f1 --- /dev/null +++ b/packages/babel-plugin-jsx/README.md @@ -0,0 +1,11 @@ +# `babel-plugin-jsx` + +> TODO: description + +## Usage + +``` +const babelPluginJsx = require('babel-plugin-jsx'); + +// TODO: DEMONSTRATE API +``` diff --git a/example/index.js b/packages/babel-plugin-jsx/example/index.js similarity index 52% rename from example/index.js rename to packages/babel-plugin-jsx/example/index.js index dc27ac6..c7030c8 100644 --- a/example/index.js +++ b/packages/babel-plugin-jsx/example/index.js @@ -1,19 +1,26 @@ import { createApp, ref, defineComponent } from 'vue'; -const SuperButton = (props, context) => ( +const SuperButton = (props, context) => { + const obj = { + mouseover: () => { + context.emit('mouseover'); + }, + click: () => { + context.emit('click'); + }, + }; + return (
Super
-); + ); +}; SuperButton.inheritAttrs = false; @@ -23,17 +30,23 @@ const App = defineComponent(() => { count.value++; }; + const obj = { + click: inc, + mouseover: inc, + }; + return () => ( - <> +
Foo {count.value} - + vShow={true} + on={obj} + > + + +
); }); diff --git a/index.html b/packages/babel-plugin-jsx/index.html similarity index 100% rename from index.html rename to packages/babel-plugin-jsx/index.html diff --git a/packages/babel-plugin-jsx/package.json b/packages/babel-plugin-jsx/package.json new file mode 100644 index 0000000..d10913a --- /dev/null +++ b/packages/babel-plugin-jsx/package.json @@ -0,0 +1,42 @@ +{ + "name": "@ant-design-vue/babel-plugin-jsx", + "version": "1.0.0", + "description": "Babel plugin for Vue 3.0 JSX", + "author": "Amour1688 ", + "homepage": "https://github.com/vueComponent/jsx/tree/master/packages/babel-plugin-jsx#readme", + "license": "MIT", + "main": "src/index.js", + "repository": { + "type": "git", + "url": "git+https://github.com/vueComponent/jsx.git" + }, + "scripts": { + "dev": "webpack-dev-server", + "lint": "eslint --ext .js src", + "test": "jest --config .jest.js" + }, + "bugs": { + "url": "https://github.com/vueComponent/jsx/issues" + }, + "dependencies": { + "@ant-design-vue/babel-helper-vue-transform-on": "^1.0.0", + "@babel/helper-module-imports": "^7.0.0", + "@babel/plugin-syntax-jsx": "^7.0.0", + "camelcase": "^6.0.0", + "html-tags": "^3.1.0", + "svg-tags": "^1.0.0" + }, + "devDependencies": { + "@babel/core": "^7.9.6", + "@babel/preset-env": "^7.9.6", + "@vue/test-utils": "^2.0.0-alpha.6", + "babel-jest": "^26.0.1", + "babel-loader": "^8.1.0", + "jest": "^26.0.1", + "regenerator-runtime": "^0.13.5", + "vue": "^3.0.0-beta.14", + "webpack": "^4.43.0", + "webpack-cli": "^3.3.11", + "webpack-dev-server": "^3.10.3" + } +} diff --git a/src/index.js b/packages/babel-plugin-jsx/src/index.js similarity index 80% rename from src/index.js rename to packages/babel-plugin-jsx/src/index.js index 3084b5e..497014f 100644 --- a/src/index.js +++ b/packages/babel-plugin-jsx/src/index.js @@ -3,12 +3,12 @@ const tranformVueJSX = require('./transform-vue-jsx'); const sugarVModel = require('./sugar-v-model'); const sugarFragment = require('./sugar-fragment'); -module.exports = ({ types: t }) => ({ +module.exports = ({ types: t }, opts = {}) => ({ name: 'babel-plugin-jsx', inherits: syntaxJsx, visitor: { ...sugarVModel(t), - ...tranformVueJSX(t), + ...tranformVueJSX(t, opts), ...sugarFragment(t), }, }); diff --git a/src/sugar-fragment.js b/packages/babel-plugin-jsx/src/sugar-fragment.js similarity index 100% rename from src/sugar-fragment.js rename to packages/babel-plugin-jsx/src/sugar-fragment.js diff --git a/src/sugar-v-model.js b/packages/babel-plugin-jsx/src/sugar-v-model.js similarity index 100% rename from src/sugar-v-model.js rename to packages/babel-plugin-jsx/src/sugar-v-model.js diff --git a/src/transform-vue-jsx.js b/packages/babel-plugin-jsx/src/transform-vue-jsx.js similarity index 83% rename from src/transform-vue-jsx.js rename to packages/babel-plugin-jsx/src/transform-vue-jsx.js index 09cb44b..dc65deb 100644 --- a/src/transform-vue-jsx.js +++ b/packages/babel-plugin-jsx/src/transform-vue-jsx.js @@ -1,16 +1,11 @@ const htmlTags = require('html-tags'); const svgTags = require('svg-tags'); -const { addNamed } = require('@babel/helper-module-imports'); +const { addNamed, addDefault } = require('@babel/helper-module-imports'); const xlinkRE = /^xlink([A-Z])/; const eventRE = /^on[A-Z][a-z]+$/; const rootAttributes = ['class', 'style']; -/** - * click --> onClick - */ - -const transformOn = (event = '') => `on${event[0].toUpperCase()}${event.substr(1)}`; /** * Checks if string is describing a directive @@ -85,18 +80,15 @@ const getJSXAttributeValue = (t, path) => { return null; }; -const transformJSXAttribute = (t, path, attributesToMerge, directives) => { +const transformJSXAttribute = (t, path, state, attributesToMerge, directives) => { let name = getJSXAttributeName(t, path); - if (name === 'on') { - const { properties = [] } = getJSXAttributeValue(t, path); - properties.forEach((property) => { - attributesToMerge.push(t.objectExpression([ - t.objectProperty( - t.identifier(transformOn(property.key.name)), - property.value, - ), - ])); - }); + const attributeValue = getJSXAttributeValue(t, path); + if (state.opts.transformOn && (name === 'on' || name === 'nativeOn')) { + const transformOn = addDefault(path, '@ant-design-vue/babel-helper-vue-transform-on', { nameHint: '_transformOn' }); + attributesToMerge.push(t.callExpression( + transformOn, + [attributeValue || t.booleanLiteral(true)], + )); return null; } if (isDirective(name)) { @@ -104,18 +96,18 @@ const transformJSXAttribute = (t, path, attributesToMerge, directives) => { ? name.replace('v-', '') : name.replace(`v${name[1]}`, name[1].toLowerCase()); if (directiveName === '_model') { - directives.push(getJSXAttributeValue(t, path)); + directives.push(attributeValue); } else if (directiveName === 'show') { directives.push(t.arrayExpression([ - path.vShow, - getJSXAttributeValue(t, path), + state.vShow, + attributeValue, ])); } else { directives.push(t.arrayExpression([ - t.callExpression(path.resolveDirective, [ + t.callExpression(state.resolveDirective, [ t.stringLiteral(directiveName), ]), - getJSXAttributeValue(t, path), + attributeValue, ])); } return null; @@ -127,7 +119,7 @@ const transformJSXAttribute = (t, path, attributesToMerge, directives) => { t.stringLiteral( name, ), - getJSXAttributeValue(t, path), + attributeValue, ), ]), ); @@ -141,7 +133,7 @@ const transformJSXAttribute = (t, path, attributesToMerge, directives) => { t.stringLiteral( name, ), - getJSXAttributeValue(t, path) || t.booleanLiteral(true), + attributeValue || t.booleanLiteral(true), ); }; @@ -169,12 +161,12 @@ const transformJSXSpreadAttribute = (t, path, attributesToMerge) => { }))); }; -const transformAttribute = (t, path, attributesToMerge, directives) => ( +const transformAttribute = (t, path, state, attributesToMerge, directives) => ( path.isJSXAttribute() - ? transformJSXAttribute(t, path, attributesToMerge, directives) + ? transformJSXAttribute(t, path, state, attributesToMerge, directives) : transformJSXSpreadAttribute(t, path, attributesToMerge)); -const getAttributes = (t, path, directives) => { +const getAttributes = (t, path, state, directives) => { const attributes = path.get('openingElement').get('attributes'); if (attributes.length === 0) { return t.nullLiteral(); @@ -184,13 +176,13 @@ const getAttributes = (t, path, directives) => { const attributeArray = []; attributes .forEach((attribute) => { - const attr = transformAttribute(t, attribute, attributesToMerge, directives); + const attr = transformAttribute(t, attribute, state, attributesToMerge, directives); if (attr) { attributeArray.push(attr); } }); return t.callExpression( - path.mergeProps, + state.mergeProps, [ ...attributesToMerge, t.objectExpression(attributeArray), @@ -295,18 +287,18 @@ const getChildren = (t, paths) => paths && !t.isJSXEmptyExpression(value) )); -const transformJSXElement = (t, path) => { +const transformJSXElement = (t, path, state) => { const directives = []; const tag = getTag(t, path); const children = t.arrayExpression(getChildren(t, path.get('children'))); - const h = t.callExpression(path.h, [ + const h = t.callExpression(state.h, [ tag, - getAttributes(t, path, directives), + getAttributes(t, path, state, directives), !t.isStringLiteral(tag) ? t.objectExpression([ t.objectProperty( t.identifier('default'), - t.callExpression(path.withCtx, [ + t.callExpression(state.withCtx, [ t.arrowFunctionExpression( [], children, @@ -319,7 +311,7 @@ const transformJSXElement = (t, path) => { if (!directives.length) { return h; } - return t.callExpression(path.withDirectives, [ + return t.callExpression(state.withDirectives, [ h, t.arrayExpression(directives), ]); @@ -332,14 +324,14 @@ const imports = [ module.exports = (t) => ({ JSXElement: { - exit(path) { + exit(path, state) { imports.forEach((m) => { - if (!path[m]) { - path[m] = addNamed(path, m, 'vue'); + if (!state[m]) { + state[m] = addNamed(path, m, 'vue'); } }); path.replaceWith( - transformJSXElement(t, path), + transformJSXElement(t, path, state), ); }, }, diff --git a/test/index.test.js b/packages/babel-plugin-jsx/test/index.test.js similarity index 100% rename from test/index.test.js rename to packages/babel-plugin-jsx/test/index.test.js diff --git a/test/setup.js b/packages/babel-plugin-jsx/test/setup.js similarity index 100% rename from test/setup.js rename to packages/babel-plugin-jsx/test/setup.js diff --git a/webpack.config.js b/packages/babel-plugin-jsx/webpack.config.js similarity index 100% rename from webpack.config.js rename to packages/babel-plugin-jsx/webpack.config.js