From 47c4105c4f0056e5315c96701fefb4a1b319a4a4 Mon Sep 17 00:00:00 2001 From: Amour1688 Date: Sun, 24 May 2020 22:06:59 +0800 Subject: [PATCH] refactor: remove @babel/types in dependencies --- package.json | 5 +- src/index.js | 8 +-- src/sugar-fragment.js | 15 +++-- src/sugar-v-model.js | 54 +++++++++--------- src/transform-vue-jsx.js | 119 ++++++++++++++++++++------------------- 5 files changed, 101 insertions(+), 100 deletions(-) diff --git a/package.json b/package.json index 2e30113..7aac3fc 100644 --- a/package.json +++ b/package.json @@ -23,9 +23,8 @@ "jsx" ], "dependencies": { - "@babel/helper-module-imports": "^7.8.3", - "@babel/plugin-syntax-jsx": "^7.8.3", - "@babel/types": "^7.9.6", + "@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" diff --git a/src/index.js b/src/index.js index 8be41be..3084b5e 100644 --- a/src/index.js +++ b/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 = () => ({ +module.exports = ({ types: t }) => ({ name: 'babel-plugin-jsx', inherits: syntaxJsx, visitor: { - ...sugarVModel, - ...tranformVueJSX, - ...sugarFragment, + ...sugarVModel(t), + ...tranformVueJSX(t), + ...sugarFragment(t), }, }); diff --git a/src/sugar-fragment.js b/src/sugar-fragment.js index 41bc627..f7b50e0 100644 --- a/src/sugar-fragment.js +++ b/src/sugar-fragment.js @@ -1,7 +1,6 @@ -const t = require('@babel/types'); const helperModuleImports = require('@babel/helper-module-imports'); -const transformFragment = (path, { name }) => { +const transformFragment = (t, path, { name }) => { const children = path.get('children') || []; return t.jsxElement( t.jsxOpeningElement(t.jsxIdentifier(name), []), @@ -11,13 +10,13 @@ const transformFragment = (path, { name }) => { ); }; -module.exports = { +module.exports = (t) => ({ JSXFragment: { - enter(path, state) { - if (!state.vueFragment) { - state.vueFragment = helperModuleImports.addNamed(path, 'Fragment', 'vue'); + enter(path) { + if (!path.vueFragment) { + path.vueFragment = helperModuleImports.addNamed(path, 'Fragment', 'vue'); } - path.replaceWith(transformFragment(path, state.vueFragment)); + path.replaceWith(transformFragment(t, path, path.vueFragment)); }, }, -}; +}); diff --git a/src/sugar-v-model.js b/src/sugar-v-model.js index a439f5f..690716b 100644 --- a/src/sugar-v-model.js +++ b/src/sugar-v-model.js @@ -1,4 +1,3 @@ -const t = require('@babel/types'); const htmlTags = require('html-tags'); const svgTags = require('svg-tags'); const camelCase = require('camelcase'); @@ -33,7 +32,6 @@ const addProp = (path, value) => { /** * Get JSX element tag name * - * @param t * @param path Path */ const getTagName = (path) => path.get('name.name').node; @@ -44,7 +42,7 @@ const getTagName = (path) => path.get('name.name').node; * @param t * @param path Path */ -const getType = (path) => { +const getType = (t, path) => { const typePath = path .get('attributes') .find( @@ -64,7 +62,7 @@ const getType = (path) => { * @param path JSXOpeningElement * @returns boolean */ -const isComponent = (path) => { +const isComponent = (t, path) => { const name = path.get('name'); if (t.isJSXMemberExpression(name)) { @@ -77,11 +75,12 @@ const isComponent = (path) => { }; /** + * @param t * Transform vModel */ -const getModelDirective = (path, state, value) => { +const getModelDirective = (t, path, value) => { const tag = getTagName(path); - const type = getType(path); + const type = getType(t, path); addProp(path, t.jsxSpreadAttribute( t.objectExpression([ @@ -95,7 +94,7 @@ const getModelDirective = (path, state, value) => { ]), )); - if (isComponent(path)) { + if (isComponent(t, path)) { addProp(path, t.jsxAttribute(t.jsxIdentifier('modelValue'), t.jsxExpressionContainer(value))); return null; } @@ -103,35 +102,35 @@ const getModelDirective = (path, state, value) => { let modelToUse; switch (tag) { case 'select': - if (!state.vueVModelSelect) { - state.vueVModelSelect = addNamed(path, 'vModelSelect', 'vue'); + if (!path.vueVModelSelect) { + path.vueVModelSelect = addNamed(path, 'vModelSelect', 'vue'); } - modelToUse = state.vueVModelSelect; + modelToUse = path.vueVModelSelect; break; case 'textarea': - if (!state.vueVModelText) { - state.vueVModelText = addNamed(path, 'vModelText', 'vue'); + if (!path.vueVModelText) { + path.vueVModelText = addNamed(path, 'vModelText', 'vue'); } break; default: switch (type) { case 'checkbox': - if (!state.vueVModelCheckbox) { - state.vueVModelCheckbox = addNamed(path, 'vModelCheckbox', 'vue'); + if (!path.vueVModelCheckbox) { + path.vueVModelCheckbox = addNamed(path, 'vModelCheckbox', 'vue'); } - modelToUse = state.vueVModelCheckbox; + modelToUse = path.vueVModelCheckbox; break; case 'radio': - if (!state.vueVModelRadio) { - state.vueVModelRadio = addNamed(path, 'vModelRadio', 'vue'); + if (!path.vueVModelRadio) { + path.vueVModelRadio = addNamed(path, 'vModelRadio', 'vue'); } - modelToUse = state.vueVModelRadio; + modelToUse = path.vueVModelRadio; break; default: - if (!state.vueVModelText) { - state.vueVModelText = addNamed(path, 'vModelText', 'vue'); + if (!path.vueVModelText) { + path.vueVModelText = addNamed(path, 'vModelText', 'vue'); } - modelToUse = state.vueVModelText; + modelToUse = path.vueVModelText; } } @@ -142,10 +141,11 @@ const getModelDirective = (path, state, value) => { /** * Parse vModel metadata * + * @param t * @param path JSXAttribute * @returns null | Object<{ modifiers: Set, valuePath: Path}> */ -const parseVModel = (path) => { +const parseVModel = (t, path) => { if (t.isJSXNamespacedName(path.get('name')) || !startsWithCamel(path.get('name.name').node, 'v-model')) { return null; } @@ -162,10 +162,10 @@ const parseVModel = (path) => { }; }; -module.exports = { +module.exports = (t) => ({ JSXAttribute: { - exit(path, state) { - const parsed = parseVModel(path); + exit(path) { + const parsed = parseVModel(t, path); if (!parsed) { return; } @@ -174,7 +174,7 @@ module.exports = { const parent = path.parentPath; // v-model={xx} --> v-_model={[directive, xx, void 0, { a: true, b: true }]} - const directive = getModelDirective(parent, state, value); + const directive = getModelDirective(t, parent, value); if (directive) { path.replaceWith( t.jsxAttribute( @@ -201,4 +201,4 @@ module.exports = { } }, }, -}; +}); diff --git a/src/transform-vue-jsx.js b/src/transform-vue-jsx.js index 32dabef..127d954 100644 --- a/src/transform-vue-jsx.js +++ b/src/transform-vue-jsx.js @@ -1,4 +1,3 @@ -const t = require('@babel/types'); const htmlTags = require('html-tags'); const svgTags = require('svg-tags'); const { addNamed } = require('@babel/helper-module-imports'); @@ -13,12 +12,6 @@ const rootAttributes = ['class', 'style']; const transformOn = (event = '') => `on${event[0].toUpperCase()}${event.substr(1)}`; -const filterEmpty = (value) => ( - value !== undefined - && value !== null - && !t.isJSXEmptyExpression(value) -); - /** * Checks if string is describing a directive * @param src string @@ -28,15 +21,16 @@ const isDirective = (src) => src.startsWith('v-') /** * Transform JSXMemberExpression to MemberExpression + * @param t * @param path JSXMemberExpression * @returns MemberExpression */ -const transformJSXMemberExpression = (path) => { +const transformJSXMemberExpression = (t, path) => { const objectPath = path.get('object'); const propertyPath = path.get('property'); const transformedObject = objectPath.isJSXMemberExpression() - ? transformJSXMemberExpression(objectPath) + ? transformJSXMemberExpression(t, objectPath) : objectPath.isJSXIdentifier() ? t.identifier(objectPath.node.name) : t.nullLiteral(); @@ -46,10 +40,11 @@ const transformJSXMemberExpression = (path) => { /** * Get tag (first attribute for h) from JSXOpeningElement + * @param t * @param path JSXOpeningElement * @returns Identifier | StringLiteral | MemberExpression */ -const getTag = (path) => { +const getTag = (t, path) => { const namePath = path.get('openingElement').get('name'); if (namePath.isJSXIdentifier()) { const { name } = namePath.node; @@ -61,12 +56,12 @@ const getTag = (path) => { } if (namePath.isJSXMemberExpression()) { - return transformJSXMemberExpression(namePath); + return transformJSXMemberExpression(t, namePath); } throw new Error(`getTag: ${namePath.type} is not supported`); }; -const getJSXAttributeName = (path) => { +const getJSXAttributeName = (t, path) => { const nameNode = path.node.name; if (t.isJSXIdentifier(nameNode)) { return nameNode.name; @@ -75,10 +70,10 @@ const getJSXAttributeName = (path) => { return `${nameNode.namespace.name}:${nameNode.name.name}`; }; -const getJSXAttributeValue = (path, injected) => { +const getJSXAttributeValue = (t, path, injected) => { const valuePath = path.get('value'); if (valuePath.isJSXElement()) { - return transformJSXElement(valuePath, injected); + return transformJSXElement(t, valuePath, injected); } if (valuePath.isStringLiteral()) { return valuePath.node; @@ -90,10 +85,10 @@ const getJSXAttributeValue = (path, injected) => { return null; }; -const transformJSXAttribute = (path, attributesToMerge, directives, injected) => { - let name = getJSXAttributeName(path); +const transformJSXAttribute = (t, path, attributesToMerge, directives, injected) => { + let name = getJSXAttributeName(t, path); if (name === 'on') { - const { properties = [] } = getJSXAttributeValue(path); + const { properties = [] } = getJSXAttributeValue(t, path); properties.forEach((property) => { attributesToMerge.push(t.objectExpression([ t.objectProperty( @@ -109,18 +104,18 @@ const transformJSXAttribute = (path, attributesToMerge, directives, injected) => ? name.replace('v-', '') : name.replace(`v${name[1]}`, name[1].toLowerCase()); if (directiveName === '_model') { - directives.push(getJSXAttributeValue(path)); + directives.push(getJSXAttributeValue(t, path)); } else if (directiveName === 'show') { directives.push(t.arrayExpression([ injected.vShow, - getJSXAttributeValue(path), + getJSXAttributeValue(t, path), ])); } else { directives.push(t.arrayExpression([ t.callExpression(injected.resolveDirective, [ t.stringLiteral(directiveName), ]), - getJSXAttributeValue(path), + getJSXAttributeValue(t, path), ])); } return null; @@ -132,7 +127,7 @@ const transformJSXAttribute = (path, attributesToMerge, directives, injected) => t.stringLiteral( name, ), - getJSXAttributeValue(path, injected), + getJSXAttributeValue(t, path, injected), ), ]), ); @@ -146,11 +141,11 @@ const transformJSXAttribute = (path, attributesToMerge, directives, injected) => t.stringLiteral( name, ), - getJSXAttributeValue(path, injected) || t.booleanLiteral(true), + getJSXAttributeValue(t, path, injected) || t.booleanLiteral(true), ); }; -const transformJSXSpreadAttribute = (path, attributesToMerge) => { +const transformJSXSpreadAttribute = (t, path, attributesToMerge) => { const argument = path.get('argument').node; const { properties } = argument; if (!properties) { @@ -174,11 +169,12 @@ const transformJSXSpreadAttribute = (path, attributesToMerge) => { }))); }; -const transformAttribute = (path, attributesToMerge, directives, injected) => (path.isJSXAttribute() - ? transformJSXAttribute(path, attributesToMerge, directives, injected) - : transformJSXSpreadAttribute(path, attributesToMerge)); +const transformAttribute = (t, path, attributesToMerge, directives, injected) => ( + path.isJSXAttribute() + ? transformJSXAttribute(t, path, attributesToMerge, directives, injected) + : transformJSXSpreadAttribute(t, path, attributesToMerge)); -const getAttributes = (path, directives, injected) => { +const getAttributes = (t, path, directives, injected) => { const attributes = path.get('openingElement').get('attributes'); if (attributes.length === 0) { return t.nullLiteral(); @@ -188,7 +184,7 @@ const getAttributes = (path, directives, injected) => { const attributeArray = []; attributes .forEach((attribute) => { - const attr = transformAttribute(attribute, attributesToMerge, directives, injected); + const attr = transformAttribute(t, attribute, attributesToMerge, directives, injected); if (attr) { attributeArray.push(attr); } @@ -204,10 +200,11 @@ const getAttributes = (path, directives, injected) => { /** * Transform JSXText to StringLiteral + * @param t * @param path JSXText * @returns StringLiteral */ -const transformJSXText = (path) => { +const transformJSXText = (t, path) => { const { node } = path; const lines = node.value.split(/\r\n|\n|\r/); @@ -262,43 +259,49 @@ const transformJSXExpressionContainer = (path) => path.get('expression').node; /** * Transform JSXSpreadChild + * @param t * @param path JSXSpreadChild * @returns SpreadElement */ -const transformJSXSpreadChild = (path) => t.spreadElement(path.get('expression').node); +const transformJSXSpreadChild = (t, path) => t.spreadElement(path.get('expression').node); /** * Get children from Array of JSX children + * @param t * @param paths Array * @param injected {} * @returns Array */ -const getChildren = (paths, injected) => paths +const getChildren = (t, paths, injected) => paths .map((path) => { if (path.isJSXText()) { - return transformJSXText(path); + return transformJSXText(t, path); } if (path.isJSXExpressionContainer()) { return transformJSXExpressionContainer(path); } if (path.isJSXSpreadChild()) { - return transformJSXSpreadChild(path); + return transformJSXSpreadChild(t, path); } if (path.isCallExpression()) { return path.node; } if (path.isJSXElement()) { - return transformJSXElement(path, injected); + return transformJSXElement(t, path, injected); } throw new Error(`getChildren: ${path.type} is not supported`); - }).filter(filterEmpty); + }).filter((value) => ( + value !== undefined + && value !== null + && !t.isJSXEmptyExpression(value) + )); -const transformJSXElement = (path, injected) => { +const transformJSXElement = (t, path, injected) => { const directives = []; const h = t.callExpression(injected.h, [ - getTag(path), - getAttributes(path, directives, injected), - t.arrayExpression(getChildren(path.get('children'), injected)), + getTag(t, path), + getAttributes(t, path, directives, injected), + t.arrayExpression(getChildren(t, path.get('children'), injected)), ]); if (!directives.length) { return h; @@ -309,33 +312,33 @@ const transformJSXElement = (path, injected) => { ]); }; -module.exports = { +module.exports = (t) => ({ JSXElement: { - exit(path, state) { - if (!state.vueCreateElementInjected) { - state.vueCreateElementInjected = addNamed(path, 'h', 'vue'); + exit(path) { + if (!path.vueCreateElementInjected) { + path.vueCreateElementInjected = addNamed(path, 'h', 'vue'); } - if (!state.vueMergePropsInjected) { - state.vueMergePropsInjected = addNamed(path, 'mergeProps', 'vue'); + if (!path.vueMergePropsInjected) { + path.vueMergePropsInjected = addNamed(path, 'mergeProps', 'vue'); } - if (!state.vueWithDirectivesInjected) { - state.vueWithDirectivesInjected = addNamed(path, 'withDirectives', 'vue'); + if (!path.vueWithDirectivesInjected) { + path.vueWithDirectivesInjected = addNamed(path, 'withDirectives', 'vue'); } - if (!state.vueResolveDirectiveInjected) { - state.vueResolveDirectiveInjected = addNamed(path, 'resolveDirective', 'vue'); + if (!path.vueResolveDirectiveInjected) { + path.vueResolveDirectiveInjected = addNamed(path, 'resolveDirective', 'vue'); } - if (!state.vueVShowInjected) { - state.vueVShowInjected = addNamed(path, 'vShow', 'vue'); + if (!path.vueVShowInjected) { + path.vueVShowInjected = addNamed(path, 'vShow', 'vue'); } path.replaceWith( - transformJSXElement(path, { - h: state.vueCreateElementInjected, - mergeProps: state.vueMergePropsInjected, - withDirectives: state.vueWithDirectivesInjected, - resolveDirective: state.vueResolveDirectiveInjected, - vShow: state.vueVShowInjected, + transformJSXElement(t, path, { + h: path.vueCreateElementInjected, + mergeProps: path.vueMergePropsInjected, + withDirectives: path.vueWithDirectivesInjected, + resolveDirective: path.vueResolveDirectiveInjected, + vShow: path.vueVShowInjected, }), ); }, }, -}; +});