fix: pure string export in jsx

This commit is contained in:
春希 2020-11-12 11:26:27 +08:00
parent d719c43e60
commit 1a9e9534ae
3 changed files with 43 additions and 11 deletions

View File

@ -29,6 +29,7 @@
"@babel/types": "^7.9.5", "@babel/types": "^7.9.5",
"@types/prettier": "^1.19.1", "@types/prettier": "^1.19.1",
"change-case": "^3.1.0", "change-case": "^3.1.0",
"html-entities": "^1.3.1",
"jszip": "^3.5.0", "jszip": "^3.5.0",
"prettier": "^2.0.2", "prettier": "^2.0.2",
"semver": "^7.3.2", "semver": "^7.3.2",

View File

@ -33,3 +33,9 @@ export function uniqueArray<T>(arr: T[], by: (i: T) => string) {
const uniqueItems = uniqueKeys.map((key) => map[key]); const uniqueItems = uniqueKeys.map((key) => map[key]);
return uniqueItems; return uniqueItems;
} }
export function getStaticExprValue<T>(expr: string): T {
// TODO: 需要安全性检查
// eslint-disable-next-line no-new-func
return Function(`"use strict";return (${expr})`)();
}

View File

@ -1,5 +1,6 @@
import _ from 'lodash'; import _ from 'lodash';
import { NodeSchema, isNodeSchema, NodeDataType, CompositeValue } from '@ali/lowcode-types'; import { NodeSchema, isNodeSchema, NodeDataType, CompositeValue } from '@ali/lowcode-types';
import { AllHtmlEntities } from 'html-entities';
import { import {
IScope, IScope,
@ -13,9 +14,15 @@ import {
} from '../types'; } from '../types';
import { generateCompositeType } from './compositeType'; import { generateCompositeType } from './compositeType';
import { getStaticExprValue } from './common';
import { executeFunctionStack } from './aopHelper'; import { executeFunctionStack } from './aopHelper';
function mergeNodeGeneratorConfig(cfg1: NodeGeneratorConfig, cfg2: NodeGeneratorConfig = {}): NodeGeneratorConfig { const entities = new AllHtmlEntities();
function mergeNodeGeneratorConfig(
cfg1: NodeGeneratorConfig,
cfg2: NodeGeneratorConfig = {},
): NodeGeneratorConfig {
const resCfg: NodeGeneratorConfig = {}; const resCfg: NodeGeneratorConfig = {};
if (cfg1.handlers || cfg2.handlers) { if (cfg1.handlers || cfg2.handlers) {
resCfg.handlers = { resCfg.handlers = {
@ -44,11 +51,12 @@ function mergeNodeGeneratorConfig(cfg1: NodeGeneratorConfig, cfg2: NodeGenerator
} }
export function isPureString(v: string) { export function isPureString(v: string) {
return v[0] === "'" && v[v.length - 1] === "'"; // FIXME: 目前的方式不够严谨
return (v[0] === "'" && v[v.length - 1] === "'") || (v[0] === '"' && v[v.length - 1] === '"');
} }
export function getPureStringContent(v: string) { export function encodeJsxStringNode(v: string) {
return v.substring(1, v.length - 1); return entities.encode(v);
} }
function generateAttrValue( function generateAttrValue(
@ -93,8 +101,9 @@ function generateAttr(
// 因此这个处理最好的方式是对传出值做语法分析,判断以哪种模版产出 Attr 值 // 因此这个处理最好的方式是对传出值做语法分析,判断以哪种模版产出 Attr 值
let newValue: string; let newValue: string;
if (p.value && isPureString(p.value)) { if (p.value && isPureString(p.value)) {
const content = getPureStringContent(p.value); // 似乎多次一举,目前的诉求是处理多种引号类型字符串的 case正确处理转义
newValue = `"${content}"`; const content = getStaticExprValue<string>(p.value);
newValue = JSON.stringify(content);
} else { } else {
newValue = `{${p.value}}`; newValue = `{${p.value}}`;
} }
@ -108,7 +117,11 @@ function generateAttr(
return pieces; return pieces;
} }
function generateAttrs(nodeItem: NodeSchema, scope: IScope, config?: NodeGeneratorConfig): CodePiece[] { function generateAttrs(
nodeItem: NodeSchema,
scope: IScope,
config?: NodeGeneratorConfig,
): CodePiece[] {
const { props } = nodeItem; const { props } = nodeItem;
let pieces: CodePiece[] = []; let pieces: CodePiece[] = [];
@ -133,7 +146,11 @@ function generateAttrs(nodeItem: NodeSchema, scope: IScope, config?: NodeGenerat
return pieces; return pieces;
} }
function generateBasicNode(nodeItem: NodeSchema, scope: IScope, config?: NodeGeneratorConfig): CodePiece[] { function generateBasicNode(
nodeItem: NodeSchema,
scope: IScope,
config?: NodeGeneratorConfig,
): CodePiece[] {
const pieces: CodePiece[] = []; const pieces: CodePiece[] = [];
const tagName = (config?.tagMapping || _.identity)(nodeItem.componentName); const tagName = (config?.tagMapping || _.identity)(nodeItem.componentName);
@ -145,7 +162,11 @@ function generateBasicNode(nodeItem: NodeSchema, scope: IScope, config?: NodeGen
return pieces; return pieces;
} }
function generateSimpleNode(nodeItem: NodeSchema, scope: IScope, config?: NodeGeneratorConfig): CodePiece[] { function generateSimpleNode(
nodeItem: NodeSchema,
scope: IScope,
config?: NodeGeneratorConfig,
): CodePiece[] {
const basicParts = generateBasicNode(nodeItem, scope, config) || []; const basicParts = generateBasicNode(nodeItem, scope, config) || [];
const attrParts = generateAttrs(nodeItem, scope, config) || []; const attrParts = generateAttrs(nodeItem, scope, config) || [];
const childrenParts: CodePiece[] = []; const childrenParts: CodePiece[] = [];
@ -197,7 +218,11 @@ function linkPieces(pieces: CodePiece[]): string {
return `${beforeParts}<${tagName}${attrsParts} />${afterParts}`; return `${beforeParts}<${tagName}${attrsParts} />${afterParts}`;
} }
function generateNodeSchema(nodeItem: NodeSchema, scope: IScope, config?: NodeGeneratorConfig): string { function generateNodeSchema(
nodeItem: NodeSchema,
scope: IScope,
config?: NodeGeneratorConfig,
): string {
const pieces: CodePiece[] = []; const pieces: CodePiece[] = [];
if (config?.nodePlugins) { if (config?.nodePlugins) {
const res = executeFunctionStack<NodeSchema, CodePiece[], NodeGeneratorConfig>( const res = executeFunctionStack<NodeSchema, CodePiece[], NodeGeneratorConfig>(
@ -346,7 +371,7 @@ export function createNodeGenerator(cfg: NodeGeneratorConfig = {}): NodeGenerato
}); });
if (isPureString(valueStr)) { if (isPureString(valueStr)) {
return getPureStringContent(valueStr); return encodeJsxStringNode(getStaticExprValue<string>(valueStr));
} }
return `{${valueStr}}`; return `{${valueStr}}`;