babel-plugin-transform-react-jsx-to-rn-stylesheet 3.5.4 → 3.5.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/index.ts CHANGED
@@ -9,6 +9,7 @@ const STYLE_SHEET_NAME = '_styleSheet'
9
9
  const GET_STYLE_FUNC_NAME = '_getStyle'
10
10
  const MERGE_STYLES_FUNC_NAME = '_mergeStyles'
11
11
  const MERGE_ELE_STYLES_FUNC_NAME = '_mergeEleStyles'
12
+ const GET_MODULE_CLS_NAME_FUNC_NAME = '_getModuleClassName'
12
13
 
13
14
  const GET_CLS_NAME_FUNC_NAME = '_getClassName'
14
15
  const NAME_SUFFIX = 'styleSheet'
@@ -60,14 +61,14 @@ function findLastImportIndex (body) {
60
61
  }
61
62
 
62
63
  const MergeStylesFunction = `
63
- function _mergeStyles() {
64
+ function ${MERGE_STYLES_FUNC_NAME}() {
64
65
  var newTarget = {};
65
-
66
66
  for (var index = 0; index < arguments.length; index++) {
67
- var target = arguments[index];
67
+ var [styleSheet, rawStyleName] = arguments[index];
68
68
 
69
- for (var key in target) {
70
- newTarget[key] = Object.assign(newTarget[key] || {}, target[key]);
69
+ for (var key in styleSheet) {
70
+ const _key = rawStyleName ? rawStyleName + '-' + key : key
71
+ newTarget[_key] = Object.assign(newTarget[_key] || {}, styleSheet[key]);
71
72
  }
72
73
  }
73
74
 
@@ -115,6 +116,15 @@ function ${GET_STYLE_FUNC_NAME}(classNameExpression) {
115
116
  return style;
116
117
  }
117
118
  `
119
+ const getModuleClassNameFunction = `
120
+ function ${GET_MODULE_CLS_NAME_FUNC_NAME}(moduleStyle, styleId) {
121
+ return Object.keys(moduleStyle).reduce((pre, cur) => (
122
+ Object.assign(pre, {
123
+ [cur]: styleId + '-' + cur
124
+ })
125
+ ), {})
126
+ }
127
+ `
118
128
 
