Skip to content

Commit

Permalink
feat(babel-plugin-transform-react-jsx-to-rn-stylesheet): 当style为array…
Browse files Browse the repository at this point in the history
…,需要转换为object #11476 (#11486)

* feat(babel-plugin-transform-react-jsx-to-rn-stylesheet): 当style为array,需要转换为Object

* feat(babel-plugin-transform-react-jsx-to-rn-stylesheet): 还原test引入路径

Co-authored-by: jian.sun1 <jian.sun1@amn-group.com>
  • Loading branch information
biorz and jian.sun1 authored Mar 21, 2022
1 parent 92f3126 commit 6310499
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ const getStyleFunctionTemplete = `function _getStyle(classNameExpression) {
return style;
}`

const mergeEleStylesFunctionTemplate = `function _mergeEleStyles() {
return [].concat.apply([], arguments).reduce((pre, cur) => Object.assign(pre, cur), {});
}`

describe('jsx style plugin', () => {
function getTransfromCode (source, debug = false, options = {}) {
const { enableCSSModule, enableMultipleClassName = false } = options
Expand Down Expand Up @@ -116,11 +120,14 @@ class App extends Component {
}
}`)).toBe(`import { createElement, Component } from 'rax';
import appCssStyleSheet from "./app.css";
${mergeEleStylesFunctionTemplate}
var _styleSheet = appCssStyleSheet;
class App extends Component {
render() {
return <div style={[_styleSheet["header1"], _styleSheet["header2"]]} />;
return <div style={_mergeEleStyles(_styleSheet["header1"], _styleSheet["header2"])} />;
}
}`)
Expand Down Expand Up @@ -179,13 +186,15 @@ class App extends Component {
import app1CssStyleSheet from "./app1.css";
import app2CssStyleSheet from "./app2.css";
${mergeEleStylesFunctionTemplate}
${mergeStylesFunctionTemplate}
var _styleSheet = _mergeStyles(app1CssStyleSheet, app2CssStyleSheet);
class App extends Component {
render() {
return <div style={[_styleSheet["header1"], _styleSheet["header2"]]} />;
return <div style={_mergeEleStyles(_styleSheet["header1"], _styleSheet["header2"])} />;
}
}`)
Expand All @@ -204,13 +213,15 @@ class App extends Component {
import appCssStyleSheet from "./app.css";
import appCssStyleSheet1 from "../app.css";
${mergeEleStylesFunctionTemplate}
${mergeStylesFunctionTemplate}
var _styleSheet = _mergeStyles(appCssStyleSheet, appCssStyleSheet1);
class App extends Component {
render() {
return <div style={[_styleSheet["header1"], _styleSheet["header2"]]} />;
return <div style={_mergeEleStyles(_styleSheet["header1"], _styleSheet["header2"])} />;
}
}`)
Expand All @@ -229,13 +240,15 @@ class App extends Component {
import appCssStyleSheet from "./app.css";
import style from "./style.css";
${mergeEleStylesFunctionTemplate}
${mergeStylesFunctionTemplate}
var _styleSheet = _mergeStyles(appCssStyleSheet, style);
class App extends Component {
render() {
return <div style={[_styleSheet["header2"], style.header1]} />;
return <div style={_mergeEleStyles(_styleSheet["header2"], style.header1)} />;
}
}`)
Expand All @@ -254,13 +267,16 @@ class App extends Component {
}
}`)).toBe(`import { createElement, Component } from 'rax';
import appCssStyleSheet from "./app.css";
${mergeEleStylesFunctionTemplate}
var _styleSheet = appCssStyleSheet;
class App extends Component {
render() {
return <div style={[_styleSheet["header"], {
return <div style={_mergeEleStyles(_styleSheet["header"], {
height: 100
}]} />;
})} />;
}\n
}`)
})
Expand All @@ -279,13 +295,15 @@ class App extends Component {
import appCssStyleSheet from "./app.css";
import style from "./style.css";
${mergeEleStylesFunctionTemplate}
${mergeStylesFunctionTemplate}
var _styleSheet = _mergeStyles(appCssStyleSheet, style);
class App extends Component {
render() {
return <div style={[_styleSheet["header2"], style.header1, style.header3]} />;
return <div style={_mergeEleStyles(_styleSheet["header2"], style.header1, style.header3)} />;
}\n
}`)
})
Expand Down Expand Up @@ -407,11 +425,14 @@ import './app.less';
render(<div className="header" style={{width: 100, height: 100}} />);
`)).toBe(`import { createElement, render } from 'rax';
import appLessStyleSheet from "./app.less";
${mergeEleStylesFunctionTemplate}
var _styleSheet = appLessStyleSheet;
render(<div style={[_styleSheet["header"], {
render(<div style={_mergeEleStyles(_styleSheet["header"], {
width: 100,
height: 100
}]} />);`)
})} />);`)
})
it('transform styleAttribute inline string', () => {
expect(getTransfromCode(`
Expand All @@ -436,15 +457,18 @@ import './app.less';
render(<div className="header" style="width:100px;height:100px;background-color:rgba(0, 0, 0, 0.5);border: 1px solid;" />);
`)).toBe(`import { createElement, render } from 'rax';
import appLessStyleSheet from "./app.less";
${mergeEleStylesFunctionTemplate}
var _styleSheet = appLessStyleSheet;
render(<div style={[_styleSheet["header"], {
render(<div style={_mergeEleStyles(_styleSheet["header"], {
"width": 100,
"height": 100,
"backgroundColor": "rgba(0, 0, 0, 0.5)",
"borderWidth": 1,
"borderStyle": "solid",
"borderColor": "black"
}]} />);`)
})} />);`)
})

it('ignore merge stylesheet when css module enable', () => {
Expand All @@ -460,11 +484,14 @@ class App extends Component {
}`, false, { enableCSSModule: true })).toBe(`import { createElement, Component } from 'rax';
import appScssStyleSheet from "./app.scss";
import styleSheet from './app.module.scss';
${mergeEleStylesFunctionTemplate}
var _styleSheet = appScssStyleSheet;
class App extends Component {
render() {
return <div style={[_styleSheet["header"], styleSheet.red]} />;
return <div style={_mergeEleStyles(_styleSheet["header"], styleSheet.red)} />;
}\n
}`)
})
Expand Down Expand Up @@ -585,13 +612,15 @@ class App extends Component {
import appScssStyleSheet from "./app.scss";
import styleSheet from "./app.module.scss";
${mergeEleStylesFunctionTemplate}
${mergeStylesFunctionTemplate}
var _styleSheet = _mergeStyles(appScssStyleSheet, styleSheet);
class App extends Component {
render() {
return <div style={[_styleSheet["header"], styleSheet.red]} />;
return <div style={_mergeEleStyles(_styleSheet["header"], styleSheet.red)} />;
}\n
}`)
})
Expand Down Expand Up @@ -649,15 +678,18 @@ class App extends Component {
}
}`, false, { enableMultipleClassName: true })).toBe(`import { createElement, Component } from 'rax';
import appCssStyleSheet from "./app.css";
${mergeEleStylesFunctionTemplate}
var _styleSheet = appCssStyleSheet;
class App extends Component {
render() {
return <div style={[_styleSheet["container"], {
return <div style={_mergeEleStyles(_styleSheet["container"], {
color: "red"
}]} headerStyle={[_styleSheet["header"], {
})} headerStyle={_mergeEleStyles(_styleSheet["header"], {
color: "green"
}]} />;
})} />;
}
}`)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import { ConvertPluginPass as PluginPass } from './types'
const STYLE_SHEET_NAME = '_styleSheet'
const GET_STYLE_FUNC_NAME = '_getStyle'
const MERGE_STYLES_FUNC_NAME = '_mergeStyles'
const MERGE_ELE_STYLES_FUNC_NAME = '_mergeEleStyles'

