diff --git a/packages/babel-plugin-transform-react-jsx-to-rn-stylesheet/__tests__/__snapshots__/index.spec.js.snap b/packages/babel-plugin-transform-react-jsx-to-rn-stylesheet/__tests__/__snapshots__/index.spec.js.snap
new file mode 100644
index 000000000000..412e66e7fd76
--- /dev/null
+++ b/packages/babel-plugin-transform-react-jsx-to-rn-stylesheet/__tests__/__snapshots__/index.spec.js.snap
@@ -0,0 +1,660 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`jsx style plugin Processing module style assignment When css module enable 1`] = `
+"import { createElement, Component } from 'rax';
+import appScssStyleSheet from \\"./app.scss\\";
+import _styleSheetModuleStyle from './app.module.scss';
+
+function _getClassName() {
+ var className = [];
+ var args = arguments[0];
+ var type = Object.prototype.toString.call(args).slice(8, -1).toLowerCase();
+
+ if (type === 'string') {
+ args = args.trim();
+ args && className.push(args);
+ } else if (type === 'array') {
+ args.forEach(function (cls) {
+ cls = _getClassName(cls).trim();
+ cls && className.push(cls);
+ });
+ } else if (type === 'object') {
+ for (var k in args) {
+ k = k.trim();
+
+ if (k && args.hasOwnProperty(k) && args[k]) {
+ className.push(k);
+ }
+ }
+ }
+
+ return className.join(' ').trim();
+}
+
+function _getStyle(classNameExpression) {
+ var className = _getClassName(classNameExpression);
+
+ var classNameArr = className.split(/\\\\s+/);
+ var style = {};
+ classNameArr.reduce((sty, cls) => Object.assign(sty, _styleSheet[cls.trim()]), style);
+ return style;
+}
+
+function _getModuleClassName(moduleStyle, styleId) {
+ return Object.keys(moduleStyle).reduce((pre, cur) => Object.assign(pre, {
+ [cur]: styleId + '-' + cur
+ }), {});
+}
+
+var styleSheet = _getModuleClassName(_styleSheetModuleStyle, 'styleSheet');
+
+function _mergeStyles() {
+ var newTarget = {};
+
+ for (var index = 0; index < arguments.length; index++) {
+ var [styleSheet, rawStyleName] = arguments[index];
+
+ for (var key in styleSheet) {
+ const _key = rawStyleName ? rawStyleName + '-' + key : key;
+
+ newTarget[_key] = Object.assign(newTarget[_key] || {}, styleSheet[key]);
+ }
+ }
+
+ return newTarget;
+}
+
+var _styleSheet = _mergeStyles([appScssStyleSheet, \\"\\"], [_styleSheetModuleStyle, \\"styleSheet\\"]);
+
+class App extends Component {
+ render() {
+ const a = styleSheet.red;
+ return
;
+ }
+
+}"
+`;
+
+exports[`jsx style plugin Processing module style conditional expression When css module enable 1`] = `
+"import { createElement, Component } from 'rax';
+import appScssStyleSheet from \\"./app.scss\\";
+import _styleSheetModuleStyle from './app.module.scss';
+
+function _getClassName() {
+ var className = [];
+ var args = arguments[0];
+ var type = Object.prototype.toString.call(args).slice(8, -1).toLowerCase();
+
+ if (type === 'string') {
+ args = args.trim();
+ args && className.push(args);
+ } else if (type === 'array') {
+ args.forEach(function (cls) {
+ cls = _getClassName(cls).trim();
+ cls && className.push(cls);
+ });
+ } else if (type === 'object') {
+ for (var k in args) {
+ k = k.trim();
+
+ if (k && args.hasOwnProperty(k) && args[k]) {
+ className.push(k);
+ }
+ }
+ }
+
+ return className.join(' ').trim();
+}
+
+function _getStyle(classNameExpression) {
+ var className = _getClassName(classNameExpression);
+
+ var classNameArr = className.split(/\\\\s+/);
+ var style = {};
+ classNameArr.reduce((sty, cls) => Object.assign(sty, _styleSheet[cls.trim()]), style);
+ return style;
+}
+
+function _getModuleClassName(moduleStyle, styleId) {
+ return Object.keys(moduleStyle).reduce((pre, cur) => Object.assign(pre, {
+ [cur]: styleId + '-' + cur
+ }), {});
+}
+
+var styleSheet = _getModuleClassName(_styleSheetModuleStyle, 'styleSheet');
+
+function _mergeStyles() {
+ var newTarget = {};
+
+ for (var index = 0; index < arguments.length; index++) {
+ var [styleSheet, rawStyleName] = arguments[index];
+
+ for (var key in styleSheet) {
+ const _key = rawStyleName ? rawStyleName + '-' + key : key;
+
+ newTarget[_key] = Object.assign(newTarget[_key] || {}, styleSheet[key]);
+ }
+ }
+
+ return newTarget;
+}
+
+var _styleSheet = _mergeStyles([appScssStyleSheet, \\"\\"], [_styleSheetModuleStyle, \\"styleSheet\\"]);
+
+class App extends Component {
+ render() {
+ const a = 1 ? styleSheet.red : styleSheet.blue;
+ return ;
+ }
+
+}"
+`;
+
+exports[`jsx style plugin Processing module style spread and assign When css module enable 1`] = `
+"import { createElement, Component } from 'rax';
+import appScssStyleSheet from \\"./app.scss\\";
+import _styleSheetModuleStyle from './app.module.scss';
+
+function _getClassName() {
+ var className = [];
+ var args = arguments[0];
+ var type = Object.prototype.toString.call(args).slice(8, -1).toLowerCase();
+
+ if (type === 'string') {
+ args = args.trim();
+ args && className.push(args);
+ } else if (type === 'array') {
+ args.forEach(function (cls) {
+ cls = _getClassName(cls).trim();
+ cls && className.push(cls);
+ });
+ } else if (type === 'object') {
+ for (var k in args) {
+ k = k.trim();
+
+ if (k && args.hasOwnProperty(k) && args[k]) {
+ className.push(k);
+ }
+ }
+ }
+
+ return className.join(' ').trim();
+}
+
+function _getStyle(classNameExpression) {
+ var className = _getClassName(classNameExpression);
+
+ var classNameArr = className.split(/\\\\s+/);
+ var style = {};
+ classNameArr.reduce((sty, cls) => Object.assign(sty, _styleSheet[cls.trim()]), style);
+ return style;
+}
+
+function _getModuleClassName(moduleStyle, styleId) {
+ return Object.keys(moduleStyle).reduce((pre, cur) => Object.assign(pre, {
+ [cur]: styleId + '-' + cur
+ }), {});
+}
+
+var styleSheet = _getModuleClassName(_styleSheetModuleStyle, 'styleSheet');
+
+function _mergeStyles() {
+ var newTarget = {};
+
+ for (var index = 0; index < arguments.length; index++) {
+ var [styleSheet, rawStyleName] = arguments[index];
+
+ for (var key in styleSheet) {
+ const _key = rawStyleName ? rawStyleName + '-' + key : key;
+
+ newTarget[_key] = Object.assign(newTarget[_key] || {}, styleSheet[key]);
+ }
+ }
+
+ return newTarget;
+}
+
+var _styleSheet = _mergeStyles([appScssStyleSheet, \\"\\"], [_styleSheetModuleStyle, \\"styleSheet\\"]);
+
+class App extends Component {
+ render() {
+ const a = { ...styleSheet.red
+ };
+ const b = a;
+ return ;
+ }
+
+}"
+`;
+
+exports[`jsx style plugin Processing module style through call expression When css module enable 1`] = `
+"import { createElement, Component } from 'rax';
+import _styleSheetModuleStyle from './app.module.scss';
+
+function _getClassName() {
+ var className = [];
+ var args = arguments[0];
+ var type = Object.prototype.toString.call(args).slice(8, -1).toLowerCase();
+
+ if (type === 'string') {
+ args = args.trim();
+ args && className.push(args);
+ } else if (type === 'array') {
+ args.forEach(function (cls) {
+ cls = _getClassName(cls).trim();
+ cls && className.push(cls);
+ });
+ } else if (type === 'object') {
+ for (var k in args) {
+ k = k.trim();
+
+ if (k && args.hasOwnProperty(k) && args[k]) {
+ className.push(k);
+ }
+ }
+ }
+
+ return className.join(' ').trim();
+}
+
+function _getStyle(classNameExpression) {
+ var className = _getClassName(classNameExpression);
+
+ var classNameArr = className.split(/\\\\s+/);
+ var style = {};
+ classNameArr.reduce((sty, cls) => Object.assign(sty, _styleSheet[cls.trim()]), style);
+ return style;
+}
+
+function _getModuleClassName(moduleStyle, styleId) {
+ return Object.keys(moduleStyle).reduce((pre, cur) => Object.assign(pre, {
+ [cur]: styleId + '-' + cur
+ }), {});
+}
+
+var styleSheet = _getModuleClassName(_styleSheetModuleStyle, 'styleSheet');
+
+function _mergeStyles() {
+ var newTarget = {};
+
+ for (var index = 0; index < arguments.length; index++) {
+ var [styleSheet, rawStyleName] = arguments[index];
+
+ for (var key in styleSheet) {
+ const _key = rawStyleName ? rawStyleName + '-' + key : key;
+
+ newTarget[_key] = Object.assign(newTarget[_key] || {}, styleSheet[key]);
+ }
+ }
+
+ return newTarget;
+}
+
+var _styleSheet = _mergeStyles([_styleSheetModuleStyle, \\"styleSheet\\"]);
+
+class App extends Component {
+ render() {
+ const a = Object.assign({}, styleSheet.red);
+ const b = Object.assign({}, a);
+ return
;
+ }
+
+}"
+`;
+
+exports[`jsx style plugin Processing multiple module style When css module enable 1`] = `
+"import { createElement, Component } from 'rax';
+import _styleSheetModuleStyle from './app.module.scss';
+import _styleSheet2ModuleStyle from './app2.module.scss';
+
+function _getClassName() {
+ var className = [];
+ var args = arguments[0];
+ var type = Object.prototype.toString.call(args).slice(8, -1).toLowerCase();
+
+ if (type === 'string') {
+ args = args.trim();
+ args && className.push(args);
+ } else if (type === 'array') {
+ args.forEach(function (cls) {
+ cls = _getClassName(cls).trim();
+ cls && className.push(cls);
+ });
+ } else if (type === 'object') {
+ for (var k in args) {
+ k = k.trim();
+
+ if (k && args.hasOwnProperty(k) && args[k]) {
+ className.push(k);
+ }
+ }
+ }
+
+ return className.join(' ').trim();
+}
+
+function _getStyle(classNameExpression) {
+ var className = _getClassName(classNameExpression);
+
+ var classNameArr = className.split(/\\\\s+/);
+ var style = {};
+ classNameArr.reduce((sty, cls) => Object.assign(sty, _styleSheet[cls.trim()]), style);
+ return style;
+}
+
+function _getModuleClassName(moduleStyle, styleId) {
+ return Object.keys(moduleStyle).reduce((pre, cur) => Object.assign(pre, {
+ [cur]: styleId + '-' + cur
+ }), {});
+}
+
+var styleSheet = _getModuleClassName(_styleSheetModuleStyle, 'styleSheet');
+
+var styleSheet2 = _getModuleClassName(_styleSheet2ModuleStyle, 'styleSheet2');
+
+function _mergeStyles() {
+ var newTarget = {};
+
+ for (var index = 0; index < arguments.length; index++) {
+ var [styleSheet, rawStyleName] = arguments[index];
+
+ for (var key in styleSheet) {
+ const _key = rawStyleName ? rawStyleName + '-' + key : key;
+
+ newTarget[_key] = Object.assign(newTarget[_key] || {}, styleSheet[key]);
+ }
+ }
+
+ return newTarget;
+}
+
+var _styleSheet = _mergeStyles([_styleSheetModuleStyle, \\"styleSheet\\"], [_styleSheet2ModuleStyle, \\"styleSheet2\\"]);
+
+class App extends Component {
+ render() {
+ const a = styleSheet.red;
+ return ;
+ }
+
+}"
+`;
+
+exports[`jsx style plugin Provide a default stylesheet object when css module enable and import css module sheet only 1`] = `
+"import { createElement, Component } from 'rax';
+import _styleSheetModuleStyle from './app.module.scss';
+
+function _getClassName() {
+ var className = [];
+ var args = arguments[0];
+ var type = Object.prototype.toString.call(args).slice(8, -1).toLowerCase();
+
+ if (type === 'string') {
+ args = args.trim();
+ args && className.push(args);
+ } else if (type === 'array') {
+ args.forEach(function (cls) {
+ cls = _getClassName(cls).trim();
+ cls && className.push(cls);
+ });
+ } else if (type === 'object') {
+ for (var k in args) {
+ k = k.trim();
+
+ if (k && args.hasOwnProperty(k) && args[k]) {
+ className.push(k);
+ }
+ }
+ }
+
+ return className.join(' ').trim();
+}
+
+function _getStyle(classNameExpression) {
+ var className = _getClassName(classNameExpression);
+
+ var classNameArr = className.split(/\\\\s+/);
+ var style = {};
+ classNameArr.reduce((sty, cls) => Object.assign(sty, _styleSheet[cls.trim()]), style);
+ return style;
+}
+
+function _getModuleClassName(moduleStyle, styleId) {
+ return Object.keys(moduleStyle).reduce((pre, cur) => Object.assign(pre, {
+ [cur]: styleId + '-' + cur
+ }), {});
+}
+
+var styleSheet = _getModuleClassName(_styleSheetModuleStyle, 'styleSheet');
+
+function _mergeStyles() {
+ var newTarget = {};
+
+ for (var index = 0; index < arguments.length; index++) {
+ var [styleSheet, rawStyleName] = arguments[index];
+
+ for (var key in styleSheet) {
+ const _key = rawStyleName ? rawStyleName + '-' + key : key;
+
+ newTarget[_key] = Object.assign(newTarget[_key] || {}, styleSheet[key]);
+ }
+ }
+
+ return newTarget;
+}
+
+var _styleSheet = _mergeStyles([_styleSheetModuleStyle, \\"styleSheet\\"]);
+
+class App extends Component {
+ render() {
+ return ;
+ }
+
+}"
+`;
+
+exports[`jsx style plugin combine multiple anonymous css file 1`] = `
+"import { createElement, Component } from 'rax';
+import app1CssStyleSheet from \\"./app1.css\\";
+import app2CssStyleSheet from \\"./app2.css\\";
+
+function _mergeEleStyles() {
+ return [].concat.apply([], arguments).reduce((pre, cur) => Object.assign(pre, cur), {});
+}
+
+function _mergeStyles() {
+ var newTarget = {};
+
+ for (var index = 0; index < arguments.length; index++) {
+ var [styleSheet, rawStyleName] = arguments[index];
+
+ for (var key in styleSheet) {
+ const _key = rawStyleName ? rawStyleName + '-' + key : key;
+
+ newTarget[_key] = Object.assign(newTarget[_key] || {}, styleSheet[key]);
+ }
+ }
+
+ return newTarget;
+}
+
+var _styleSheet = _mergeStyles([app1CssStyleSheet, \\"\\"], [app2CssStyleSheet, \\"\\"]);
+
+class App extends Component {
+ render() {
+ return ;
+ }
+
+}"
+`;
+
+exports[`jsx style plugin combine multiple different extension style sources 1`] = `
+"import { createElement, render } from 'rax';
+import indexCssStyleSheet from \\"./index.css\\";
+import indexScssStyleSheet from \\"./index.scss\\";
+import indexLessStyleSheet from \\"../index.less\\";
+import styl from \\"./index.styl\\";
+
+function _mergeStyles() {
+ var newTarget = {};
+
+ for (var index = 0; index < arguments.length; index++) {
+ var [styleSheet, rawStyleName] = arguments[index];
+
+ for (var key in styleSheet) {
+ const _key = rawStyleName ? rawStyleName + '-' + key : key;
+
+ newTarget[_key] = Object.assign(newTarget[_key] || {}, styleSheet[key]);
+ }
+ }
+
+ return newTarget;
+}
+
+var _styleSheet = _mergeStyles([indexCssStyleSheet, \\"\\"], [indexScssStyleSheet, \\"\\"], [indexLessStyleSheet, \\"\\"], [styl, \\"\\"]);
+
+render();"
+`;
+
+exports[`jsx style plugin combine multiple styles and className 1`] = `
+"import { createElement, Component } from 'rax';
+import appCssStyleSheet from \\"./app.css\\";
+import style from \\"./style.css\\";
+
+function _mergeEleStyles() {
+ return [].concat.apply([], arguments).reduce((pre, cur) => Object.assign(pre, cur), {});
+}
+
+function _mergeStyles() {
+ var newTarget = {};
+
+ for (var index = 0; index < arguments.length; index++) {
+ var [styleSheet, rawStyleName] = arguments[index];
+
+ for (var key in styleSheet) {
+ const _key = rawStyleName ? rawStyleName + '-' + key : key;
+
+ newTarget[_key] = Object.assign(newTarget[_key] || {}, styleSheet[key]);
+ }
+ }
+
+ return newTarget;
+}
+
+var _styleSheet = _mergeStyles([appCssStyleSheet, \\"\\"], [style, \\"\\"]);
+
+class App extends Component {
+ render() {
+ return ;
+ }
+
+}"
+`;
+
+exports[`jsx style plugin combine one style and className 1`] = `
+"import { createElement, Component } from 'rax';
+import appCssStyleSheet from \\"./app.css\\";
+import style from \\"./style.css\\";
+
+function _mergeEleStyles() {
+ return [].concat.apply([], arguments).reduce((pre, cur) => Object.assign(pre, cur), {});
+}
+
+function _mergeStyles() {
+ var newTarget = {};
+
+ for (var index = 0; index < arguments.length; index++) {
+ var [styleSheet, rawStyleName] = arguments[index];
+
+ for (var key in styleSheet) {
+ const _key = rawStyleName ? rawStyleName + '-' + key : key;
+
+ newTarget[_key] = Object.assign(newTarget[_key] || {}, styleSheet[key]);
+ }
+ }
+
+ return newTarget;
+}
+
+var _styleSheet = _mergeStyles([appCssStyleSheet, \\"\\"], [style, \\"\\"]);
+
+class App extends Component {
+ render() {
+ return ;
+ }
+
+}"
+`;
+
+exports[`jsx style plugin combine the same filename style source 1`] = `
+"import { createElement, Component } from 'rax';
+import appCssStyleSheet from \\"./app.css\\";
+import appCssStyleSheet from \\"../app.css\\";
+
+function _mergeEleStyles() {
+ return [].concat.apply([], arguments).reduce((pre, cur) => Object.assign(pre, cur), {});
+}
+
+function _mergeStyles() {
+ var newTarget = {};
+
+ for (var index = 0; index < arguments.length; index++) {
+ var [styleSheet, rawStyleName] = arguments[index];
+
+ for (var key in styleSheet) {
+ const _key = rawStyleName ? rawStyleName + '-' + key : key;
+
+ newTarget[_key] = Object.assign(newTarget[_key] || {}, styleSheet[key]);
+ }
+ }
+
+ return newTarget;
+}
+
+var _styleSheet = _mergeStyles([appCssStyleSheet, \\"\\"], [appCssStyleSheet, \\"\\"]);
+
+class App extends Component {
+ render() {
+ return ;
+ }
+
+}"
+`;
+
+exports[`jsx style plugin merge stylesheet when css module disable 1`] = `
+"import { createElement, Component } from 'rax';
+import appScssStyleSheet from \\"./app.scss\\";
+import styleSheet from \\"./app.module.scss\\";
+
+function _mergeEleStyles() {
+ return [].concat.apply([], arguments).reduce((pre, cur) => Object.assign(pre, cur), {});
+}
+
+function _mergeStyles() {
+ var newTarget = {};
+
+ for (var index = 0; index < arguments.length; index++) {
+ var [styleSheet, rawStyleName] = arguments[index];
+
+ for (var key in styleSheet) {
+ const _key = rawStyleName ? rawStyleName + '-' + key : key;
+
+ newTarget[_key] = Object.assign(newTarget[_key] || {}, styleSheet[key]);
+ }
+ }
+
+ return newTarget;
+}
+
+var _styleSheet = _mergeStyles([appScssStyleSheet, \\"\\"], [styleSheet, \\"\\"]);
+
+class App extends Component {
+ render() {
+ return ;
+ }
+
+}"
+`;
diff --git a/packages/babel-plugin-transform-react-jsx-to-rn-stylesheet/__tests__/index.spec.js b/packages/babel-plugin-transform-react-jsx-to-rn-stylesheet/__tests__/index.spec.js
index 3d0b2c5af08d..09ef61b5d7ec 100644
--- a/packages/babel-plugin-transform-react-jsx-to-rn-stylesheet/__tests__/index.spec.js
+++ b/packages/babel-plugin-transform-react-jsx-to-rn-stylesheet/__tests__/index.spec.js
@@ -3,20 +3,6 @@ import syntaxJSX from 'babel-plugin-syntax-jsx'
import jSXStylePlugin from '../src/index'
-const mergeStylesFunctionTemplate = `function _mergeStyles() {
- var newTarget = {};
-
- for (var index = 0; index < arguments.length; index++) {
- var target = arguments[index];
-
- for (var key in target) {
- newTarget[key] = Object.assign(newTarget[key] || {}, target[key]);
- }
- }
-
- return newTarget;
-}`
-
const getClassNameFunctionTemplate = `function _getClassName() {
var className = [];
var args = arguments[0];
@@ -183,22 +169,7 @@ class App extends Component {
render() {
return ;
}
-}`)).toBe(`import { createElement, Component } from 'rax';
-import app1CssStyleSheet from "./app1.css";
-import app2CssStyleSheet from "./app2.css";
-
-${mergeEleStylesFunctionTemplate}
-
-${mergeStylesFunctionTemplate}
-
-var _styleSheet = _mergeStyles(app1CssStyleSheet, app2CssStyleSheet);
-
-class App extends Component {
- render() {
- return ;
- }
-
-}`)
+}`)).toMatchSnapshot()
})
it('combine the same filename style source', () => {
@@ -210,22 +181,7 @@ class App extends Component {
render() {
return ;
}
-}`)).toBe(`import { createElement, Component } from 'rax';
-import appCssStyleSheet from "./app.css";
-import appCssStyleSheet1 from "../app.css";
-
-${mergeEleStylesFunctionTemplate}
-
-${mergeStylesFunctionTemplate}
-
-var _styleSheet = _mergeStyles(appCssStyleSheet, appCssStyleSheet1);
-
-class App extends Component {
- render() {
- return ;
- }
-
-}`)
+}`)).toMatchSnapshot()
})
it('combine one style and className', () => {
@@ -237,22 +193,7 @@ class App extends Component {
render() {
return ;
}
-}`)).toBe(`import { createElement, Component } from 'rax';
-import appCssStyleSheet from "./app.css";
-import style from "./style.css";
-
-${mergeEleStylesFunctionTemplate}
-
-${mergeStylesFunctionTemplate}
-
-var _styleSheet = _mergeStyles(appCssStyleSheet, style);
-
-class App extends Component {
- render() {
- return ;
- }
-
-}`)
+}`)).toMatchSnapshot()
})
it('combine inline style object and className', () => {
@@ -292,21 +233,7 @@ class App extends Component {
render() {
return ;
}
-}`)).toBe(`import { createElement, Component } from 'rax';
-import appCssStyleSheet from "./app.css";
-import style from "./style.css";
-
-${mergeEleStylesFunctionTemplate}
-
-${mergeStylesFunctionTemplate}
-
-var _styleSheet = _mergeStyles(appCssStyleSheet, style);
-
-class App extends Component {
- render() {
- return ;
- }\n
-}`)
+}`)).toMatchSnapshot()
})
it('do not transfrom code when no css file', () => {
@@ -406,17 +333,7 @@ import '../index.less'
import styl from './index.styl'
render();
-`)).toBe(`import { createElement, render } from 'rax';
-import indexCssStyleSheet from "./index.css";
-import indexScssStyleSheet from "./index.scss";
-import indexLessStyleSheet from "../index.less";
-import styl from "./index.styl";
-
-${mergeStylesFunctionTemplate}
-
-var _styleSheet = _mergeStyles(indexCssStyleSheet, indexScssStyleSheet, indexLessStyleSheet, styl);
-
-render();`)
+`)).toMatchSnapshot()
})
it('transform styleAttribute expression', () => {
expect(getTransfromCode(`
@@ -472,31 +389,6 @@ render();`)
})
- it('ignore merge stylesheet when css module enable', () => {
- expect(getTransfromCode(`
-import { createElement, Component } from 'rax';
-import './app.scss';
-import styleSheet from './app.module.scss';
-
-class App extends Component {
- render() {
- return ;
- }
-}`, 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 ;
- }\n
-}`)
- })
-
it('Provide a default stylesheet object when css module enable and import css module sheet only', () => {
expect(getTransfromCode(`
import { createElement, Component } from 'rax';
@@ -509,18 +401,7 @@ class App extends Component {
;
}
-}`, false, { enableCSSModule: true })).toBe(`import { createElement, Component } from 'rax';
-import styleSheet from './app.module.scss';
-var _styleSheet = {};
-
-class App extends Component {
- render() {
- return ;
- }\n
-}`)
+}`, false, { enableCSSModule: true })).toMatchSnapshot()
})
it('Processing module style assignment When css module enable', () => {
@@ -534,17 +415,21 @@ class App extends Component {
const a = styleSheet.red
return ;
}
-}`, false, { enableCSSModule: true })).toBe(`import { createElement, Component } from 'rax';
-import appScssStyleSheet from "./app.scss";
+}`, false, { enableCSSModule: true })).toMatchSnapshot()
+ })
+
+ it('Processing multiple module style When css module enable', () => {
+ expect(getTransfromCode(`
+import { createElement, Component } from 'rax';
import styleSheet from './app.module.scss';
-var _styleSheet = appScssStyleSheet;
+import styleSheet2 from './app2.module.scss';
class App extends Component {
render() {
- const a = styleSheet.red;
- return ;
- }\n
-}`)
+ const a = styleSheet.red
+ return ;
+ }
+}`, false, { enableCSSModule: true })).toMatchSnapshot()
})
it('Processing module style spread and assign When css module enable', () => {
@@ -559,20 +444,7 @@ class App extends Component {
const b = a;
return ;
}
-}`, false, { enableCSSModule: true })).toBe(`import { createElement, Component } from 'rax';
-import appScssStyleSheet from "./app.scss";
-import styleSheet from './app.module.scss';
-var _styleSheet = appScssStyleSheet;
-
-class App extends Component {
- render() {
- const a = { ...styleSheet.red
- };
- const b = a;
- return ;
- }\n
-}`)
+}`, false, { enableCSSModule: true })).toMatchSnapshot()
})
it('Processing module style conditional expression When css module enable', () => {
@@ -586,17 +458,7 @@ class App extends Component {
const a = 1 ? styleSheet.red : styleSheet.blue;
return ;
}
-}`, false, { enableCSSModule: true })).toBe(`import { createElement, Component } from 'rax';
-import appScssStyleSheet from "./app.scss";
-import styleSheet from './app.module.scss';
-var _styleSheet = appScssStyleSheet;
-
-class App extends Component {
- render() {
- const a = 1 ? styleSheet.red : styleSheet.blue;
- return ;
- }\n
-}`)
+}`, false, { enableCSSModule: true })).toMatchSnapshot()
})
it('Processing module style through call expression When css module enable', () => {
@@ -610,17 +472,7 @@ class App extends Component {
const b = Object.assign({}, a);
return
;
}
-}`, false, { enableCSSModule: true })).toBe(`import { createElement, Component } from 'rax';
-import styleSheet from './app.module.scss';
-var _styleSheet = {};
-
-class App extends Component {
- render() {
- const a = Object.assign({}, styleSheet.red);
- const b = Object.assign({}, a);
- return
;
- }\n
-}`)
+}`, false, { enableCSSModule: true })).toMatchSnapshot()
})
it('merge stylesheet when css module disable', () => {
@@ -633,21 +485,7 @@ class App extends Component {
render() {
return ;
}
-}`)).toBe(`import { createElement, Component } from 'rax';
-import appScssStyleSheet from "./app.scss";
-import styleSheet from "./app.module.scss";
-
-${mergeEleStylesFunctionTemplate}
-
-${mergeStylesFunctionTemplate}
-
-var _styleSheet = _mergeStyles(appScssStyleSheet, styleSheet);
-
-class App extends Component {
- render() {
- return ;
- }\n
-}`)
+}`)).toMatchSnapshot()
})
it('disableMultipleClassName and transform multiple className to multiple style', () => {
diff --git a/packages/babel-plugin-transform-react-jsx-to-rn-stylesheet/src/index.ts b/packages/babel-plugin-transform-react-jsx-to-rn-stylesheet/src/index.ts
index 1b4129b38138..a387e69ca141 100644
--- a/packages/babel-plugin-transform-react-jsx-to-rn-stylesheet/src/index.ts
+++ b/packages/babel-plugin-transform-react-jsx-to-rn-stylesheet/src/index.ts
@@ -9,6 +9,7 @@ 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_MODULE_CLS_NAME_FUNC_NAME = '_getModuleClassName'
const GET_CLS_NAME_FUNC_NAME = '_getClassName'
const NAME_SUFFIX = 'styleSheet'
@@ -60,14 +61,14 @@ function findLastImportIndex (body) {
}
const MergeStylesFunction = `
-function _mergeStyles() {
+function ${MERGE_STYLES_FUNC_NAME}() {
var newTarget = {};
-
for (var index = 0; index < arguments.length; index++) {
- var target = arguments[index];
+ var [styleSheet, rawStyleName] = arguments[index];
- for (var key in target) {
- newTarget[key] = Object.assign(newTarget[key] || {}, target[key]);
+ for (var key in styleSheet) {
+ const _key = rawStyleName ? rawStyleName + '-' + key : key
+ newTarget[_key] = Object.assign(newTarget[_key] || {}, styleSheet[key]);
}
}
@@ -115,6 +116,15 @@ function ${GET_STYLE_FUNC_NAME}(classNameExpression) {
return style;
}
`
+const getModuleClassNameFunction = `
+function ${GET_MODULE_CLS_NAME_FUNC_NAME}(moduleStyle, styleId) {
+ return Object.keys(moduleStyle).reduce((pre, cur) => (
+ Object.assign(pre, {
+ [cur]: styleId + '-' + cur
+ })
+ ), {})
+}
+`
export default function (babel: {
types: typeof Types
@@ -128,6 +138,9 @@ export default function (babel: {
const getMergeEleStyleFunctionStmt = template(getMergeEleStyleFunction)()
+ const getModuleClassNameFunctionStmt = template(getModuleClassNameFunction)()
+
+
function getMap (str) {
return str.split(/\s+/).map((className) => {
// return template(`${STYLE_SHEET_NAME}["${className}"]`)().expression
@@ -138,88 +151,7 @@ export default function (babel: {
})
}
- function isCSSMemberOrBindings (expression, cssModuleStylesheets, astPath) {
- if (t.isIdentifier(expression)) {
- if (cssModuleStylesheets.includes(expression.name)) {
- return true
- } else {
- const binding = astPath.scope.getBinding(expression.name)
- if (binding) {
- const { node } = binding.path
- if (isCSSMemberOrBindings(node.init, cssModuleStylesheets, astPath)) {
- return true
- }
- }
- }
- }
-
- // assign 属性引用
- if (t.isMemberExpression(expression) && t.isIdentifier(expression.object)) {
- if (cssModuleStylesheets.includes(expression.object.name)) {
- return true
- } else {
- const binding = astPath.scope.getBinding(expression.object.name)
- if (binding) {
- const { node } = binding.path
- if (isCSSMemberOrBindings(node.init, cssModuleStylesheets, astPath)) {
- return true
- }
- }
- }
- }
-
- // Conditional_Operator 条件(三元)运算符
- if (t.isConditionalExpression(expression)) {
- const { consequent, alternate } = expression
- if (
- isCSSMemberOrBindings(consequent, cssModuleStylesheets, astPath) ||
- isCSSMemberOrBindings(alternate, cssModuleStylesheets, astPath)
- ) {
- return true
- }
- }
-
- // spread 解构
- if (t.isObjectExpression(expression)) {
- for (const prop of expression.properties) {
- if (t.isSpreadElement(prop)) {
- if (isCSSMemberOrBindings(prop.argument, cssModuleStylesheets, astPath)) {
- return true
- }
- }
- }
- }
-
- // 函数调用
- // some call expression args references like Object.assign or @babel/runtime/helpers/extends
- if (t.isCallExpression(expression)) {
- const { arguments: args } = expression
- for (const arg of args) {
- if (isCSSMemberOrBindings(arg, cssModuleStylesheets, astPath)) {
- return true
- }
- }
- }
- }
-
- function isJSXCSSModuleExpression (value, cssModuleStylesheets, astPath) {
- if (t.isJSXExpressionContainer(value)) {
- // 1. memberExpression a. 导入. b. 赋值. like `className="{style.red}"` or `const a = style; className="{a.red}"`
- // 2. spread like `className="{{ ...style.red }}"`
- // 3. memberExpression and spread. like `const a = { ...style }; className="{a.red}"
-
- if (isCSSMemberOrBindings(value.expression, cssModuleStylesheets, astPath)) {
- return true
- }
- }
- }
-
- function getArrayExpression (value, cssModuleStylesheets, astPath) {
- // css module 时 className 处理成 style 属性,所以直接取值跟 style 合并
- if (isJSXCSSModuleExpression(value, cssModuleStylesheets, astPath)) {
- return [value.expression]
- }
-
+ function getArrayExpression (value) {
let str
if (!value || value.value === '') {
@@ -274,12 +206,14 @@ export default function (babel: {
if (existStyleImport) {
const { file } = state
const styleSheetIdentifiers = file.get('styleSheetIdentifiers') || []
+ const cssModuleStylesheets = file.get('cssModuleStylesheets') || []
+ const allStyleSheetIdentifiers = [...styleSheetIdentifiers, ...cssModuleStylesheets]
let expression
// only one css file,由于样式文件合并,永远只有一个
- if (styleSheetIdentifiers.length === 1) {
- expression = `var ${STYLE_SHEET_NAME} = ${styleSheetIdentifiers[0].name};\n`
- } else if (styleSheetIdentifiers.length > 1) {
- const params = styleSheetIdentifiers.reduce((current, next) => `${current},${next.name}`, '').slice(1)
+ if (allStyleSheetIdentifiers.length === 1 && styleSheetIdentifiers.length === 1) {
+ expression = `var ${STYLE_SHEET_NAME} = ${allStyleSheetIdentifiers[0].styleSheetName};\n`
+ } else if (allStyleSheetIdentifiers.length >= 1) {
+ const params = allStyleSheetIdentifiers.reduce((current, next) => `${current},[${next.styleSheetName}, "${next.rawStyleSheetName || ''}"]`, '').slice(1)
expression = `${MergeStylesFunction}\n
var ${STYLE_SHEET_NAME} = ${MERGE_STYLES_FUNC_NAME}(${params});\n`
} else {
@@ -293,6 +227,7 @@ export default function (babel: {
const { file } = state
const node = astPath.node
const injectGetStyle = file.get('injectGetStyle')
+ const cssModuleStylesheets = file.get('cssModuleStylesheets') || []
// 从最后一个import 开始插入表达式,后续插入的表达式追加在后面
let lastImportIndex = findLastImportIndex(node.body)
if (injectGetStyle) {
@@ -305,6 +240,16 @@ export default function (babel: {
// @ts-ignore
node.body.splice(++lastImportIndex, 0, getMergeEleStyleFunctionStmt)
}
+ // 将 styleSheet 转为 {[classname]: classname}
+ if (cssModuleStylesheets.length) {
+ // @ts-ignore
+ node.body.splice(++lastImportIndex, 0, getModuleClassNameFunctionStmt)
+ cssModuleStylesheets.forEach(({ styleSheetName, rawStyleSheetName }) => {
+ const functionTempalte = `var ${rawStyleSheetName} = ${GET_MODULE_CLS_NAME_FUNC_NAME}(${styleSheetName}, '${rawStyleSheetName}')`
+ // @ts-ignore
+ node.body.splice(++lastImportIndex, 0, template(functionTempalte)())
+ })
+ }
existStyleImport = false
}
},
@@ -313,7 +258,6 @@ export default function (babel: {
const { file, opts = {} } = state
const { enableMultipleClassName = false } = opts
const { styleMatchRule, classNameMathRule } = getMatchRule(enableMultipleClassName)
- const cssModuleStylesheets = file.get('cssModuleStylesheets') || []
const styleNameMapping: any = {}
const DEFAULT_STYLE_KEY = 'style'
@@ -342,8 +286,16 @@ export default function (babel: {
})
}
}
+
for (const key in styleNameMapping) {
const { hasClassName, classNameAttribute, hasStyleAttribute, styleAttribute } = styleNameMapping[key]
+ if (!(hasClassName && existStyleImport) && hasStyleAttribute) {
+ if (t.isStringLiteral(styleAttribute.value)) {
+ const cssObject = string2Object(styleAttribute.value.value)
+ styleAttribute.value = t.jSXExpressionContainer(object2Expression(template, cssObject))
+ }
+ }
+
if (hasClassName && existStyleImport) {
// Remove origin className
attributes.splice(attributes.indexOf(classNameAttribute), 1)
@@ -351,13 +303,12 @@ export default function (babel: {
if (
classNameAttribute.value &&
classNameAttribute.value.type === 'JSXExpressionContainer' &&
- typeof classNameAttribute.value.expression.value !== 'string' && // not like className={'container'}
- !isJSXCSSModuleExpression(classNameAttribute.value, cssModuleStylesheets, astPath) // 不含有 css module 变量的表达式
+ typeof classNameAttribute.value.expression.value !== 'string'// not like className={'container'}
) {
file.set('injectGetStyle', true)
}
- const arrayExpression = getArrayExpression(classNameAttribute.value, cssModuleStylesheets, astPath)
+ const arrayExpression = getArrayExpression(classNameAttribute.value)
if (arrayExpression.length === 0) {
return
@@ -401,11 +352,6 @@ export default function (babel: {
: arrayExpression[0]
attributes.push(t.jSXAttribute(t.jSXIdentifier(key === DEFAULT_STYLE_KEY ? key : (key + 'Style')), t.jSXExpressionContainer(expression)))
}
- } else if (hasStyleAttribute) {
- if (t.isStringLiteral(styleAttribute.value)) {
- const cssObject = string2Object(styleAttribute.value.value)
- styleAttribute.value = t.jSXExpressionContainer(object2Expression(template, cssObject))
- }
}
}
}
@@ -435,7 +381,13 @@ function importDeclaration (astPath, state, t) {
if (enableCSSModule && isModuleSource(sourceValue)) {
if (styleSheetName) {
- cssModuleStylesheets.push(styleSheetName)
+ const moduleStyleSheetName = astPath.scope.generateUid(`${styleSheetName}ModuleStyle`)
+ specifiers[0].local.name = moduleStyleSheetName
+ // 保留原始引用的 name
+ cssModuleStylesheets.push({
+ styleSheetName: moduleStyleSheetName,
+ rawStyleSheetName: styleSheetName
+ })
}
} else {
const cssFileName = path.basename(sourceValue)
@@ -455,7 +407,9 @@ function importDeclaration (astPath, state, t) {
node.specifiers = [t.importDefaultSpecifier(styleSheetIdentifier)]
node.source = t.stringLiteral(styleSheetSource)
- styleSheetIdentifiers.push(styleSheetIdentifier)
+ styleSheetIdentifiers.push({
+ styleSheetName: styleSheetIdentifier.name
+ })
}
}