mirror of
https://github.com/vuejs/babel-plugin-jsx.git
synced 2025-04-24 10:32:33 +08:00
refactor: with TypeScript (#24)
* refactor: add ts support (#19) Co-authored-by: 逆寒 <869732751@qq.com>
This commit is contained in:
parent
3d49271878
commit
bc4ef2c028
2
global.d.ts
vendored
Normal file
2
global.d.ts
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
declare module '@babel/helper-module-imports';
|
||||||
|
declare module '@babel/plugin-syntax-jsx';
|
@ -5,6 +5,7 @@
|
|||||||
],
|
],
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"publish": "lerna publish",
|
"publish": "lerna publish",
|
||||||
|
"test": "lerna run test",
|
||||||
"dev": "node scripts/dev.js",
|
"dev": "node scripts/dev.js",
|
||||||
"site": "node scripts/site.js"
|
"site": "node scripts/site.js"
|
||||||
},
|
},
|
||||||
|
2
packages/babel-plugin-jsx/global.d.ts
vendored
Normal file
2
packages/babel-plugin-jsx/global.d.ts
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
declare module '@babel/helper-module-imports';
|
||||||
|
declare module '@babel/plugin-syntax-jsx';
|
@ -12,9 +12,9 @@
|
|||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "npm run build && webpack-dev-server",
|
"dev": "npm run build && webpack-dev-server",
|
||||||
"build": "rollup -c",
|
"build": "tsc",
|
||||||
"lint": "eslint --ext .js src",
|
"lint": "eslint --ext .js src",
|
||||||
"test": "jest --coverage"
|
"test": "npm run build && jest --coverage"
|
||||||
},
|
},
|
||||||
"bugs": {
|
"bugs": {
|
||||||
"url": "https://github.com/vueComponent/jsx/issues"
|
"url": "https://github.com/vueComponent/jsx/issues"
|
||||||
@ -27,13 +27,14 @@
|
|||||||
"@ant-design-vue/babel-helper-vue-transform-on": "^1.0.0",
|
"@ant-design-vue/babel-helper-vue-transform-on": "^1.0.0",
|
||||||
"@babel/helper-module-imports": "^7.0.0",
|
"@babel/helper-module-imports": "^7.0.0",
|
||||||
"@babel/plugin-syntax-jsx": "^7.0.0",
|
"@babel/plugin-syntax-jsx": "^7.0.0",
|
||||||
|
"@babel/types": "^7.0.0",
|
||||||
"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"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "^7.9.6",
|
"@babel/core": "^7.0.0",
|
||||||
"@babel/preset-env": "^7.9.6",
|
"@babel/preset-env": "^7.0.0",
|
||||||
"@rollup/plugin-babel": "^5.0.3",
|
"@rollup/plugin-babel": "^5.0.3",
|
||||||
"@vue/compiler-dom": "3.0.0-beta.20",
|
"@vue/compiler-dom": "3.0.0-beta.20",
|
||||||
"@vue/test-utils": "^2.0.0-alpha.8",
|
"@vue/test-utils": "^2.0.0-alpha.8",
|
||||||
@ -43,6 +44,7 @@
|
|||||||
"regenerator-runtime": "^0.13.5",
|
"regenerator-runtime": "^0.13.5",
|
||||||
"rollup": "^2.13.1",
|
"rollup": "^2.13.1",
|
||||||
"vue": "3.0.0-beta.20",
|
"vue": "3.0.0-beta.20",
|
||||||
|
"typescript": "^3.9.6",
|
||||||
"webpack": "^4.43.0",
|
"webpack": "^4.43.0",
|
||||||
"webpack-cli": "^3.3.11",
|
"webpack-cli": "^3.3.11",
|
||||||
"webpack-dev-server": "^3.10.3"
|
"webpack-dev-server": "^3.10.3"
|
||||||
|
@ -1,22 +1,12 @@
|
|||||||
import babel from '@rollup/plugin-babel';
|
// import babel from '@rollup/plugin-babel';
|
||||||
|
import commonjs from '@rollup/plugin-commonjs';
|
||||||
|
import typescript from '@rollup/plugin-typescript';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
input: 'src/index.js',
|
input: 'src/index.ts',
|
||||||
plugins: [
|
plugins: [
|
||||||
babel({
|
commonjs(),
|
||||||
presets: [
|
typescript(),
|
||||||
[
|
|
||||||
'@babel/preset-env',
|
|
||||||
{
|
|
||||||
targets: {
|
|
||||||
node: 8,
|
|
||||||
},
|
|
||||||
modules: false,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
],
|
|
||||||
configFile: false,
|
|
||||||
}),
|
|
||||||
],
|
],
|
||||||
output: [
|
output: [
|
||||||
{
|
{
|
||||||
|
@ -1,12 +0,0 @@
|
|||||||
import syntaxJsx from '@babel/plugin-syntax-jsx';
|
|
||||||
import tranformVueJSX from './transform-vue-jsx';
|
|
||||||
import sugarFragment from './sugar-fragment';
|
|
||||||
|
|
||||||
export default ({ types: t }) => ({
|
|
||||||
name: 'babel-plugin-jsx',
|
|
||||||
inherits: syntaxJsx,
|
|
||||||
visitor: {
|
|
||||||
...tranformVueJSX(t),
|
|
||||||
...sugarFragment(t),
|
|
||||||
},
|
|
||||||
});
|
|
25
packages/babel-plugin-jsx/src/index.ts
Normal file
25
packages/babel-plugin-jsx/src/index.ts
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
import syntaxJsx from '@babel/plugin-syntax-jsx';
|
||||||
|
import tranformVueJSX from './transform-vue-jsx';
|
||||||
|
import sugarFragment from './sugar-fragment';
|
||||||
|
|
||||||
|
export type State = {
|
||||||
|
get: (name: string) => any;
|
||||||
|
set: (name: string, value: any) => any;
|
||||||
|
opts: Opts;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Opts {
|
||||||
|
transformOn?: boolean;
|
||||||
|
compatibleProps?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type ExcludesFalse = <T>(x: T | false) => x is T;
|
||||||
|
|
||||||
|
export default () => ({
|
||||||
|
name: 'babel-plugin-jsx',
|
||||||
|
inherits: syntaxJsx,
|
||||||
|
visitor: {
|
||||||
|
...tranformVueJSX(),
|
||||||
|
...sugarFragment(),
|
||||||
|
},
|
||||||
|
});
|
33
packages/babel-plugin-jsx/src/patchFlags.ts
Normal file
33
packages/babel-plugin-jsx/src/patchFlags.ts
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
// https://github.com/vuejs/vue-next/blob/master/packages/shared/src/patchFlags.ts
|
||||||
|
export const enum PatchFlags {
|
||||||
|
TEXT = 1,
|
||||||
|
CLASS = 1 << 1,
|
||||||
|
STYLE = 1 << 2,
|
||||||
|
PROPS = 1 << 3,
|
||||||
|
FULL_PROPS = 1 << 4,
|
||||||
|
HYDRATE_EVENTS = 1 << 5,
|
||||||
|
STABLE_FRAGMENT = 1 << 6,
|
||||||
|
KEYED_FRAGMENT = 1 << 7,
|
||||||
|
UNKEYED_FRAGMENT = 1 << 8,
|
||||||
|
NEED_PATCH = 1 << 9,
|
||||||
|
DYNAMIC_SLOTS = 1 << 10,
|
||||||
|
HOISTED = -1,
|
||||||
|
BAIL = -2
|
||||||
|
}
|
||||||
|
|
||||||
|
// dev only flag -> name mapping
|
||||||
|
export const PatchFlagNames = {
|
||||||
|
[PatchFlags.TEXT]: `TEXT`,
|
||||||
|
[PatchFlags.CLASS]: `CLASS`,
|
||||||
|
[PatchFlags.STYLE]: `STYLE`,
|
||||||
|
[PatchFlags.PROPS]: `PROPS`,
|
||||||
|
[PatchFlags.FULL_PROPS]: `FULL_PROPS`,
|
||||||
|
[PatchFlags.HYDRATE_EVENTS]: `HYDRATE_EVENTS`,
|
||||||
|
[PatchFlags.STABLE_FRAGMENT]: `STABLE_FRAGMENT`,
|
||||||
|
[PatchFlags.KEYED_FRAGMENT]: `KEYED_FRAGMENT`,
|
||||||
|
[PatchFlags.UNKEYED_FRAGMENT]: `UNKEYED_FRAGMENT`,
|
||||||
|
[PatchFlags.DYNAMIC_SLOTS]: `DYNAMIC_SLOTS`,
|
||||||
|
[PatchFlags.NEED_PATCH]: `NEED_PATCH`,
|
||||||
|
[PatchFlags.HOISTED]: `HOISTED`,
|
||||||
|
[PatchFlags.BAIL]: `BAIL`
|
||||||
|
}
|
@ -1,6 +1,9 @@
|
|||||||
|
import * as t from '@babel/types'
|
||||||
import { addNamespace } from '@babel/helper-module-imports';
|
import { addNamespace } from '@babel/helper-module-imports';
|
||||||
|
import { NodePath } from '@babel/traverse';
|
||||||
|
import { State } from './';
|
||||||
|
|
||||||
const transformFragment = (t, path, Fragment) => {
|
const transformFragment = (path: NodePath<t.JSXElement>, Fragment: t.JSXMemberExpression) => {
|
||||||
const children = path.get('children') || [];
|
const children = path.get('children') || [];
|
||||||
return t.jsxElement(
|
return t.jsxElement(
|
||||||
t.jsxOpeningElement(Fragment, []),
|
t.jsxOpeningElement(Fragment, []),
|
||||||
@ -10,15 +13,15 @@ const transformFragment = (t, path, Fragment) => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default (t) => ({
|
export default () => ({
|
||||||
JSXFragment: {
|
JSXFragment: {
|
||||||
enter(path, state) {
|
enter(path: NodePath<t.JSXElement>, state: State) {
|
||||||
if (!state.get('vue')) {
|
if (!state.get('vue')) {
|
||||||
state.set('vue', addNamespace(path, 'vue'));
|
state.set('vue', addNamespace(path, 'vue'));
|
||||||
}
|
}
|
||||||
path.replaceWith(
|
path.replaceWith(
|
||||||
transformFragment(
|
transformFragment(
|
||||||
t, path,
|
path,
|
||||||
t.jsxMemberExpression(
|
t.jsxMemberExpression(
|
||||||
t.jsxIdentifier(state.get('vue').name),
|
t.jsxIdentifier(state.get('vue').name),
|
||||||
t.jsxIdentifier('Fragment'),
|
t.jsxIdentifier('Fragment'),
|
@ -1,39 +1,49 @@
|
|||||||
|
import * as t from '@babel/types';
|
||||||
|
import { NodePath } from '@babel/traverse';
|
||||||
import { addDefault, addNamespace } from '@babel/helper-module-imports';
|
import { addDefault, addNamespace } from '@babel/helper-module-imports';
|
||||||
import {
|
import {
|
||||||
createIdentifier,
|
createIdentifier,
|
||||||
PatchFlags,
|
|
||||||
PatchFlagNames,
|
|
||||||
isDirective,
|
isDirective,
|
||||||
checkIsComponent,
|
checkIsComponent,
|
||||||
|
transformJSXSpreadChild,
|
||||||
getTag,
|
getTag,
|
||||||
getJSXAttributeName,
|
getJSXAttributeName,
|
||||||
transformJSXText,
|
transformJSXText,
|
||||||
transformJSXExpressionContainer,
|
transformJSXExpressionContainer,
|
||||||
transformJSXSpreadChild,
|
|
||||||
parseDirectives,
|
parseDirectives,
|
||||||
isFragment,
|
isFragment,
|
||||||
} from './utils';
|
} from './utils';
|
||||||
|
import { PatchFlags, PatchFlagNames } from './patchFlags';
|
||||||
|
import { State, ExcludesFalse } from './';
|
||||||
|
|
||||||
const xlinkRE = /^xlink([A-Z])/;
|
const xlinkRE = /^xlink([A-Z])/;
|
||||||
const onRE = /^on[^a-z]/;
|
const onRE = /^on[^a-z]/;
|
||||||
|
|
||||||
const isOn = (key) => onRE.test(key);
|
const isOn = (key: string) => onRE.test(key);
|
||||||
|
|
||||||
const transformJSXSpreadAttribute = (t, path, mergeArgs) => {
|
const transformJSXSpreadAttribute = (
|
||||||
const argument = path.get('argument').node;
|
path: NodePath<t.JSXSpreadAttribute>,
|
||||||
const { properties } = argument;
|
mergeArgs: (t.ObjectProperty | t.Expression)[]
|
||||||
|
) => {
|
||||||
|
const argument = path.get('argument') as NodePath<t.ObjectExpression>;
|
||||||
|
const { properties } = argument.node;
|
||||||
if (!properties) {
|
if (!properties) {
|
||||||
// argument is an Identifier
|
// argument is an Identifier
|
||||||
mergeArgs.push(argument);
|
mergeArgs.push(argument.node);
|
||||||
} else {
|
} else {
|
||||||
mergeArgs.push(t.objectExpression(properties));
|
mergeArgs.push(t.objectExpression(properties));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const getJSXAttributeValue = (t, path, state) => {
|
const getJSXAttributeValue = (
|
||||||
|
path: NodePath<t.JSXAttribute>,
|
||||||
|
state: State
|
||||||
|
): (
|
||||||
|
t.StringLiteral | t.Expression | null
|
||||||
|
) => {
|
||||||
const valuePath = path.get('value');
|
const valuePath = path.get('value');
|
||||||
if (valuePath.isJSXElement()) {
|
if (valuePath.isJSXElement()) {
|
||||||
return transformJSXElement(t, valuePath, state);
|
return transformJSXElement(valuePath, state);
|
||||||
}
|
}
|
||||||
if (valuePath.isStringLiteral()) {
|
if (valuePath.isStringLiteral()) {
|
||||||
return valuePath.node;
|
return valuePath.node;
|
||||||
@ -47,46 +57,48 @@ const getJSXAttributeValue = (t, path, state) => {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if an attribute value is constant
|
* Check if an attribute value is constant
|
||||||
* @param t
|
|
||||||
* @param path
|
* @param path
|
||||||
* @returns boolean
|
* @returns boolean
|
||||||
*/
|
*/
|
||||||
const isConstant = (t, path) => {
|
const isConstant = (
|
||||||
if (t.isIdentifier(path)) {
|
node: t.Expression | t.Identifier | t.Literal | t.SpreadElement | null
|
||||||
return path.name === 'undefined';
|
): boolean => {
|
||||||
|
if (t.isIdentifier(node)) {
|
||||||
|
return node.name === 'undefined';
|
||||||
}
|
}
|
||||||
if (t.isArrayExpression(path)) {
|
if (t.isArrayExpression(node)) {
|
||||||
return path.elements.every((element) => isConstant(t, element));
|
const elements = node.elements;
|
||||||
|
return elements.every((element) => element && isConstant(element));
|
||||||
}
|
}
|
||||||
if (t.isObjectExpression(path)) {
|
if (t.isObjectExpression(node)) {
|
||||||
return path.properties.every((property) => isConstant(t, property.value));
|
return node.properties.every((property) => isConstant((property as any).value));
|
||||||
}
|
}
|
||||||
if (t.isLiteral(path)) {
|
if (t.isLiteral(node)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
const mergeAsArray = (t, existing, incoming) => {
|
const mergeAsArray = (existing: t.ObjectProperty, incoming: t.ObjectProperty) => {
|
||||||
if (t.isArrayExpression(existing.value)) {
|
if (t.isArrayExpression(existing.value)) {
|
||||||
existing.value.elements.push(incoming.value);
|
existing.value.elements.push(incoming.value as t.Expression);
|
||||||
} else {
|
} else {
|
||||||
existing.value = t.arrayExpression([
|
existing.value = t.arrayExpression([
|
||||||
existing.value,
|
existing.value as t.Expression,
|
||||||
incoming.value,
|
incoming.value as t.Expression,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const dedupeProperties = (t, properties = []) => {
|
const dedupeProperties = (properties: t.ObjectProperty[] = []) => {
|
||||||
const knownProps = new Map();
|
const knownProps = new Map<string, t.ObjectProperty>();
|
||||||
const deduped = [];
|
const deduped: t.ObjectProperty[] = [];
|
||||||
properties.forEach((prop) => {
|
properties.forEach((prop) => {
|
||||||
const { key: { value: name } = {} } = prop;
|
const { value: name } = prop.key as t.StringLiteral;
|
||||||
const existing = knownProps.get(name);
|
const existing = knownProps.get(name);
|
||||||
if (existing) {
|
if (existing) {
|
||||||
if (name === 'style' || name === 'class' || name.startsWith('on')) {
|
if (name === 'style' || name === 'class' || name.startsWith('on')) {
|
||||||
mergeAsArray(t, existing, prop);
|
mergeAsArray(existing, prop);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
knownProps.set(name, prop);
|
knownProps.set(name, prop);
|
||||||
@ -97,19 +109,17 @@ const dedupeProperties = (t, properties = []) => {
|
|||||||
return deduped;
|
return deduped;
|
||||||
};
|
};
|
||||||
|
|
||||||
const buildProps = (t, path, state, hasContainer) => {
|
const buildProps = (path: NodePath<t.JSXElement>, state: State) => {
|
||||||
const tag = getTag(t, path);
|
const tag = getTag(path, state);
|
||||||
const isComponent = checkIsComponent(t, path.get('openingElement'));
|
const isComponent = checkIsComponent(path.get('openingElement'));
|
||||||
const props = path.get('openingElement').get('attributes');
|
const props = path.get('openingElement').get('attributes');
|
||||||
const directives = [];
|
const directives: t.ArrayExpression[] = [];
|
||||||
const dynamicPropNames = new Set();
|
const dynamicPropNames = new Set();
|
||||||
|
|
||||||
let patchFlag = 0;
|
let patchFlag = 0;
|
||||||
|
|
||||||
if (isFragment(t, path.get('openingElement.name'))) {
|
if (isFragment(path.get('openingElement').get('name'))) {
|
||||||
patchFlag |= PatchFlags.STABLE_FRAGMENT;
|
patchFlag |= PatchFlags.STABLE_FRAGMENT;
|
||||||
} else if (hasContainer) {
|
|
||||||
patchFlag |= PatchFlags.BAIL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (props.length === 0) {
|
if (props.length === 0) {
|
||||||
@ -122,7 +132,7 @@ const buildProps = (t, path, state, hasContainer) => {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const properties = [];
|
const properties: t.ObjectProperty[] = [];
|
||||||
|
|
||||||
// patchFlag analysis
|
// patchFlag analysis
|
||||||
let hasRef = false;
|
let hasRef = false;
|
||||||
@ -131,16 +141,15 @@ const buildProps = (t, path, state, hasContainer) => {
|
|||||||
let hasHydrationEventBinding = false;
|
let hasHydrationEventBinding = false;
|
||||||
let hasDynamicKeys = false;
|
let hasDynamicKeys = false;
|
||||||
|
|
||||||
const mergeArgs = [];
|
const mergeArgs: (t.CallExpression | t.ObjectProperty | t.Identifier)[] = [];
|
||||||
|
|
||||||
props
|
props
|
||||||
.forEach((prop) => {
|
.forEach((prop) => {
|
||||||
if (prop.isJSXAttribute()) {
|
if (prop.isJSXAttribute()) {
|
||||||
let name = getJSXAttributeName(t, prop);
|
let name = getJSXAttributeName(prop);
|
||||||
|
|
||||||
const attributeValue = getJSXAttributeValue(t, prop);
|
const attributeValue = getJSXAttributeValue(prop, state);
|
||||||
|
|
||||||
if (!isConstant(t, attributeValue) || name === 'ref') {
|
if (!isConstant(attributeValue) || name === 'ref') {
|
||||||
if (
|
if (
|
||||||
!isComponent
|
!isComponent
|
||||||
&& isOn(name)
|
&& isOn(name)
|
||||||
@ -182,16 +191,14 @@ const buildProps = (t, path, state, hasContainer) => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (isDirective(name)) {
|
if (isDirective(name)) {
|
||||||
const { directive, modifiers, directiveName } = parseDirectives(
|
const { directive, modifiers, directiveName } = parseDirectives({
|
||||||
t, {
|
tag,
|
||||||
tag,
|
isComponent,
|
||||||
isComponent,
|
name,
|
||||||
name,
|
path: prop,
|
||||||
path: prop,
|
state,
|
||||||
state,
|
value: attributeValue,
|
||||||
value: attributeValue,
|
});
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
if (directive) {
|
if (directive) {
|
||||||
directives.push(t.arrayExpression(directive));
|
directives.push(t.arrayExpression(directive));
|
||||||
@ -199,6 +206,7 @@ const buildProps = (t, path, state, hasContainer) => {
|
|||||||
// must be v-model and is a component
|
// must be v-model and is a component
|
||||||
properties.push(t.objectProperty(
|
properties.push(t.objectProperty(
|
||||||
t.stringLiteral('modelValue'),
|
t.stringLiteral('modelValue'),
|
||||||
|
// @ts-ignore
|
||||||
attributeValue,
|
attributeValue,
|
||||||
));
|
));
|
||||||
|
|
||||||
@ -219,11 +227,12 @@ const buildProps = (t, path, state, hasContainer) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (directiveName === 'model') {
|
if (directiveName === 'model' && attributeValue) {
|
||||||
properties.push(t.objectProperty(
|
properties.push(t.objectProperty(
|
||||||
t.stringLiteral('onUpdate:modelValue'),
|
t.stringLiteral('onUpdate:modelValue'),
|
||||||
t.arrowFunctionExpression(
|
t.arrowFunctionExpression(
|
||||||
[t.identifier('$event')],
|
[t.identifier('$event')],
|
||||||
|
// @ts-ignore
|
||||||
t.assignmentExpression('=', attributeValue, t.identifier('$event')),
|
t.assignmentExpression('=', attributeValue, t.identifier('$event')),
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
@ -240,8 +249,9 @@ const buildProps = (t, path, state, hasContainer) => {
|
|||||||
attributeValue || t.booleanLiteral(true),
|
attributeValue || t.booleanLiteral(true),
|
||||||
));
|
));
|
||||||
} else {
|
} else {
|
||||||
|
// JSXSpreadAttribute
|
||||||
hasDynamicKeys = true;
|
hasDynamicKeys = true;
|
||||||
transformJSXSpreadAttribute(t, prop, mergeArgs);
|
transformJSXSpreadAttribute(prop as NodePath<t.JSXSpreadAttribute>, mergeArgs);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -270,15 +280,15 @@ const buildProps = (t, path, state, hasContainer) => {
|
|||||||
patchFlag |= PatchFlags.NEED_PATCH;
|
patchFlag |= PatchFlags.NEED_PATCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
let propsExpression = t.nullLiteral();
|
let propsExpression: t.Expression | t.ObjectProperty | t.Literal = t.nullLiteral();
|
||||||
|
|
||||||
if (mergeArgs.length) {
|
if (mergeArgs.length) {
|
||||||
if (properties.length) {
|
if (properties.length) {
|
||||||
mergeArgs.push(...dedupeProperties(t, properties));
|
mergeArgs.push(...dedupeProperties(properties));
|
||||||
}
|
}
|
||||||
if (mergeArgs.length > 1) {
|
if (mergeArgs.length > 1) {
|
||||||
const exps = [];
|
const exps: (t.CallExpression | t.Identifier)[] = [];
|
||||||
const objectProperties = [];
|
const objectProperties: t.ObjectProperty[] = [];
|
||||||
mergeArgs.forEach((arg) => {
|
mergeArgs.forEach((arg) => {
|
||||||
if (t.isIdentifier(arg) || t.isExpression(arg)) {
|
if (t.isIdentifier(arg) || t.isExpression(arg)) {
|
||||||
exps.push(arg);
|
exps.push(arg);
|
||||||
@ -287,20 +297,18 @@ const buildProps = (t, path, state, hasContainer) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
propsExpression = t.callExpression(
|
propsExpression = t.callExpression(
|
||||||
createIdentifier(t, state, 'mergeProps'),
|
createIdentifier(state, 'mergeProps'),
|
||||||
[
|
[
|
||||||
...exps,
|
...exps,
|
||||||
objectProperties.length
|
!!objectProperties.length && t.objectExpression(objectProperties),
|
||||||
&& t.objectExpression(objectProperties),
|
].filter(Boolean as any as ExcludesFalse),
|
||||||
].filter(Boolean),
|
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
// single no need for a mergeProps call
|
// single no need for a mergeProps call
|
||||||
// eslint-disable-next-line prefer-destructuring
|
|
||||||
propsExpression = mergeArgs[0];
|
propsExpression = mergeArgs[0];
|
||||||
}
|
}
|
||||||
} else if (properties.length) {
|
} else if (properties.length) {
|
||||||
propsExpression = t.objectExpression(dedupeProperties(t, properties));
|
propsExpression = t.objectExpression(dedupeProperties(properties));
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@ -314,50 +322,59 @@ const buildProps = (t, path, state, hasContainer) => {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Get children from Array of JSX children
|
* Get children from Array of JSX children
|
||||||
* @param t
|
* @param paths Array<JSXText | JSXExpressionContainer | JSXElement | JSXFragment>
|
||||||
* @param paths Array<JSXText | JSXExpressionContainer | JSXSpreadChild | JSXElement>
|
|
||||||
* @returns Array<Expression | SpreadElement>
|
* @returns Array<Expression | SpreadElement>
|
||||||
*/
|
*/
|
||||||
const getChildren = (t, paths, state) => {
|
const getChildren = (
|
||||||
let hasContainer = false;
|
paths: NodePath<
|
||||||
return {
|
t.JSXText
|
||||||
children: paths
|
| t.JSXExpressionContainer
|
||||||
.map((path) => {
|
| t.JSXSpreadChild
|
||||||
if (path.isJSXText()) {
|
| t.JSXElement
|
||||||
return transformJSXText(t, path);
|
| t.JSXFragment
|
||||||
|
>[],
|
||||||
|
state: State
|
||||||
|
): t.Expression[] =>
|
||||||
|
paths
|
||||||
|
.map((path) => {
|
||||||
|
if (path.isJSXText()) {
|
||||||
|
const transformedText = transformJSXText(path);
|
||||||
|
if (transformedText) {
|
||||||
|
return t.callExpression(createIdentifier(state, 'createTextVNode'), [transformedText]);
|
||||||
}
|
}
|
||||||
if (path.isJSXExpressionContainer()) {
|
return transformedText;
|
||||||
hasContainer = true;
|
}
|
||||||
return transformJSXExpressionContainer(path);
|
if (path.isJSXExpressionContainer()) {
|
||||||
}
|
return transformJSXExpressionContainer(path);
|
||||||
if (path.isJSXSpreadChild()) {
|
}
|
||||||
return transformJSXSpreadChild(t, path);
|
if (t.isJSXSpreadChild(path)) {
|
||||||
}
|
return transformJSXSpreadChild(path as NodePath<t.JSXSpreadChild>);
|
||||||
if (path.isCallExpression()) {
|
}
|
||||||
return path.node;
|
if (path.isCallExpression()) {
|
||||||
}
|
return path.node;
|
||||||
if (path.isJSXElement()) {
|
}
|
||||||
return transformJSXElement(t, path, state);
|
if (path.isJSXElement()) {
|
||||||
}
|
return transformJSXElement(path, state);
|
||||||
throw new Error(`getChildren: ${path.type} is not supported`);
|
}
|
||||||
}).filter((value) => (
|
throw new Error(`getChildren: ${path.type} is not supported`);
|
||||||
value !== undefined
|
}).filter(((value: any) => (
|
||||||
|
value !== undefined
|
||||||
&& value !== null
|
&& value !== null
|
||||||
&& !t.isJSXEmptyExpression(value)
|
&& !t.isJSXEmptyExpression(value)
|
||||||
)),
|
)) as any);
|
||||||
hasContainer,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
const transformJSXElement = (t, path, state) => {
|
const transformJSXElement = (
|
||||||
const { children, hasContainer } = getChildren(t, path.get('children'), state);
|
path: NodePath<t.JSXElement>,
|
||||||
|
state: State
|
||||||
|
): t.CallExpression => {
|
||||||
|
const children = getChildren(path.get('children'), state);
|
||||||
const {
|
const {
|
||||||
tag,
|
tag,
|
||||||
props,
|
props,
|
||||||
directives,
|
directives,
|
||||||
patchFlag,
|
patchFlag,
|
||||||
dynamicPropNames,
|
dynamicPropNames,
|
||||||
} = buildProps(t, path, state, hasContainer);
|
} = buildProps(path, state);
|
||||||
|
|
||||||
const flagNames = Object.keys(PatchFlagNames)
|
const flagNames = Object.keys(PatchFlagNames)
|
||||||
.map(Number)
|
.map(Number)
|
||||||
@ -365,10 +382,6 @@ const transformJSXElement = (t, path, state) => {
|
|||||||
.map((n) => PatchFlagNames[n])
|
.map((n) => PatchFlagNames[n])
|
||||||
.join(', ');
|
.join(', ');
|
||||||
|
|
||||||
const isComponent = checkIsComponent(t, path.get('openingElement'));
|
|
||||||
const child = children.length === 1 && t.isStringLiteral(children[0])
|
|
||||||
? children[0] : t.arrayExpression(children);
|
|
||||||
|
|
||||||
const { compatibleProps } = state.opts;
|
const { compatibleProps } = state.opts;
|
||||||
if (compatibleProps && !state.get('compatibleProps')) {
|
if (compatibleProps && !state.get('compatibleProps')) {
|
||||||
state.set('compatibleProps', addDefault(
|
state.set('compatibleProps', addDefault(
|
||||||
@ -376,53 +389,35 @@ const transformJSXElement = (t, path, state) => {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
const createVNode = t.callExpression(createIdentifier(t, state, 'createVNode'), [
|
// @ts-ignore
|
||||||
|
const createVNode = t.callExpression(createIdentifier(state, 'createVNode'), [
|
||||||
tag,
|
tag,
|
||||||
|
// @ts-ignore
|
||||||
compatibleProps ? t.callExpression(state.get('compatibleProps'), [props]) : props,
|
compatibleProps ? t.callExpression(state.get('compatibleProps'), [props]) : props,
|
||||||
children[0]
|
!!children.length ? t.arrayExpression(children) : t.nullLiteral(),
|
||||||
? (
|
!!patchFlag && t.addComment(t.numericLiteral(patchFlag), 'trailing', ` ${flagNames} `, false),
|
||||||
isComponent
|
!!dynamicPropNames.size
|
||||||
? t.objectExpression([
|
&& t.arrayExpression([...dynamicPropNames.keys()].map((name) => t.stringLiteral(name as string))),
|
||||||
t.objectProperty(
|
].filter(Boolean as any as ExcludesFalse));
|
||||||
t.identifier('default'),
|
|
||||||
t.callExpression(createIdentifier(t, state, 'withCtx'), [
|
|
||||||
t.arrowFunctionExpression(
|
|
||||||
[],
|
|
||||||
t.isStringLiteral(child)
|
|
||||||
? t.callExpression(
|
|
||||||
createIdentifier(t, state, 'createTextVNode'),
|
|
||||||
[child],
|
|
||||||
)
|
|
||||||
: child,
|
|
||||||
),
|
|
||||||
]),
|
|
||||||
),
|
|
||||||
])
|
|
||||||
: child
|
|
||||||
) : t.nullLiteral(),
|
|
||||||
patchFlag && t.addComment(t.numericLiteral(patchFlag), 'trailing', ` ${flagNames} `, false),
|
|
||||||
dynamicPropNames.size
|
|
||||||
&& t.arrayExpression([...dynamicPropNames.keys()].map((name) => t.stringLiteral(name))),
|
|
||||||
].filter(Boolean));
|
|
||||||
|
|
||||||
if (!directives.length) {
|
if (!directives.length) {
|
||||||
return createVNode;
|
return createVNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
return t.callExpression(createIdentifier(t, state, 'withDirectives'), [
|
return t.callExpression(createIdentifier(state, 'withDirectives'), [
|
||||||
createVNode,
|
createVNode,
|
||||||
t.arrayExpression(directives),
|
t.arrayExpression(directives),
|
||||||
]);
|
]);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default (t) => ({
|
export default () => ({
|
||||||
JSXElement: {
|
JSXElement: {
|
||||||
exit(path, state) {
|
exit(path: NodePath<t.JSXElement>, state: State) {
|
||||||
if (!state.get('vue')) {
|
if (!state.get('vue')) {
|
||||||
state.set('vue', addNamespace(path, 'vue'));
|
state.set('vue', addNamespace(path, 'vue'));
|
||||||
}
|
}
|
||||||
path.replaceWith(
|
path.replaceWith(
|
||||||
transformJSXElement(t, path, state),
|
transformJSXElement(path, state),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
},
|
},
|
@ -1,119 +1,97 @@
|
|||||||
|
import * as t from '@babel/types';
|
||||||
import htmlTags from 'html-tags';
|
import htmlTags from 'html-tags';
|
||||||
import svgTags from 'svg-tags';
|
import svgTags from 'svg-tags';
|
||||||
|
import { NodePath } from '@babel/traverse';
|
||||||
|
import { State, ExcludesFalse } from './';
|
||||||
|
|
||||||
const PatchFlags = {
|
/**
|
||||||
TEXT: 1,
|
* create Identifier
|
||||||
CLASS: 1 << 1,
|
* @param state
|
||||||
STYLE: 1 << 2,
|
* @param id string
|
||||||
PROPS: 1 << 3,
|
* @returns MemberExpression
|
||||||
FULL_PROPS: 1 << 4,
|
*/
|
||||||
HYDRATE_EVENTS: 1 << 5,
|
const createIdentifier = (
|
||||||
STABLE_FRAGMENT: 1 << 6,
|
state: State, id: string
|
||||||
KEYED_FRAGMENT: 1 << 7,
|
): t.MemberExpression => t.memberExpression(state.get('vue'), t.identifier(id));
|
||||||
UNKEYED_FRAGMENT: 1 << 8,
|
|
||||||
NEED_PATCH: 1 << 9,
|
|
||||||
DYNAMIC_SLOTS: 1 << 10,
|
|
||||||
HOISTED: -1,
|
|
||||||
BAIL: -2,
|
|
||||||
};
|
|
||||||
|
|
||||||
// dev only flag -> name mapping
|
|
||||||
const PatchFlagNames = {
|
|
||||||
[PatchFlags.TEXT]: 'TEXT',
|
|
||||||
[PatchFlags.CLASS]: 'CLASS',
|
|
||||||
[PatchFlags.STYLE]: 'STYLE',
|
|
||||||
[PatchFlags.PROPS]: 'PROPS',
|
|
||||||
[PatchFlags.FULL_PROPS]: 'FULL_PROPS',
|
|
||||||
[PatchFlags.HYDRATE_EVENTS]: 'HYDRATE_EVENTS',
|
|
||||||
[PatchFlags.STABLE_FRAGMENT]: 'STABLE_FRAGMENT',
|
|
||||||
[PatchFlags.KEYED_FRAGMENT]: 'KEYED_FRAGMENT',
|
|
||||||
[PatchFlags.UNKEYED_FRAGMENT]: 'UNKEYED_FRAGMENT',
|
|
||||||
[PatchFlags.NEED_PATCH]: 'NEED_PATCH',
|
|
||||||
[PatchFlags.DYNAMIC_SLOTS]: 'DYNAMIC_SLOTS',
|
|
||||||
[PatchFlags.HOISTED]: 'HOISTED',
|
|
||||||
[PatchFlags.BAIL]: 'BAIL',
|
|
||||||
};
|
|
||||||
|
|
||||||
const createIdentifier = (t, state, id) => t.memberExpression(state.get('vue'), t.identifier(id));
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if string is describing a directive
|
* Checks if string is describing a directive
|
||||||
* @param src string
|
* @param src string
|
||||||
*/
|
*/
|
||||||
const isDirective = (src) => src.startsWith('v-')
|
const isDirective = (src: string): boolean => src.startsWith('v-')
|
||||||
|| (src.startsWith('v') && src.length >= 2 && src[1] >= 'A' && src[1] <= 'Z');
|
|| (src.startsWith('v') && src.length >= 2 && src[1] >= 'A' && src[1] <= 'Z');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if a JSXOpeningElement is fragment
|
* Check if a Node is fragment
|
||||||
* @param {*} t
|
* @param {*} path JSXIdentifier | JSXMemberExpression | JSXNamespacedName
|
||||||
* @param {*} path
|
|
||||||
* @returns boolean
|
* @returns boolean
|
||||||
*/
|
*/
|
||||||
const isFragment = (t, path) => t.isJSXMemberExpression(path)
|
const isFragment = (path: NodePath<t.JSXIdentifier | t.JSXMemberExpression | t.JSXNamespacedName>) =>
|
||||||
&& path.node.property.name === 'Fragment';
|
t.isJSXMemberExpression(path)
|
||||||
|
&& (path.node as t.JSXMemberExpression).property.name === 'Fragment';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if a JSXOpeningElement is a component
|
* Check if a Node is a component
|
||||||
*
|
*
|
||||||
* @param t
|
* @param t
|
||||||
* @param path JSXOpeningElement
|
* @param path JSXOpeningElement
|
||||||
* @returns boolean
|
* @returns boolean
|
||||||
*/
|
*/
|
||||||
const checkIsComponent = (t, path) => {
|
const checkIsComponent = (path: NodePath<t.JSXOpeningElement>): boolean => {
|
||||||
const namePath = path.get('name');
|
const namePath = path.get('name');
|
||||||
|
|
||||||
if (t.isJSXMemberExpression(namePath)) {
|
if (t.isJSXMemberExpression(namePath)) {
|
||||||
return !isFragment(t, namePath); // For withCtx
|
return !isFragment(namePath); // For withCtx
|
||||||
}
|
}
|
||||||
|
|
||||||
const tag = namePath.get('name').node;
|
const tag = (namePath as NodePath<t.JSXIdentifier>).get('name');
|
||||||
|
|
||||||
return !htmlTags.includes(tag) && !svgTags.includes(tag);
|
return !htmlTags.includes(tag) && !svgTags.includes(tag);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Transform JSXMemberExpression to MemberExpression
|
* Transform JSXMemberExpression to MemberExpression
|
||||||
* @param t
|
|
||||||
* @param path JSXMemberExpression
|
* @param path JSXMemberExpression
|
||||||
* @returns MemberExpression
|
* @returns MemberExpression
|
||||||
*/
|
*/
|
||||||
const transformJSXMemberExpression = (t, path) => {
|
const transformJSXMemberExpression = (path: NodePath<t.JSXMemberExpression>): t.MemberExpression => {
|
||||||
const objectPath = path.get('object');
|
const objectPath = path.node.object;
|
||||||
const propertyPath = path.get('property');
|
const propertyPath = path.node.property;
|
||||||
|
const transformedObject = t.isJSXMemberExpression(objectPath)
|
||||||
const transformedObject = objectPath.isJSXMemberExpression()
|
? transformJSXMemberExpression(path.get('object') as NodePath<t.JSXMemberExpression>)
|
||||||
? transformJSXMemberExpression(t, objectPath)
|
: t.isJSXIdentifier(objectPath)
|
||||||
: objectPath.isJSXIdentifier()
|
? t.identifier(objectPath.name)
|
||||||
? t.identifier(objectPath.node.name)
|
|
||||||
: t.nullLiteral();
|
: t.nullLiteral();
|
||||||
const transformedProperty = t.identifier(propertyPath.get('name').node);
|
const transformedProperty = t.identifier(propertyPath.name);
|
||||||
return t.memberExpression(transformedObject, transformedProperty);
|
return t.memberExpression(transformedObject, transformedProperty);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get tag (first attribute for h) from JSXOpeningElement
|
* Get tag (first attribute for h) from JSXOpeningElement
|
||||||
* @param t
|
* @param path JSXElement
|
||||||
* @param path JSXOpeningElement
|
* @param state State
|
||||||
* @returns Identifier | StringLiteral | MemberExpression
|
* @returns Identifier | StringLiteral | MemberExpression
|
||||||
*/
|
*/
|
||||||
const getTag = (t, path) => {
|
const getTag = (path: NodePath<t.JSXElement>, state: State) => {
|
||||||
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;
|
||||||
if (path.scope.hasBinding(name) && !htmlTags.includes(name) && !svgTags.includes(name)) {
|
if (!htmlTags.includes(name) && !svgTags.includes(name)) {
|
||||||
return t.identifier(name);
|
return path.scope.hasBinding(name)
|
||||||
|
? t.identifier(name)
|
||||||
|
: t.callExpression(createIdentifier(state, 'resolveComponent'), [t.stringLiteral(name)]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return t.stringLiteral(name);
|
return t.stringLiteral(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (namePath.isJSXMemberExpression()) {
|
if (namePath.isJSXMemberExpression()) {
|
||||||
return transformJSXMemberExpression(t, namePath);
|
return transformJSXMemberExpression(namePath);
|
||||||
}
|
}
|
||||||
throw new Error(`getTag: ${namePath.type} is not supported`);
|
throw new Error(`getTag: ${namePath.type} is not supported`);
|
||||||
};
|
};
|
||||||
|
|
||||||
const getJSXAttributeName = (t, path) => {
|
const getJSXAttributeName = (path: NodePath<t.JSXAttribute>): string => {
|
||||||
const nameNode = path.node.name;
|
const nameNode = path.node.name;
|
||||||
if (t.isJSXIdentifier(nameNode)) {
|
if (t.isJSXIdentifier(nameNode)) {
|
||||||
return nameNode.name;
|
return nameNode.name;
|
||||||
@ -124,11 +102,10 @@ const getJSXAttributeName = (t, path) => {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Transform JSXText to StringLiteral
|
* Transform JSXText to StringLiteral
|
||||||
* @param t
|
|
||||||
* @param path JSXText
|
* @param path JSXText
|
||||||
* @returns StringLiteral
|
* @returns StringLiteral | null
|
||||||
*/
|
*/
|
||||||
const transformJSXText = (t, path) => {
|
const transformJSXText = (path: NodePath<t.JSXText>): t.StringLiteral | null => {
|
||||||
const { node } = path;
|
const { node } = path;
|
||||||
const lines = node.value.split(/\r\n|\n|\r/);
|
const lines = node.value.split(/\r\n|\n|\r/);
|
||||||
|
|
||||||
@ -179,64 +156,69 @@ const transformJSXText = (t, path) => {
|
|||||||
* @param path JSXExpressionContainer
|
* @param path JSXExpressionContainer
|
||||||
* @returns Expression
|
* @returns Expression
|
||||||
*/
|
*/
|
||||||
const transformJSXExpressionContainer = (path) => path.get('expression').node;
|
const transformJSXExpressionContainer = (
|
||||||
|
path: NodePath<t.JSXExpressionContainer>
|
||||||
|
): (t.Expression) => path.get('expression').node as t.Expression;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Transform JSXSpreadChild
|
* Transform JSXSpreadChild
|
||||||
* @param t
|
|
||||||
* @param path JSXSpreadChild
|
* @param path JSXSpreadChild
|
||||||
* @returns SpreadElement
|
* @returns SpreadElement
|
||||||
*/
|
*/
|
||||||
const transformJSXSpreadChild = (t, path) => t.spreadElement(path.get('expression').node);
|
const transformJSXSpreadChild = (
|
||||||
|
path: NodePath<t.JSXSpreadChild>
|
||||||
|
): t.SpreadElement => t.spreadElement(path.get('expression').node);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get JSX element type
|
* Get JSX element type
|
||||||
*
|
*
|
||||||
* @param t
|
|
||||||
* @param path Path<JSXOpeningElement>
|
* @param path Path<JSXOpeningElement>
|
||||||
*/
|
*/
|
||||||
const getType = (t, path) => {
|
const getType = (path: NodePath<t.JSXOpeningElement>) => {
|
||||||
const typePath = path
|
const typePath = path
|
||||||
.get('attributes')
|
.get('attributes')
|
||||||
.find(
|
.find((attribute) => {
|
||||||
(attributePath) => t.isJSXAttribute(attributePath)
|
if (!t.isJSXAttribute(attribute)) {
|
||||||
&& t.isJSXIdentifier(attributePath.get('name'))
|
return false;
|
||||||
&& attributePath.get('name.name').node === 'type'
|
}
|
||||||
&& t.isStringLiteral(attributePath.get('value')),
|
return t.isJSXIdentifier(attribute.get('name'))
|
||||||
|
&& (attribute.get('name') as NodePath<t.JSXIdentifier>).get('name') === 'type'
|
||||||
|
&& t.isStringLiteral(attribute.get('value'))
|
||||||
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
return typePath ? typePath.get('value.value').node : '';
|
return typePath ? typePath.get('value.value') : '';
|
||||||
};
|
};
|
||||||
|
|
||||||
const resolveDirective = (t, path, state, tag, directiveName) => {
|
const resolveDirective = (path: NodePath<t.JSXAttribute>, state: State, tag: any, directiveName: string) => {
|
||||||
if (directiveName === 'show') {
|
if (directiveName === 'show') {
|
||||||
return createIdentifier(t, state, 'vShow');
|
return createIdentifier(state, 'vShow');
|
||||||
} if (directiveName === 'model') {
|
} if (directiveName === 'model') {
|
||||||
let modelToUse;
|
let modelToUse;
|
||||||
const type = getType(t, path.parentPath);
|
const type = getType(path.parentPath as NodePath<t.JSXOpeningElement>);
|
||||||
switch (tag.value) {
|
switch (tag.value) {
|
||||||
case 'select':
|
case 'select':
|
||||||
modelToUse = createIdentifier(t, state, 'vModelSelect');
|
modelToUse = createIdentifier(state, 'vModelSelect');
|
||||||
break;
|
break;
|
||||||
case 'textarea':
|
case 'textarea':
|
||||||
modelToUse = createIdentifier(t, state, 'vModelText');
|
modelToUse = createIdentifier(state, 'vModelText');
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 'checkbox':
|
case 'checkbox':
|
||||||
modelToUse = createIdentifier(t, state, 'vModelCheckbox');
|
modelToUse = createIdentifier(state, 'vModelCheckbox');
|
||||||
break;
|
break;
|
||||||
case 'radio':
|
case 'radio':
|
||||||
modelToUse = createIdentifier(t, state, 'vModelRadio');
|
modelToUse = createIdentifier(state, 'vModelRadio');
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
modelToUse = createIdentifier(t, state, 'vModelText');
|
modelToUse = createIdentifier(state, 'vModelText');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return modelToUse;
|
return modelToUse;
|
||||||
}
|
}
|
||||||
return t.callExpression(
|
return t.callExpression(
|
||||||
createIdentifier(t, state, 'resolveDirective'), [
|
createIdentifier(state, 'resolveDirective'), [
|
||||||
t.stringLiteral(directiveName),
|
t.stringLiteral(directiveName),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
@ -245,18 +227,25 @@ const resolveDirective = (t, path, state, tag, directiveName) => {
|
|||||||
/**
|
/**
|
||||||
* Parse directives metadata
|
* Parse directives 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 parseDirectives = (t, {
|
const parseDirectives = (args: {
|
||||||
name, path, value, state, tag, isComponent,
|
name: string,
|
||||||
|
path: NodePath<t.JSXAttribute>,
|
||||||
|
value: t.StringLiteral | t.Expression | null,
|
||||||
|
state: State,
|
||||||
|
tag: t.Identifier | t.MemberExpression | t.StringLiteral | t.CallExpression,
|
||||||
|
isComponent: boolean
|
||||||
}) => {
|
}) => {
|
||||||
const modifiers = name.split('_');
|
const {
|
||||||
const directiveName = modifiers.shift()
|
name, path, value, state, tag, isComponent,
|
||||||
.replace(/^v/, '')
|
} = args
|
||||||
|
const modifiers: string[] = name.split('_');
|
||||||
|
const directiveName: string = modifiers.shift()
|
||||||
|
?.replace(/^v/, '')
|
||||||
.replace(/^-/, '')
|
.replace(/^-/, '')
|
||||||
.replace(/^\S/, (s) => s.toLowerCase());
|
.replace(/^\S/, (s: string) => s.toLowerCase()) || '';
|
||||||
|
|
||||||
if (directiveName === 'model' && !t.isJSXExpressionContainer(path.get('value'))) {
|
if (directiveName === 'model' && !t.isJSXExpressionContainer(path.get('value'))) {
|
||||||
throw new Error('You have to use JSX Expression inside your v-model');
|
throw new Error('You have to use JSX Expression inside your v-model');
|
||||||
@ -270,10 +259,10 @@ const parseDirectives = (t, {
|
|||||||
directiveName,
|
directiveName,
|
||||||
modifiers: modifiersSet,
|
modifiers: modifiersSet,
|
||||||
directive: hasDirective ? [
|
directive: hasDirective ? [
|
||||||
resolveDirective(t, path, state, tag, directiveName),
|
resolveDirective(path, state, tag, directiveName),
|
||||||
value,
|
value,
|
||||||
modifiersSet.size && t.unaryExpression('void', t.numericLiteral(0), true),
|
!!modifiersSet.size && t.unaryExpression('void', t.numericLiteral(0), true),
|
||||||
modifiersSet.size && t.objectExpression(
|
!!modifiersSet.size && t.objectExpression(
|
||||||
[...modifiersSet].map(
|
[...modifiersSet].map(
|
||||||
(modifier) => t.objectProperty(
|
(modifier) => t.objectProperty(
|
||||||
t.identifier(modifier),
|
t.identifier(modifier),
|
||||||
@ -281,7 +270,7 @@ const parseDirectives = (t, {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
].filter(Boolean) : undefined,
|
].filter(Boolean as any as ExcludesFalse) : undefined,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -295,8 +284,6 @@ export {
|
|||||||
transformJSXText,
|
transformJSXText,
|
||||||
transformJSXSpreadChild,
|
transformJSXSpreadChild,
|
||||||
transformJSXExpressionContainer,
|
transformJSXExpressionContainer,
|
||||||
PatchFlags,
|
|
||||||
PatchFlagNames,
|
|
||||||
parseDirectives,
|
parseDirectives,
|
||||||
isFragment,
|
isFragment,
|
||||||
};
|
};
|
@ -3,6 +3,7 @@ import { shallowMount, mount } from '@vue/test-utils';
|
|||||||
|
|
||||||
const patchFlagExpect = (wrapper, flag, dynamic) => {
|
const patchFlagExpect = (wrapper, flag, dynamic) => {
|
||||||
const { patchFlag, dynamicProps } = wrapper.vm.$.subTree;
|
const { patchFlag, dynamicProps } = wrapper.vm.$.subTree;
|
||||||
|
|
||||||
expect(patchFlag).toBe(flag);
|
expect(patchFlag).toBe(flag);
|
||||||
expect(dynamicProps).toEqual(dynamic);
|
expect(dynamicProps).toEqual(dynamic);
|
||||||
};
|
};
|
||||||
|
13
packages/babel-plugin-jsx/tsconfig.json
Normal file
13
packages/babel-plugin-jsx/tsconfig.json
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"extends": "../../tsconfig.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"rootDirs": ["./src"],
|
||||||
|
"outDir": "dist",
|
||||||
|
"downlevelIteration": true
|
||||||
|
},
|
||||||
|
"include": [
|
||||||
|
"src/**/*",
|
||||||
|
"global.d.ts"
|
||||||
|
],
|
||||||
|
"exclude": ["node_modules"]
|
||||||
|
}
|
@ -8,12 +8,13 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@ant-design-vue/babel-plugin-jsx": "^1.0.0-alpha.6",
|
"@ant-design-vue/babel-plugin-jsx": "^1.0.0-alpha.6",
|
||||||
"@babel/core": "^7.0.0",
|
"@babel/core": "^7.0.0",
|
||||||
"babel-loader": "^8.1.0",
|
|
||||||
"css-loader": "^3.5.3",
|
"css-loader": "^3.5.3",
|
||||||
"file-loader": "^6.0.0",
|
"file-loader": "^6.0.0",
|
||||||
"html-webpack-plugin": "^4.3.0",
|
"html-webpack-plugin": "^4.3.0",
|
||||||
"monaco-editor-webpack-plugin": "^1.9.0",
|
"monaco-editor-webpack-plugin": "^1.9.0",
|
||||||
"style-loader": "^1.2.1",
|
"style-loader": "^1.2.1",
|
||||||
|
"ts-loader": "^8.0.0",
|
||||||
|
"typescript": "^3.9.6",
|
||||||
"url-loader": "^4.1.0",
|
"url-loader": "^4.1.0",
|
||||||
"vue": "3.0.0-beta.20",
|
"vue": "3.0.0-beta.20",
|
||||||
"webpack": "^4.43.0",
|
"webpack": "^4.43.0",
|
||||||
|
@ -12,13 +12,15 @@ createApp(
|
|||||||
() => h('h1', null, 'Vue JSX Explorer'),
|
() => h('h1', null, 'Vue JSX Explorer'),
|
||||||
).mount('#header');
|
).mount('#header');
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
if (module.hot) {
|
if (module.hot) {
|
||||||
|
// @ts-ignore
|
||||||
module.hot.accept('../../babel-plugin-jsx/src', () => {
|
module.hot.accept('../../babel-plugin-jsx/src', () => {
|
||||||
compile();
|
compile();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const sharedEditorOptions = {
|
const sharedEditorOptions: monaco.editor.IStandaloneEditorConstructionOptions = {
|
||||||
theme: 'vs-dark',
|
theme: 'vs-dark',
|
||||||
fontSize: 14,
|
fontSize: 14,
|
||||||
wordWrap: 'on',
|
wordWrap: 'on',
|
||||||
@ -39,14 +41,14 @@ monaco.languages.typescript.typescriptDefaults.setCompilerOptions({
|
|||||||
typeRoots: ['node_modules/@types'],
|
typeRoots: ['node_modules/@types'],
|
||||||
});
|
});
|
||||||
|
|
||||||
const editor = monaco.editor.create(document.getElementById('source'), {
|
const editor = monaco.editor.create(document.getElementById('source')!, {
|
||||||
value: decodeURIComponent(window.location.hash.slice(1)) || localStorage.getItem('state') || 'const App = () => <div>Hello World</div>',
|
value: decodeURIComponent(window.location.hash.slice(1)) || localStorage.getItem('state') || 'const App = () => <div>Hello World</div>',
|
||||||
language: 'javascript',
|
language: 'javascript',
|
||||||
tabSize: 2,
|
tabSize: 2,
|
||||||
...sharedEditorOptions,
|
...sharedEditorOptions,
|
||||||
});
|
});
|
||||||
|
|
||||||
const output = monaco.editor.create(document.getElementById('output'), {
|
const output = monaco.editor.create(document.getElementById('output')!, {
|
||||||
value: '',
|
value: '',
|
||||||
language: 'javascript',
|
language: 'javascript',
|
||||||
readOnly: true,
|
readOnly: true,
|
||||||
@ -63,12 +65,13 @@ const compile = () => {
|
|||||||
babelrc: false,
|
babelrc: false,
|
||||||
plugins: [[babelPluginJSx, { transformOn: true }]],
|
plugins: [[babelPluginJSx, { transformOn: true }]],
|
||||||
ast: true,
|
ast: true,
|
||||||
}, (err, result) => {
|
}, (err, result = {}) => {
|
||||||
|
const res = result!;
|
||||||
if (!err) {
|
if (!err) {
|
||||||
console.log('AST', result.ast);
|
console.log('AST', res.ast!);
|
||||||
output.setValue(result.code);
|
output.setValue(res.code!);
|
||||||
} else {
|
} else {
|
||||||
output.setValue(err.message);
|
output.setValue(err.message!);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@ -84,15 +87,18 @@ compile();
|
|||||||
// update compile output when input changes
|
// update compile output when input changes
|
||||||
editor.onDidChangeModelContent(debounce(compile));
|
editor.onDidChangeModelContent(debounce(compile));
|
||||||
|
|
||||||
function debounce(fn, delay = 300) {
|
function debounce<T extends (...args: any[]) => any>(
|
||||||
let prevTimer = null;
|
fn: T,
|
||||||
return ((...args) => {
|
delay: number = 300
|
||||||
|
): T {
|
||||||
|
let prevTimer: number | null = null
|
||||||
|
return ((...args: any[]) => {
|
||||||
if (prevTimer) {
|
if (prevTimer) {
|
||||||
clearTimeout(prevTimer);
|
clearTimeout(prevTimer)
|
||||||
}
|
}
|
||||||
prevTimer = window.setTimeout(() => {
|
prevTimer = window.setTimeout(() => {
|
||||||
fn(...args);
|
fn(...args)
|
||||||
prevTimer = null;
|
prevTimer = null
|
||||||
}, delay);
|
}, delay)
|
||||||
});
|
}) as any
|
||||||
}
|
}
|
@ -4,25 +4,28 @@ const HtmlWebpackPlugin = require('html-webpack-plugin');
|
|||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
mode: 'development',
|
mode: 'development',
|
||||||
devtool: 'cheap-module-eval-source-map',
|
devtool: false,
|
||||||
context: path.join(__dirname, '../packages/jsx-explorer'),
|
context: path.join(__dirname, '../packages/jsx-explorer'),
|
||||||
entry: './src/index.js',
|
entry: './src/index.ts',
|
||||||
output: {
|
output: {
|
||||||
publicPath: './',
|
publicPath: './',
|
||||||
},
|
},
|
||||||
module: {
|
module: {
|
||||||
rules: [
|
rules: [
|
||||||
{
|
{
|
||||||
test: /\.jsx?$/,
|
test: /\.tsx?$/,
|
||||||
loader: 'babel-loader',
|
loader: 'ts-loader',
|
||||||
exclude: /node_modules/,
|
exclude: /node_modules/,
|
||||||
|
options: {
|
||||||
|
compilerOptions: { downlevelIteration: true },
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
|
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
|
||||||
loader: 'url-loader',
|
loader: 'url-loader',
|
||||||
options: {
|
options: {
|
||||||
limit: 10000,
|
limit: 10000,
|
||||||
name: 'dist/fonts/[name].[hash:7].[ext]',
|
name: 'fonts/[name].[hash:7].[ext]',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -40,6 +43,9 @@ module.exports = {
|
|||||||
filename: 'index.html',
|
filename: 'index.html',
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
|
resolve: {
|
||||||
|
extensions: ['.ts', '.js'],
|
||||||
|
},
|
||||||
node: {
|
node: {
|
||||||
fs: 'empty',
|
fs: 'empty',
|
||||||
},
|
},
|
||||||
|
21
tsconfig.json
Normal file
21
tsconfig.json
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"sourceMap": false,
|
||||||
|
"target": "es5",
|
||||||
|
"module": "commonjs",
|
||||||
|
"moduleResolution": "node",
|
||||||
|
"allowJs": false,
|
||||||
|
"strict": true,
|
||||||
|
"noUnusedLocals": true,
|
||||||
|
"experimentalDecorators": true,
|
||||||
|
"resolveJsonModule": true,
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"removeComments": false,
|
||||||
|
"jsx": "preserve",
|
||||||
|
"lib": ["esnext", "dom"],
|
||||||
|
"types": ["node"],
|
||||||
|
},
|
||||||
|
"include": [
|
||||||
|
"global.d.ts"
|
||||||
|
]
|
||||||
|
}
|
73
yarn.lock
73
yarn.lock
@ -224,6 +224,11 @@
|
|||||||
resolved "https://r.cnpmjs.org/@babel/helper-validator-identifier/download/@babel/helper-validator-identifier-7.10.1.tgz#5770b0c1a826c4f53f5ede5e153163e0318e94b5"
|
resolved "https://r.cnpmjs.org/@babel/helper-validator-identifier/download/@babel/helper-validator-identifier-7.10.1.tgz#5770b0c1a826c4f53f5ede5e153163e0318e94b5"
|
||||||
integrity sha1-V3CwwagmxPU/Xt5eFTFj4DGOlLU=
|
integrity sha1-V3CwwagmxPU/Xt5eFTFj4DGOlLU=
|
||||||
|
|
||||||
|
"@babel/helper-validator-identifier@^7.10.4":
|
||||||
|
version "7.10.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz#a78c7a7251e01f616512d31b10adcf52ada5e0d2"
|
||||||
|
integrity sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==
|
||||||
|
|
||||||
"@babel/helper-wrap-function@^7.10.1":
|
"@babel/helper-wrap-function@^7.10.1":
|
||||||
version "7.10.1"
|
version "7.10.1"
|
||||||
resolved "https://r.cnpmjs.org/@babel/helper-wrap-function/download/@babel/helper-wrap-function-7.10.1.tgz#956d1310d6696257a7afd47e4c42dfda5dfcedc9"
|
resolved "https://r.cnpmjs.org/@babel/helper-wrap-function/download/@babel/helper-wrap-function-7.10.1.tgz#956d1310d6696257a7afd47e4c42dfda5dfcedc9"
|
||||||
@ -817,6 +822,15 @@
|
|||||||
lodash "^4.17.13"
|
lodash "^4.17.13"
|
||||||
to-fast-properties "^2.0.0"
|
to-fast-properties "^2.0.0"
|
||||||
|
|
||||||
|
"@babel/types@^7.10.4":
|
||||||
|
version "7.10.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.10.4.tgz#369517188352e18219981efd156bfdb199fff1ee"
|
||||||
|
integrity sha512-UTCFOxC3FsFHb7lkRMVvgLzaRVamXuAs2Tz4wajva4WxtVY82eZeaUBtC2Zt95FU9TiznuC0Zk35tsim8jeVpg==
|
||||||
|
dependencies:
|
||||||
|
"@babel/helper-validator-identifier" "^7.10.4"
|
||||||
|
lodash "^4.17.13"
|
||||||
|
to-fast-properties "^2.0.0"
|
||||||
|
|
||||||
"@bcoe/v8-coverage@^0.2.3":
|
"@bcoe/v8-coverage@^0.2.3":
|
||||||
version "0.2.3"
|
version "0.2.3"
|
||||||
resolved "https://r.cnpmjs.org/@bcoe/v8-coverage/download/@bcoe/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39"
|
resolved "https://r.cnpmjs.org/@bcoe/v8-coverage/download/@bcoe/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39"
|
||||||
@ -1901,7 +1915,28 @@
|
|||||||
"@babel/helper-module-imports" "^7.7.4"
|
"@babel/helper-module-imports" "^7.7.4"
|
||||||
"@rollup/pluginutils" "^3.0.8"
|
"@rollup/pluginutils" "^3.0.8"
|
||||||
|
|
||||||
"@rollup/pluginutils@^3.0.8":
|
"@rollup/plugin-commonjs@^13.0.0":
|
||||||
|
version "13.0.0"
|
||||||
|
resolved "https://r.cnpmjs.org/@rollup/plugin-commonjs/download/@rollup/plugin-commonjs-13.0.0.tgz#8a1d684ba6848afe8b9e3d85649d4b2f6f7217ec"
|
||||||
|
integrity sha1-ih1oS6aEiv6Lnj2FZJ1LL29yF+w=
|
||||||
|
dependencies:
|
||||||
|
"@rollup/pluginutils" "^3.0.8"
|
||||||
|
commondir "^1.0.1"
|
||||||
|
estree-walker "^1.0.1"
|
||||||
|
glob "^7.1.2"
|
||||||
|
is-reference "^1.1.2"
|
||||||
|
magic-string "^0.25.2"
|
||||||
|
resolve "^1.11.0"
|
||||||
|
|
||||||
|
"@rollup/plugin-typescript@^3.0.0":
|
||||||
|
version "3.1.1"
|
||||||
|
resolved "https://r.cnpmjs.org/@rollup/plugin-typescript/download/@rollup/plugin-typescript-3.1.1.tgz#a39175a552ed82a3e424862e6bb403bf9da451ee"
|
||||||
|
integrity sha1-o5F1pVLtgqPkJIYua7QDv52kUe4=
|
||||||
|
dependencies:
|
||||||
|
"@rollup/pluginutils" "^3.0.1"
|
||||||
|
resolve "^1.14.1"
|
||||||
|
|
||||||
|
"@rollup/pluginutils@^3.0.1", "@rollup/pluginutils@^3.0.8":
|
||||||
version "3.1.0"
|
version "3.1.0"
|
||||||
resolved "https://r.cnpmjs.org/@rollup/pluginutils/download/@rollup/pluginutils-3.1.0.tgz#706b4524ee6dc8b103b3c995533e5ad680c02b9b"
|
resolved "https://r.cnpmjs.org/@rollup/pluginutils/download/@rollup/pluginutils-3.1.0.tgz#706b4524ee6dc8b103b3c995533e5ad680c02b9b"
|
||||||
integrity sha1-cGtFJO5tyLEDs8mVUz5a1oDAK5s=
|
integrity sha1-cGtFJO5tyLEDs8mVUz5a1oDAK5s=
|
||||||
@ -1967,6 +2002,11 @@
|
|||||||
resolved "https://r.cnpmjs.org/@types/color-name/download/@types/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0"
|
resolved "https://r.cnpmjs.org/@types/color-name/download/@types/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0"
|
||||||
integrity sha1-HBJhu+qhCoBVu8XYq4S3sq/IRqA=
|
integrity sha1-HBJhu+qhCoBVu8XYq4S3sq/IRqA=
|
||||||
|
|
||||||
|
"@types/estree@*":
|
||||||
|
version "0.0.45"
|
||||||
|
resolved "https://r.cnpmjs.org/@types/estree/download/@types/estree-0.0.45.tgz#e9387572998e5ecdac221950dab3e8c3b16af884"
|
||||||
|
integrity sha1-6Th1cpmOXs2sIhlQ2rPow7Fq+IQ=
|
||||||
|
|
||||||
"@types/estree@0.0.39":
|
"@types/estree@0.0.39":
|
||||||
version "0.0.39"
|
version "0.0.39"
|
||||||
resolved "https://r.cnpmjs.org/@types/estree/download/@types/estree-0.0.39.tgz#e177e699ee1b8c22d23174caaa7422644389509f"
|
resolved "https://r.cnpmjs.org/@types/estree/download/@types/estree-0.0.39.tgz#e177e699ee1b8c22d23174caaa7422644389509f"
|
||||||
@ -2057,6 +2097,11 @@
|
|||||||
resolved "https://r.cnpmjs.org/@types/stack-utils/download/@types/stack-utils-1.0.1.tgz#0a851d3bd96498fa25c33ab7278ed3bd65f06c3e"
|
resolved "https://r.cnpmjs.org/@types/stack-utils/download/@types/stack-utils-1.0.1.tgz#0a851d3bd96498fa25c33ab7278ed3bd65f06c3e"
|
||||||
integrity sha1-CoUdO9lkmPolwzq3J47TvWXwbD4=
|
integrity sha1-CoUdO9lkmPolwzq3J47TvWXwbD4=
|
||||||
|
|
||||||
|
"@types/svg-tags@^1.0.0":
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/svg-tags/-/svg-tags-1.0.0.tgz#2ba2a2e8d72827ae41cbec453d52f939c2049b63"
|
||||||
|
integrity sha512-PlLI3u2hocS4nbzd9WUzQn/EyFl+NifbssU9QV40XzWOpwf5R7cDod2dmTUKYN7awE9jMrhy9FCO904ZYwaBDw==
|
||||||
|
|
||||||
"@types/tapable@*", "@types/tapable@^1.0.5":
|
"@types/tapable@*", "@types/tapable@^1.0.5":
|
||||||
version "1.0.6"
|
version "1.0.6"
|
||||||
resolved "https://r.cnpmjs.org/@types/tapable/download/@types/tapable-1.0.6.tgz#a9ca4b70a18b270ccb2bc0aaafefd1d486b7ea74"
|
resolved "https://r.cnpmjs.org/@types/tapable/download/@types/tapable-1.0.6.tgz#a9ca4b70a18b270ccb2bc0aaafefd1d486b7ea74"
|
||||||
@ -6049,6 +6094,13 @@ is-potential-custom-element-name@^1.0.0:
|
|||||||
resolved "https://r.cnpmjs.org/is-potential-custom-element-name/download/is-potential-custom-element-name-1.0.0.tgz#0c52e54bcca391bb2c494b21e8626d7336c6e397"
|
resolved "https://r.cnpmjs.org/is-potential-custom-element-name/download/is-potential-custom-element-name-1.0.0.tgz#0c52e54bcca391bb2c494b21e8626d7336c6e397"
|
||||||
integrity sha1-DFLlS8yjkbssSUsh6GJtczbG45c=
|
integrity sha1-DFLlS8yjkbssSUsh6GJtczbG45c=
|
||||||
|
|
||||||
|
is-reference@^1.1.2:
|
||||||
|
version "1.2.1"
|
||||||
|
resolved "https://r.cnpmjs.org/is-reference/download/is-reference-1.2.1.tgz#8b2dac0b371f4bc994fdeaba9eb542d03002d0b7"
|
||||||
|
integrity sha1-iy2sCzcfS8mU/eq6nrVC0DAC0Lc=
|
||||||
|
dependencies:
|
||||||
|
"@types/estree" "*"
|
||||||
|
|
||||||
is-regex@^1.0.4, is-regex@^1.1.0:
|
is-regex@^1.0.4, is-regex@^1.1.0:
|
||||||
version "1.1.0"
|
version "1.1.0"
|
||||||
resolved "https://r.cnpmjs.org/is-regex/download/is-regex-1.1.0.tgz#ece38e389e490df0dc21caea2bd596f987f767ff"
|
resolved "https://r.cnpmjs.org/is-regex/download/is-regex-1.1.0.tgz#ece38e389e490df0dc21caea2bd596f987f767ff"
|
||||||
@ -6959,6 +7011,13 @@ macos-release@^2.2.0:
|
|||||||
resolved "https://r.cnpmjs.org/macos-release/download/macos-release-2.3.0.tgz#eb1930b036c0800adebccd5f17bc4c12de8bb71f"
|
resolved "https://r.cnpmjs.org/macos-release/download/macos-release-2.3.0.tgz#eb1930b036c0800adebccd5f17bc4c12de8bb71f"
|
||||||
integrity sha1-6xkwsDbAgArevM1fF7xMEt6Ltx8=
|
integrity sha1-6xkwsDbAgArevM1fF7xMEt6Ltx8=
|
||||||
|
|
||||||
|
magic-string@^0.25.2:
|
||||||
|
version "0.25.7"
|
||||||
|
resolved "https://r.cnpmjs.org/magic-string/download/magic-string-0.25.7.tgz#3f497d6fd34c669c6798dcb821f2ef31f5445051"
|
||||||
|
integrity sha1-P0l9b9NMZpxnmNy4IfLvMfVEUFE=
|
||||||
|
dependencies:
|
||||||
|
sourcemap-codec "^1.4.4"
|
||||||
|
|
||||||
make-dir@^1.0.0:
|
make-dir@^1.0.0:
|
||||||
version "1.3.0"
|
version "1.3.0"
|
||||||
resolved "https://r.cnpmjs.org/make-dir/download/make-dir-1.3.0.tgz#79c1033b80515bd6d24ec9933e860ca75ee27f0c"
|
resolved "https://r.cnpmjs.org/make-dir/download/make-dir-1.3.0.tgz#79c1033b80515bd6d24ec9933e860ca75ee27f0c"
|
||||||
@ -8947,7 +9006,7 @@ resolve-url@^0.2.1:
|
|||||||
resolved "https://r.cnpmjs.org/resolve-url/download/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a"
|
resolved "https://r.cnpmjs.org/resolve-url/download/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a"
|
||||||
integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=
|
integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=
|
||||||
|
|
||||||
resolve@^1.10.0, resolve@^1.13.1, resolve@^1.17.0, resolve@^1.3.2:
|
resolve@^1.10.0, resolve@^1.11.0, resolve@^1.13.1, resolve@^1.14.1, resolve@^1.17.0, resolve@^1.3.2:
|
||||||
version "1.17.0"
|
version "1.17.0"
|
||||||
resolved "https://r.cnpmjs.org/resolve/download/resolve-1.17.0.tgz#b25941b54968231cc2d1bb76a79cb7f2c0bf8444"
|
resolved "https://r.cnpmjs.org/resolve/download/resolve-1.17.0.tgz#b25941b54968231cc2d1bb76a79cb7f2c0bf8444"
|
||||||
integrity sha1-sllBtUloIxzC0bt2p5y38sC/hEQ=
|
integrity sha1-sllBtUloIxzC0bt2p5y38sC/hEQ=
|
||||||
@ -9419,6 +9478,11 @@ source-map@^0.7.3:
|
|||||||
resolved "https://r.cnpmjs.org/source-map/download/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383"
|
resolved "https://r.cnpmjs.org/source-map/download/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383"
|
||||||
integrity sha1-UwL4FpAxc1ImVECS5kmB91F1A4M=
|
integrity sha1-UwL4FpAxc1ImVECS5kmB91F1A4M=
|
||||||
|
|
||||||
|
sourcemap-codec@^1.4.4:
|
||||||
|
version "1.4.8"
|
||||||
|
resolved "https://r.cnpmjs.org/sourcemap-codec/download/sourcemap-codec-1.4.8.tgz#ea804bd94857402e6992d05a38ef1ae35a9ab4c4"
|
||||||
|
integrity sha1-6oBL2UhXQC5pktBaOO8a41qatMQ=
|
||||||
|
|
||||||
spdx-correct@^3.0.0:
|
spdx-correct@^3.0.0:
|
||||||
version "3.1.1"
|
version "3.1.1"
|
||||||
resolved "https://r.cnpmjs.org/spdx-correct/download/spdx-correct-3.1.1.tgz#dece81ac9c1e6713e5f7d1b6f17d468fa53d89a9"
|
resolved "https://r.cnpmjs.org/spdx-correct/download/spdx-correct-3.1.1.tgz#dece81ac9c1e6713e5f7d1b6f17d468fa53d89a9"
|
||||||
@ -10127,6 +10191,11 @@ typedarray@^0.0.6:
|
|||||||
resolved "https://r.cnpmjs.org/typedarray/download/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
|
resolved "https://r.cnpmjs.org/typedarray/download/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
|
||||||
integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=
|
integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=
|
||||||
|
|
||||||
|
typescript@^3.9.6:
|
||||||
|
version "3.9.6"
|
||||||
|
resolved "https://r.cnpmjs.org/typescript/download/typescript-3.9.6.tgz#8f3e0198a34c3ae17091b35571d3afd31999365a"
|
||||||
|
integrity sha1-jz4BmKNMOuFwkbNVcdOv0xmZNlo=
|
||||||
|
|
||||||
uglify-js@^3.1.4:
|
uglify-js@^3.1.4:
|
||||||
version "3.9.4"
|
version "3.9.4"
|
||||||
resolved "https://r.cnpmjs.org/uglify-js/download/uglify-js-3.9.4.tgz#867402377e043c1fc7b102253a22b64e5862401b"
|
resolved "https://r.cnpmjs.org/uglify-js/download/uglify-js-3.9.4.tgz#867402377e043c1fc7b102253a22b64e5862401b"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user