const GET_CLS_NAME_FUNC_NAME = '_getClassName'
const NAME_SUFFIX = 'styleSheet'
const RN_CSS_EXT = ['.css', '.scss', '.sass', '.less', '.styl', '.stylus']
Expand All @@ -23,7 +25,7 @@ const string2Object = str => {
const entries = str.replace(/;+$/g, '')
.split(';')
.map(l => {
const arr = l.split(':')
const arr = l.split(':').map(it => it.trim())
arr[1] = arr[1]?.replace(/px/g, 'PX')
return arr
})
Expand Down Expand Up @@ -97,6 +99,12 @@ function ${GET_CLS_NAME_FUNC_NAME}() {
return className.join(' ').trim();
}
`
// like: `[[styles.header, styles.header1], styles.header2]`
const getMergeEleStyleFunction = `
function ${MERGE_ELE_STYLES_FUNC_NAME}() {
return [].concat.apply([], arguments).reduce((pre, cur) => Object.assign(pre, cur), {})
}
`
const getStyleFunction = `
function ${GET_STYLE_FUNC_NAME}(classNameExpression) {
var className = ${GET_CLS_NAME_FUNC_NAME}(classNameExpression);
Expand All @@ -113,10 +121,11 @@ export default function (babel: {
}): PluginObj {
const { types: t, template } = babel

const getClassNameFunctionTemplate = template(getClassNameFunction)
const getStyleFunctionTemplete = template(getStyleFunction)
const getClassNameFunctionStmt = getClassNameFunctionTemplate()
const getStyleFunctionStmt = getStyleFunctionTemplete()
const getClassNameFunctionStmt = template(getClassNameFunction)()

const getStyleFunctionStmt = template(getStyleFunction)()

const getMergeEleStyleFunctionStmt = template(getMergeEleStyleFunction)()

function getMap (str) {
return str.split(/\s+/).map((className) => {
Expand Down Expand Up @@ -273,13 +282,16 @@ export default function (babel: {
const node = astPath.node
const injectGetStyle = file.get('injectGetStyle')
// 从最后一个import 开始插入表达式,后续插入的表达式追加在后面
const lastImportIndex = findLastImportIndex(node.body)

let lastImportIndex = findLastImportIndex(node.body)
if (injectGetStyle) {
// @ts-ignore
node.body.splice(lastImportIndex + 1, 0, getClassNameFunctionStmt)
node.body.splice(++lastImportIndex, 0, getClassNameFunctionStmt)
// @ts-ignore
node.body.splice(++lastImportIndex, 0, getStyleFunctionStmt)
}
if (file.get('hasMultiStyle')) {
// @ts-ignore
node.body.splice(lastImportIndex + 2, 0, getStyleFunctionStmt)
node.body.splice(++lastImportIndex, 0, getMergeEleStyleFunctionStmt)
}
existStyleImport = false
}
Expand Down Expand Up @@ -339,7 +351,12 @@ export default function (babel: {
return
}

if (arrayExpression.length > 1) {
file.set('hasMultiStyle', true)
}

if (hasStyleAttribute && styleAttribute.value) {
file.set('hasMultiStyle', true)
let expression
// 支持 行内 style 转成oject:style="width:100;height:100;" => style={{width:'100',height:'100'}}
if (t.isStringLiteral(styleAttribute.value)) {
Expand All @@ -350,9 +367,11 @@ export default function (babel: {
}
const expressionType = expression.type

let _arrayExpression
// 非rn场景,style不支持数组,因此需要将数组转换为对象
// style={[styles.a, styles.b]} ArrayExpression
if (expressionType === 'ArrayExpression') {
expression.elements = arrayExpression.concat(expression.elements)
_arrayExpression = arrayExpression.concat(expression.elements)
// style={styles.a} MemberExpression
// style={{ height: 100 }} ObjectExpression
// style={{ ...custom }} ObjectExpression
Expand All @@ -361,10 +380,13 @@ export default function (babel: {
// style={this.props.useCustom ? custom : null} ConditionalExpression
// style={custom || other} LogicalExpression
} else {
styleAttribute.value = t.jSXExpressionContainer(t.arrayExpression(arrayExpression.concat(expression)))
_arrayExpression = arrayExpression.concat(expression)
}
styleAttribute.value = t.jSXExpressionContainer(t.callExpression(t.identifier(MERGE_ELE_STYLES_FUNC_NAME), _arrayExpression))
} else {
const expression = arrayExpression.length === 1 ? arrayExpression[0] : t.arrayExpression(arrayExpression)
const expression = arrayExpression.length > 1
? t.callExpression(t.identifier(MERGE_ELE_STYLES_FUNC_NAME), arrayExpression)
: arrayExpression[0]
attributes.push(t.jSXAttribute(t.jSXIdentifier(key === DEFAULT_STYLE_KEY ? key : (key + 'Style')), t.jSXExpressionContainer(expression)))
}
} else if (hasStyleAttribute) {
Expand Down

0 comments on commit 6310499

Please sign in to comment.