refactor: remove @babel/types in dependencies

This commit is contained in:
Amour1688 2020-05-24 22:06:59 +08:00
parent 4b954484bf
commit 47c4105c4f
5 changed files with 101 additions and 100 deletions

View File

@ -23,9 +23,8 @@
"jsx" "jsx"
], ],
"dependencies": { "dependencies": {
"@babel/helper-module-imports": "^7.8.3", "@babel/helper-module-imports": "^7.0.0",
"@babel/plugin-syntax-jsx": "^7.8.3", "@babel/plugin-syntax-jsx": "^7.0.0",
"@babel/types": "^7.9.6",
"camelcase": "^6.0.0", "camelcase": "^6.0.0",
"html-tags": "^3.1.0", "html-tags": "^3.1.0",
"svg-tags": "^1.0.0" "svg-tags": "^1.0.0"

View File

@ -3,12 +3,12 @@ const tranformVueJSX = require('./transform-vue-jsx');
const sugarVModel = require('./sugar-v-model'); const sugarVModel = require('./sugar-v-model');
const sugarFragment = require('./sugar-fragment'); const sugarFragment = require('./sugar-fragment');
module.exports = () => ({ module.exports = ({ types: t }) => ({
name: 'babel-plugin-jsx', name: 'babel-plugin-jsx',
inherits: syntaxJsx, inherits: syntaxJsx,
visitor: { visitor: {
...sugarVModel, ...sugarVModel(t),
...tranformVueJSX, ...tranformVueJSX(t),
...sugarFragment, ...sugarFragment(t),
}, },
}); });

View File

@ -1,7 +1,6 @@
const t = require('@babel/types');
const helperModuleImports = require('@babel/helper-module-imports'); const helperModuleImports = require('@babel/helper-module-imports');
const transformFragment = (path, { name }) => { const transformFragment = (t, path, { name }) => {
const children = path.get('children') || []; const children = path.get('children') || [];
return t.jsxElement( return t.jsxElement(
t.jsxOpeningElement(t.jsxIdentifier(name), []), t.jsxOpeningElement(t.jsxIdentifier(name), []),
@ -11,13 +10,13 @@ const transformFragment = (path, { name }) => {
); );
}; };
module.exports = { module.exports = (t) => ({
JSXFragment: { JSXFragment: {
enter(path, state) { enter(path) {
if (!state.vueFragment) { if (!path.vueFragment) {
state.vueFragment = helperModuleImports.addNamed(path, 'Fragment', 'vue'); path.vueFragment = helperModuleImports.addNamed(path, 'Fragment', 'vue');
} }
path.replaceWith(transformFragment(path, state.vueFragment)); path.replaceWith(transformFragment(t, path, path.vueFragment));
}, },
}, },
}; });

View File

@ -1,4 +1,3 @@
const t = require('@babel/types');
const htmlTags = require('html-tags'); const htmlTags = require('html-tags');
const svgTags = require('svg-tags'); const svgTags = require('svg-tags');
const camelCase = require('camelcase'); const camelCase = require('camelcase');
@ -33,7 +32,6 @@ const addProp = (path, value) => {
/** /**
* Get JSX element tag name * Get JSX element tag name
* *
* @param t
* @param path Path<JSXOpeningElement> * @param path Path<JSXOpeningElement>
*/ */
const getTagName = (path) => path.get('name.name').node; const getTagName = (path) => path.get('name.name').node;
@ -44,7 +42,7 @@ const getTagName = (path) => path.get('name.name').node;
* @param t * @param t
* @param path Path<JSXOpeningElement> * @param path Path<JSXOpeningElement>
*/ */
const getType = (path) => { const getType = (t, path) => {
const typePath = path const typePath = path
.get('attributes') .get('attributes')
.find( .find(
@ -64,7 +62,7 @@ const getType = (path) => {
* @param path JSXOpeningElement * @param path JSXOpeningElement
* @returns boolean * @returns boolean
*/ */
const isComponent = (path) => { const isComponent = (t, path) => {
const name = path.get('name'); const name = path.get('name');
if (t.isJSXMemberExpression(name)) { if (t.isJSXMemberExpression(name)) {
@ -77,11 +75,12 @@ const isComponent = (path) => {
}; };
/** /**
* @param t
* Transform vModel * Transform vModel
*/ */
const getModelDirective = (path, state, value) => { const getModelDirective = (t, path, value) => {
const tag = getTagName(path); const tag = getTagName(path);
const type = getType(path); const type = getType(t, path);
addProp(path, t.jsxSpreadAttribute( addProp(path, t.jsxSpreadAttribute(
t.objectExpression([ 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))); addProp(path, t.jsxAttribute(t.jsxIdentifier('modelValue'), t.jsxExpressionContainer(value)));
return null; return null;
} }
@ -103,35 +102,35 @@ const getModelDirective = (path, state, value) => {
let modelToUse; let modelToUse;
switch (tag) { switch (tag) {
case 'select': case 'select':
if (!state.vueVModelSelect) { if (!path.vueVModelSelect) {
state.vueVModelSelect = addNamed(path, 'vModelSelect', 'vue'); path.vueVModelSelect = addNamed(path, 'vModelSelect', 'vue');
} }
modelToUse = state.vueVModelSelect; modelToUse = path.vueVModelSelect;
break; break;
case 'textarea': case 'textarea':
if (!state.vueVModelText) { if (!path.vueVModelText) {
state.vueVModelText = addNamed(path, 'vModelText', 'vue'); path.vueVModelText = addNamed(path, 'vModelText', 'vue');
} }
break; break;
default: default:
switch (type) { switch (type) {
case 'checkbox': case 'checkbox':
if (!state.vueVModelCheckbox) { if (!path.vueVModelCheckbox) {
state.vueVModelCheckbox = addNamed(path, 'vModelCheckbox', 'vue'); path.vueVModelCheckbox = addNamed(path, 'vModelCheckbox', 'vue');
} }
modelToUse = state.vueVModelCheckbox; modelToUse = path.vueVModelCheckbox;
break; break;
case 'radio': case 'radio':
if (!state.vueVModelRadio) { if (!path.vueVModelRadio) {
state.vueVModelRadio = addNamed(path, 'vModelRadio', 'vue'); path.vueVModelRadio = addNamed(path, 'vModelRadio', 'vue');
} }
modelToUse = state.vueVModelRadio; modelToUse = path.vueVModelRadio;
break; break;
default: default:
if (!state.vueVModelText) { if (!path.vueVModelText) {
state.vueVModelText = addNamed(path, 'vModelText', 'vue'); path.vueVModelText = addNamed(path, 'vModelText', 'vue');
} }
modelToUse = state.vueVModelText; modelToUse = path.vueVModelText;
} }
} }
@ -142,10 +141,11 @@ const getModelDirective = (path, state, value) => {
/** /**
* Parse vModel metadata * Parse vModel metadata
* *
* @param t
* @param path JSXAttribute * @param path JSXAttribute
* @returns null | Object<{ modifiers: Set<string>, valuePath: Path<Expression>}> * @returns null | Object<{ modifiers: Set<string>, valuePath: Path<Expression>}>
*/ */
const parseVModel = (path) => { const parseVModel = (t, path) => {
if (t.isJSXNamespacedName(path.get('name')) || !startsWithCamel(path.get('name.name').node, 'v-model')) { if (t.isJSXNamespacedName(path.get('name')) || !startsWithCamel(path.get('name.name').node, 'v-model')) {
return null; return null;
} }
@ -162,10 +162,10 @@ const parseVModel = (path) => {
}; };
}; };
module.exports = { module.exports = (t) => ({
JSXAttribute: { JSXAttribute: {
exit(path, state) { exit(path) {
const parsed = parseVModel(path); const parsed = parseVModel(t, path);
if (!parsed) { if (!parsed) {
return; return;
} }
@ -174,7 +174,7 @@ module.exports = {
const parent = path.parentPath; const parent = path.parentPath;
// v-model={xx} --> v-_model={[directive, xx, void 0, { a: true, b: true }]} // 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) { if (directive) {
path.replaceWith( path.replaceWith(
t.jsxAttribute( t.jsxAttribute(
@ -201,4 +201,4 @@ module.exports = {
} }
}, },
}, },
}; });

View File

@ -1,4 +1,3 @@
const t = require('@babel/types');
const htmlTags = require('html-tags'); const htmlTags = require('html-tags');
const svgTags = require('svg-tags'); const svgTags = require('svg-tags');
const { addNamed } = require('@babel/helper-module-imports'); 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 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 * Checks if string is describing a directive
* @param src string * @param src string
@ -28,15 +21,16 @@ const isDirective = (src) => src.startsWith('v-')
/** /**
* Transform JSXMemberExpression to MemberExpression * Transform JSXMemberExpression to MemberExpression
* @param t
* @param path JSXMemberExpression * @param path JSXMemberExpression
* @returns MemberExpression * @returns MemberExpression
*/ */
const transformJSXMemberExpression = (path) => { const transformJSXMemberExpression = (t, path) => {
const objectPath = path.get('object'); const objectPath = path.get('object');
const propertyPath = path.get('property'); const propertyPath = path.get('property');
const transformedObject = objectPath.isJSXMemberExpression() const transformedObject = objectPath.isJSXMemberExpression()
? transformJSXMemberExpression(objectPath) ? transformJSXMemberExpression(t, objectPath)
: objectPath.isJSXIdentifier() : objectPath.isJSXIdentifier()
? t.identifier(objectPath.node.name) ? t.identifier(objectPath.node.name)
: t.nullLiteral(); : t.nullLiteral();
@ -46,10 +40,11 @@ const transformJSXMemberExpression = (path) => {
/** /**
* Get tag (first attribute for h) from JSXOpeningElement * Get tag (first attribute for h) from JSXOpeningElement
* @param t
* @param path JSXOpeningElement * @param path JSXOpeningElement
* @returns Identifier | StringLiteral | MemberExpression * @returns Identifier | StringLiteral | MemberExpression
*/ */
const getTag = (path) => { const getTag = (t, path) => {
const namePath = path.get('openingElement').get('name'); const namePath = path.get('openingElement').get('name');
if (namePath.isJSXIdentifier()) { if (namePath.isJSXIdentifier()) {
const { name } = namePath.node; const { name } = namePath.node;
@ -61,12 +56,12 @@ const getTag = (path) => {
} }
if (namePath.isJSXMemberExpression()) { if (namePath.isJSXMemberExpression()) {
return transformJSXMemberExpression(namePath); return transformJSXMemberExpression(t, namePath);
} }
throw new Error(`getTag: ${namePath.type} is not supported`); throw new Error(`getTag: ${namePath.type} is not supported`);
}; };
const getJSXAttributeName = (path) => { const getJSXAttributeName = (t, path) => {
const nameNode = path.node.name; const nameNode = path.node.name;
if (t.isJSXIdentifier(nameNode)) { if (t.isJSXIdentifier(nameNode)) {
return nameNode.name; return nameNode.name;
@ -75,10 +70,10 @@ const getJSXAttributeName = (path) => {
return `${nameNode.namespace.name}:${nameNode.name.name}`; return `${nameNode.namespace.name}:${nameNode.name.name}`;
}; };
const getJSXAttributeValue = (path, injected) => { const getJSXAttributeValue = (t, path, injected) => {
const valuePath = path.get('value'); const valuePath = path.get('value');
if (valuePath.isJSXElement()) { if (valuePath.isJSXElement()) {
return transformJSXElement(valuePath, injected); return transformJSXElement(t, valuePath, injected);
} }
if (valuePath.isStringLiteral()) { if (valuePath.isStringLiteral()) {
return valuePath.node; return valuePath.node;
@ -90,10 +85,10 @@ const getJSXAttributeValue = (path, injected) => {
return null; return null;
}; };
const transformJSXAttribute = (path, attributesToMerge, directives, injected) => { const transformJSXAttribute = (t, path, attributesToMerge, directives, injected) => {
let name = getJSXAttributeName(path); let name = getJSXAttributeName(t, path);
if (name === 'on') { if (name === 'on') {
const { properties = [] } = getJSXAttributeValue(path); const { properties = [] } = getJSXAttributeValue(t, path);
properties.forEach((property) => { properties.forEach((property) => {
attributesToMerge.push(t.objectExpression([ attributesToMerge.push(t.objectExpression([
t.objectProperty( t.objectProperty(
@ -109,18 +104,18 @@ const transformJSXAttribute = (path, attributesToMerge, directives, injected) =>
? name.replace('v-', '') ? name.replace('v-', '')
: name.replace(`v${name[1]}`, name[1].toLowerCase()); : name.replace(`v${name[1]}`, name[1].toLowerCase());
if (directiveName === '_model') { if (directiveName === '_model') {
directives.push(getJSXAttributeValue(path)); directives.push(getJSXAttributeValue(t, path));
} else if (directiveName === 'show') { } else if (directiveName === 'show') {
directives.push(t.arrayExpression([ directives.push(t.arrayExpression([
injected.vShow, injected.vShow,
getJSXAttributeValue(path), getJSXAttributeValue(t, path),
])); ]));
} else { } else {
directives.push(t.arrayExpression([ directives.push(t.arrayExpression([
t.callExpression(injected.resolveDirective, [ t.callExpression(injected.resolveDirective, [
t.stringLiteral(directiveName), t.stringLiteral(directiveName),
]), ]),
getJSXAttributeValue(path), getJSXAttributeValue(t, path),
])); ]));
} }
return null; return null;
@ -132,7 +127,7 @@ const transformJSXAttribute = (path, attributesToMerge, directives, injected) =>
t.stringLiteral( t.stringLiteral(
name, name,
), ),
getJSXAttributeValue(path, injected), getJSXAttributeValue(t, path, injected),
), ),
]), ]),
); );
@ -146,11 +141,11 @@ const transformJSXAttribute = (path, attributesToMerge, directives, injected) =>
t.stringLiteral( t.stringLiteral(
name, 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 argument = path.get('argument').node;
const { properties } = argument; const { properties } = argument;
if (!properties) { if (!properties) {
@ -174,11 +169,12 @@ const transformJSXSpreadAttribute = (path, attributesToMerge) => {
}))); })));
}; };
const transformAttribute = (path, attributesToMerge, directives, injected) => (path.isJSXAttribute() const transformAttribute = (t, path, attributesToMerge, directives, injected) => (
? transformJSXAttribute(path, attributesToMerge, directives, injected) path.isJSXAttribute()
: transformJSXSpreadAttribute(path, attributesToMerge)); ? 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'); const attributes = path.get('openingElement').get('attributes');
if (attributes.length === 0) { if (attributes.length === 0) {
return t.nullLiteral(); return t.nullLiteral();
@ -188,7 +184,7 @@ const getAttributes = (path, directives, injected) => {
const attributeArray = []; const attributeArray = [];
attributes attributes
.forEach((attribute) => { .forEach((attribute) => {
const attr = transformAttribute(attribute, attributesToMerge, directives, injected); const attr = transformAttribute(t, attribute, attributesToMerge, directives, injected);
if (attr) { if (attr) {
attributeArray.push(attr); attributeArray.push(attr);
} }
@ -204,10 +200,11 @@ const getAttributes = (path, directives, injected) => {
/** /**
* Transform JSXText to StringLiteral * Transform JSXText to StringLiteral
* @param t
* @param path JSXText * @param path JSXText
* @returns StringLiteral * @returns StringLiteral
*/ */
const transformJSXText = (path) => { const transformJSXText = (t, path) => {
const { node } = path; const { node } = path;
const lines = node.value.split(/\r\n|\n|\r/); const lines = node.value.split(/\r\n|\n|\r/);
@ -262,43 +259,49 @@ const transformJSXExpressionContainer = (path) => path.get('expression').node;
/** /**
* Transform JSXSpreadChild * Transform JSXSpreadChild
* @param t
* @param path JSXSpreadChild * @param path JSXSpreadChild
* @returns SpreadElement * @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 * Get children from Array of JSX children
* @param t
* @param paths Array<JSXText | JSXExpressionContainer | JSXSpreadChild | JSXElement> * @param paths Array<JSXText | JSXExpressionContainer | JSXSpreadChild | JSXElement>
* @param injected {} * @param injected {}
* @returns Array<Expression | SpreadElement> * @returns Array<Expression | SpreadElement>
*/ */
const getChildren = (paths, injected) => paths const getChildren = (t, paths, injected) => paths
.map((path) => { .map((path) => {
if (path.isJSXText()) { if (path.isJSXText()) {
return transformJSXText(path); return transformJSXText(t, path);
} }
if (path.isJSXExpressionContainer()) { if (path.isJSXExpressionContainer()) {
return transformJSXExpressionContainer(path); return transformJSXExpressionContainer(path);
} }
if (path.isJSXSpreadChild()) { if (path.isJSXSpreadChild()) {
return transformJSXSpreadChild(path); return transformJSXSpreadChild(t, path);
} }
if (path.isCallExpression()) { if (path.isCallExpression()) {
return path.node; return path.node;
} }
if (path.isJSXElement()) { if (path.isJSXElement()) {
return transformJSXElement(path, injected); return transformJSXElement(t, path, injected);
} }
throw new Error(`getChildren: ${path.type} is not supported`); 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 directives = [];
const h = t.callExpression(injected.h, [ const h = t.callExpression(injected.h, [
getTag(path), getTag(t, path),
getAttributes(path, directives, injected), getAttributes(t, path, directives, injected),
t.arrayExpression(getChildren(path.get('children'), injected)), t.arrayExpression(getChildren(t, path.get('children'), injected)),
]); ]);
if (!directives.length) { if (!directives.length) {
return h; return h;
@ -309,33 +312,33 @@ const transformJSXElement = (path, injected) => {
]); ]);
}; };
module.exports = { module.exports = (t) => ({
JSXElement: { JSXElement: {
exit(path, state) { exit(path) {
if (!state.vueCreateElementInjected) { if (!path.vueCreateElementInjected) {
state.vueCreateElementInjected = addNamed(path, 'h', 'vue'); path.vueCreateElementInjected = addNamed(path, 'h', 'vue');
} }
if (!state.vueMergePropsInjected) { if (!path.vueMergePropsInjected) {
state.vueMergePropsInjected = addNamed(path, 'mergeProps', 'vue'); path.vueMergePropsInjected = addNamed(path, 'mergeProps', 'vue');
} }
if (!state.vueWithDirectivesInjected) { if (!path.vueWithDirectivesInjected) {
state.vueWithDirectivesInjected = addNamed(path, 'withDirectives', 'vue'); path.vueWithDirectivesInjected = addNamed(path, 'withDirectives', 'vue');
} }
if (!state.vueResolveDirectiveInjected) { if (!path.vueResolveDirectiveInjected) {
state.vueResolveDirectiveInjected = addNamed(path, 'resolveDirective', 'vue'); path.vueResolveDirectiveInjected = addNamed(path, 'resolveDirective', 'vue');
} }
if (!state.vueVShowInjected) { if (!path.vueVShowInjected) {
state.vueVShowInjected = addNamed(path, 'vShow', 'vue'); path.vueVShowInjected = addNamed(path, 'vShow', 'vue');
} }
path.replaceWith( path.replaceWith(
transformJSXElement(path, { transformJSXElement(t, path, {
h: state.vueCreateElementInjected, h: path.vueCreateElementInjected,
mergeProps: state.vueMergePropsInjected, mergeProps: path.vueMergePropsInjected,
withDirectives: state.vueWithDirectivesInjected, withDirectives: path.vueWithDirectivesInjected,
resolveDirective: state.vueResolveDirectiveInjected, resolveDirective: path.vueResolveDirectiveInjected,
vShow: state.vueVShowInjected, vShow: path.vueVShowInjected,
}), }),
); );
}, },
}, },
}; });