119
129
  export default function (babel: {
120
130
  types: typeof Types
@@ -128,6 +138,9 @@ export default function (babel: {
128
138
 
129
139
  const getMergeEleStyleFunctionStmt = template(getMergeEleStyleFunction)()
130
140
 
141
+ const getModuleClassNameFunctionStmt = template(getModuleClassNameFunction)()
142
+
143
+
131
144
  function getMap (str) {
132
145
  return str.split(/\s+/).map((className) => {
133
146
  // return template(`${STYLE_SHEET_NAME}["${className}"]`)().expression
@@ -138,88 +151,7 @@ export default function (babel: {
138
151
  })
139
152
  }
140
153
 
141
- function isCSSMemberOrBindings (expression, cssModuleStylesheets, astPath) {
142
- if (t.isIdentifier(expression)) {
143
- if (cssModuleStylesheets.includes(expression.name)) {
144
- return true
145
- } else {
146
- const binding = astPath.scope.getBinding(expression.name)
147
- if (binding) {
148
- const { node } = binding.path
149
- if (isCSSMemberOrBindings(node.init, cssModuleStylesheets, astPath)) {
150
- return true
151
- }
152
- }
153
- }
154
- }
155
-
156
- // assign 属性引用
157
- if (t.isMemberExpression(expression) && t.isIdentifier(expression.object)) {
158
- if (cssModuleStylesheets.includes(expression.object.name)) {
159
- return true
160
- } else {
161
- const binding = astPath.scope.getBinding(expression.object.name)
162
- if (binding) {
163
- const { node } = binding.path
164
- if (isCSSMemberOrBindings(node.init, cssModuleStylesheets, astPath)) {
165
- return true
166
- }
167
- }
168
- }
169
- }
170
-
171
- // Conditional_Operator 条件(三元)运算符
172
- if (t.isConditionalExpression(expression)) {
173
- const { consequent, alternate } = expression
174
- if (
175
- isCSSMemberOrBindings(consequent, cssModuleStylesheets, astPath) ||
176
- isCSSMemberOrBindings(alternate, cssModuleStylesheets, astPath)
177
- ) {
178
- return true
179
- }
180
- }
181
-
182
- // spread 解构
183
- if (t.isObjectExpression(expression)) {
184
- for (const prop of expression.properties) {
185
- if (t.isSpreadElement(prop)) {
186
- if (isCSSMemberOrBindings(prop.argument, cssModuleStylesheets, astPath)) {
187
- return true
188
- }
189
- }
190
- }
191
- }
192
-
193
- // 函数调用
194
- // some call expression args references like Object.assign or @babel/runtime/helpers/extends
195
- if (t.isCallExpression(expression)) {
196
- const { arguments: args } = expression
197
- for (const arg of args) {
198
- if (isCSSMemberOrBindings(arg, cssModuleStylesheets, astPath)) {
199
- return true
200
- }
201
- }
202
- }
203
- }
204
-
205
- function isJSXCSSModuleExpression (value, cssModuleStylesheets, astPath) {
206
- if (t.isJSXExpressionContainer(value)) {
207
- // 1. memberExpression a. 导入. b. 赋值. like `className="{style.red}"` or `const a = style; className="{a.red}"`
208
- // 2. spread like `className="{{ ...style.red }}"`
209
- // 3. memberExpression and spread. like `const a = { ...style }; className="{a.red}"
210
-
211
- if (isCSSMemberOrBindings(value.expression, cssModuleStylesheets, astPath)) {
212
- return true
213
- }
214
- }
215
- }
216
-
217
- function getArrayExpression (value, cssModuleStylesheets, astPath) {
218
- // css module 时 className 处理成 style 属性,所以直接取值跟 style 合并
219
- if (isJSXCSSModuleExpression(value, cssModuleStylesheets, astPath)) {
220
- return [value.expression]
221
- }
222
-
154
+ function getArrayExpression (value) {
223
155
  let str
224
156
 
225
157
  if (!value || value.value === '') {
@@ -274,12 +206,14 @@ export default function (babel: {
274
206
  if (existStyleImport) {
275
207
  const { file } = state
276
208
  const styleSheetIdentifiers = file.get('styleSheetIdentifiers') || []
209
+ const cssModuleStylesheets = file.get('cssModuleStylesheets') || []
210
+ const allStyleSheetIdentifiers = [...styleSheetIdentifiers, ...cssModuleStylesheets]
277
211
  let expression
278
212
  // only one css file,由于样式文件合并,永远只有一个
279
- if (styleSheetIdentifiers.length === 1) {
280
- expression = `var ${STYLE_SHEET_NAME} = ${styleSheetIdentifiers[0].name};\n`
281
- } else if (styleSheetIdentifiers.length > 1) {
282
- const params = styleSheetIdentifiers.reduce((current, next) => `${current},${next.name}`, '').slice(1)
213
+ if (allStyleSheetIdentifiers.length === 1 && styleSheetIdentifiers.length === 1) {
214
+ expression = `var ${STYLE_SHEET_NAME} = ${allStyleSheetIdentifiers[0].styleSheetName};\n`
215
+ } else if (allStyleSheetIdentifiers.length >= 1) {
216
+ const params = allStyleSheetIdentifiers.reduce((current, next) => `${current},[${next.styleSheetName}, "${next.rawStyleSheetName || ''}"]`, '').slice(1)
283
217
  expression = `${MergeStylesFunction}\n
284
218
  var ${STYLE_SHEET_NAME} = ${MERGE_STYLES_FUNC_NAME}(${params});\n`
285
219
  } else {
@@ -293,6 +227,7 @@ export default function (babel: {
293
227
  const { file } = state
294
228
  const node = astPath.node
295
229
  const injectGetStyle = file.get('injectGetStyle')
230
+ const cssModuleStylesheets = file.get('cssModuleStylesheets') || []
296
231
  // 从最后一个import 开始插入表达式,后续插入的表达式追加在后面
297
232
  let lastImportIndex = findLastImportIndex(node.body)
298
233
  if (injectGetStyle) {
@@ -305,6 +240,16 @@ export default function (babel: {
305
240
  // @ts-ignore
306
241
  node.body.splice(++lastImportIndex, 0, getMergeEleStyleFunctionStmt)
307
242
  }
243
+ // 将 styleSheet 转为 {[classname]: classname}
244
+ if (cssModuleStylesheets.length) {
245
+ // @ts-ignore
246
+ node.body.splice(++lastImportIndex, 0, getModuleClassNameFunctionStmt)
247
+ cssModuleStylesheets.forEach(({ styleSheetName, rawStyleSheetName }) => {
248
+ const functionTempalte = `var ${rawStyleSheetName} = ${GET_MODULE_CLS_NAME_FUNC_NAME}(${styleSheetName}, '${rawStyleSheetName}')`
249
+ // @ts-ignore
250
+ node.body.splice(++lastImportIndex, 0, template(functionTempalte)())
251
+ })
252
+ }
308
253
  existStyleImport = false
309
254
  }
310
255
  },
@@ -313,7 +258,6 @@ export default function (babel: {
313
258
  const { file, opts = {} } = state
314
259
  const { enableMultipleClassName = false } = opts
315
260
  const { styleMatchRule, classNameMathRule } = getMatchRule(enableMultipleClassName)
316
- const cssModuleStylesheets = file.get('cssModuleStylesheets') || []
317
261
 
318
262
  const styleNameMapping: any = {}
319
263
  const DEFAULT_STYLE_KEY = 'style'
@@ -342,8 +286,16 @@ export default function (babel: {
342
286
  })
343
287
  }
344
288
  }
289
+
345
290
  for (const key in styleNameMapping) {
346
291
  const { hasClassName, classNameAttribute, hasStyleAttribute, styleAttribute } = styleNameMapping[key]
292
+ if (!(hasClassName && existStyleImport) && hasStyleAttribute) {
293
+ if (t.isStringLiteral(styleAttribute.value)) {
294
+ const cssObject = string2Object(styleAttribute.value.value)
295
+ styleAttribute.value = t.jSXExpressionContainer(object2Expression(template, cssObject))
296
+ }
297
+ }
298
+
347
299
  if (hasClassName && existStyleImport) {
348
300
  // Remove origin className
349
301
  attributes.splice(attributes.indexOf(classNameAttribute), 1)
@@ -351,13 +303,12 @@ export default function (babel: {
351
303
  if (
352
304
  classNameAttribute.value &&
353
305
  classNameAttribute.value.type === 'JSXExpressionContainer' &&
354
- typeof classNameAttribute.value.expression.value !== 'string' && // not like className={'container'}
355
- !isJSXCSSModuleExpression(classNameAttribute.value, cssModuleStylesheets, astPath) // 不含有 css module 变量的表达式
306
+ typeof classNameAttribute.value.expression.value !== 'string'// not like className={'container'}
356
307
  ) {
357
308
  file.set('injectGetStyle', true)
358
309
  }
359
310
 
360
- const arrayExpression = getArrayExpression(classNameAttribute.value, cssModuleStylesheets, astPath)
311
+ const arrayExpression = getArrayExpression(classNameAttribute.value)
361
312
 
362
313
  if (arrayExpression.length === 0) {
363
314
  return
@@ -401,11 +352,6 @@ export default function (babel: {
401
352
  : arrayExpression[0]
402
353
  attributes.push(t.jSXAttribute(t.jSXIdentifier(key === DEFAULT_STYLE_KEY ? key : (key + 'Style')), t.jSXExpressionContainer(expression)))
403
354
  }
404
- } else if (hasStyleAttribute) {
405
- if (t.isStringLiteral(styleAttribute.value)) {
406
- const cssObject = string2Object(styleAttribute.value.value)
407
- styleAttribute.value = t.jSXExpressionContainer(object2Expression(template, cssObject))
408
- }
409
355
  }
410
356
  }
411
357
  }
@@ -435,7 +381,13 @@ function importDeclaration (astPath, state, t) {
435
381
 
436
382
  if (enableCSSModule && isModuleSource(sourceValue)) {
437
383
  if (styleSheetName) {
438
- cssModuleStylesheets.push(styleSheetName)
384
+ const moduleStyleSheetName = astPath.scope.generateUid(`${styleSheetName}ModuleStyle`)
385
+ specifiers[0].local.name = moduleStyleSheetName
386
+ // 保留原始引用的 name
387
+ cssModuleStylesheets.push({
388
+ styleSheetName: moduleStyleSheetName,
389
+ rawStyleSheetName: styleSheetName
390
+ })
439
391
  }
440
392
  } else {
441
393
  const cssFileName = path.basename(sourceValue)
@@ -455,7 +407,9 @@ function importDeclaration (astPath, state, t) {
455
407
 
456
408
  node.specifiers = [t.importDefaultSpecifier(styleSheetIdentifier)]
457
409
  node.source = t.stringLiteral(styleSheetSource)
458
- styleSheetIdentifiers.push(styleSheetIdentifier)
410
+ styleSheetIdentifiers.push({
411
+ styleSheetName: styleSheetIdentifier.name
412
+ })
459
413
  }
460
414
  }
461
415