@cssxjs/babel-plugin-rn-stylename-to-style 0.2.14 → 0.2.16

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/CHANGELOG.md CHANGED
@@ -1,3 +1,27 @@
1
+ # v0.2.16 (Sun Nov 09 2025)
2
+
3
+ #### 🚀 Enhancement
4
+
5
+ - feat(babel-plugin-rn-stylename-to-style): Support compiling css file imports in Babel itself ([@cray0000](https://github.com/cray0000))
6
+
7
+ #### Authors: 1
8
+
9
+ - Pavel Zhukov ([@cray0000](https://github.com/cray0000))
10
+
11
+ ---
12
+
13
+ # v0.2.15 (Sun Nov 09 2025)
14
+
15
+ #### 🐛 Bug Fix
16
+
17
+ - fix(babel-plugin-rn-stylename-to-style): remove teamplay from peer deps ([@cray0000](https://github.com/cray0000))
18
+
19
+ #### Authors: 1
20
+
21
+ - Pavel Zhukov ([@cray0000](https://github.com/cray0000))
22
+
23
+ ---
24
+
1
25
  # v0.2.14 (Sat Nov 08 2025)
2
26
 
3
27
  #### 🐛 Bug Fix
package/README.md CHANGED
@@ -113,12 +113,19 @@ List of css extensions to process (`css`, `styl`, `sass`, etc.)
113
113
 
114
114
  Whether to generate ESM `import` instead of CJS `require`.
115
115
 
116
- #### `parseJson`
116
+ #### `compileCssImports`
117
117
 
118
- **Default:** `false`
118
+ **Default:** `true`
119
+
120
+ Whether to pre-process the css file imports, like `import './index.styl'` by this babel
121
+ plugin itself, instead of passing it further to the bundler to compile.
122
+ Note that if Babel is responsible for compiling these files then the changes in then
123
+ are not gonna be reactive and to see changes made to the separate CSS file
124
+ you would need to restart the whole bundling with an option to clear the Babel cache.
119
125
 
120
- Whether the imported css is expected to be a JSON string or an object.
121
- If this flag is specified then JSON string is expected and it will do `JSON.parse` on it.
126
+ Storing styles in separate files should be avoided though, you should try to only
127
+ use it when importing some 3rd party libraries or for you global theme definitions,
128
+ so these files shouldn't frequently change.
122
129
 
123
130
  #### `cache`
124
131
 
package/index.js CHANGED
@@ -1,11 +1,14 @@
1
1
  const nodePath = require('path')
2
+ const fs = require('fs')
2
3
  const t = require('@babel/types')
3
4
  const template = require('@babel/template').default
5
+ const parser = require('@babel/parser')
4
6
  const { GLOBAL_NAME, LOCAL_NAME } = require('@cssxjs/runtime/constants')
5
7
  const { addNamed } = require('@babel/helper-module-imports')
6
8
 
7
- const COMPILERS = ['css', 'styl', 'pug'] // used in rn-stylename-inline. TODO: move to a shared place
9
+ const COMPILERS = require('@cssxjs/loaders/compilers')
8
10
  const RUNTIME_LIBRARY = 'cssxjs/runtime'
11
+ const DEFAULT_PLATFORM = 'web'
9
12
  const STYLE_NAME_REGEX = /(?:^s|S)tyleName$/
10
13
  const STYLE_REGEX = /(?:^s|S)tyle$/
11
14
  const ROOT_STYLE_PROP_NAME = 'style'
@@ -21,18 +24,19 @@ const buildSafeVar = template.expression(`
21
24
  typeof %%variable%% !== 'undefined' && %%variable%%
22
25
  `)
23
26
 
24
- const buildJsonParse = template(`
25
- const %%name%% = JSON.parse(%%jsonStyle%%)
26
- `)
27
-
28
27
  const buildRuntimeVar = template(`
29
28
  const %%name%% = %%imported%%
30
29
  `)
31
30
 
31
+ const buildConst = template(`
32
+ const %%variable%% = %%value%%
33
+ `)
34
+
32
35
  module.exports = function (babel) {
33
36
  let styleHash = {}
34
37
  let cssIdentifier
35
38
  let hasObserver
39
+ let hasFrameworkImport
36
40
  let $program
37
41
  let usedCompilers
38
42
  let runtime
@@ -267,6 +271,7 @@ module.exports = function (babel) {
267
271
  styleHash = {}
268
272
  cssIdentifier = undefined
269
273
  hasObserver = undefined
274
+ hasFrameworkImport = undefined
270
275
  $program = undefined
271
276
  usedCompilers = undefined
272
277
  runtime = undefined
@@ -282,7 +287,11 @@ module.exports = function (babel) {
282
287
  // 2. Run early traversal of everything
283
288
  $this.traverse({
284
289
  ImportDeclaration ($this, state) {
290
+ // refactor this to check if we have the magic import and observer in Program:enter
291
+ // since there is now a race condition - if observer import is after css file import
292
+ // then it won't be detected
285
293
  if (!hasObserver) hasObserver = checkObserverImport($this, state)
294
+ if (!hasFrameworkImport) hasFrameworkImport = checkHasFrameworkImport($this, state)
286
295
 
287
296
  const extensions =
288
297
  Array.isArray(state.opts.extensions) &&
@@ -299,6 +308,7 @@ module.exports = function (babel) {
299
308
  if (extensions.indexOf(getExt(node)) === -1) {
300
309
  return
301
310
  }
311
+ const extension = getExt(node)
302
312
 
303
313
  const anonymousImports = $this.container.filter(n => {
304
314
  return (
@@ -323,26 +333,44 @@ module.exports = function (babel) {
323
333
  node.specifiers = [specifier]
324
334
  }
325
335
 
326
- cssIdentifier = specifier.local
327
-
328
- // Do JSON.parse() on the css file if we receive it as a json string:
329
- // import css from './index.styl'
330
- // v v v
331
- // import jsonCss from './index.styl'
332
- // const css = JSON.parse(jsonCss)
333
- if (state.opts.parseJson) {
334
- const lastImportOrRequire = $program
335
- .get('body')
336
- .filter(p => p.isImportDeclaration() || isRequire(p.node))
337
- .pop()
338
- const tempCssIdentifier = $this.scope.generateUidIdentifier('jsonCss')
339
- node.specifiers[0].local = tempCssIdentifier
340
- lastImportOrRequire.insertAfter(
341
- buildJsonParse({
342
- name: cssIdentifier,
343
- jsonStyle: tempCssIdentifier
344
- })
336
+ const compileCssImports = state.opts.compileCssImports ?? true
337
+ // if we compile css imports, we need to replace the import with a variable declaration
338
+ if (compileCssImports) {
339
+ const localName = specifier.local.name
340
+ const filename = state.file?.opts?.filename
341
+ const platform = state.opts?.platform || state.file?.opts?.caller?.platform || DEFAULT_PLATFORM
342
+ // resolve the full path to the style file relative to the current file
343
+ const styleFilepath = nodePath.resolve(
344
+ nodePath.dirname(filename),
345
+ node.source.value
345
346
  )
347
+ // read the style file content
348
+ const styleFileContent = fs.readFileSync(styleFilepath, 'utf8')
349
+ // find the appropriate compiler
350
+ const compiler = COMPILERS[extension]
351
+ if (!compiler) {
352
+ throw $this.buildCodeFrameError(
353
+ `No compiler found for imported extension: "${extension}"`
354
+ )
355
+ }
356
+ const compiledString = compiler(
357
+ styleFileContent,
358
+ styleFilepath,
359
+ { platform }
360
+ )
361
+ const compiledExpression = parser.parseExpression(compiledString)
362
+
363
+ cssIdentifier = t.identifier(localName)
364
+ const varDeclaration = buildConst({
365
+ variable: cssIdentifier,
366
+ value: compiledExpression
367
+ })
368
+ insertAfterImports($program, varDeclaration)
369
+ // remove the original import and insert the variable declaration instead
370
+ $this.remove()
371
+ } else {
372
+ // otherwise just keep the import as is
373
+ cssIdentifier = specifier.local
346
374
  }
347
375
  },
348
376
  JSXOpeningElement: {
@@ -412,10 +440,6 @@ module.exports = function (babel) {
412
440
  }
413
441
  }
414
442
 
415
- function isRequire (node) {
416
- return node?.declarations?.[0]?.init?.callee?.name === 'require'
417
- }
418
-
419
443
  function getExt (node) {
420
444
  return nodePath.extname(node.source.value).replace(/^\./, '')
421
445
  }
@@ -515,6 +539,11 @@ function checkObserverImport ($import, state) {
515
539
  }
516
540
  }
517
541
 
542
+ function checkHasFrameworkImport ($import, state) {
543
+ const magicImports = state.opts.magicImports || DEFAULT_MAGIC_IMPORTS
544
+ return magicImports.includes($import.node.source.value)
545
+ }
546
+
518
547
  // find topmost function (which is not a lowercase named one).
519
548
  // .getFunctionParent() returns undefined when we reach Program
520
549
  function findReactFnComponent ($jsxAttribute) {
@@ -537,7 +566,6 @@ function findReactFnComponent ($jsxAttribute) {
537
566
  return $potentialComponentFn
538
567
  }
539
568
 
540
- // Get compilers from the magic import
541
569
  function getUsedCompilers ($program, state) {
542
570
  const res = new Map()
543
571
  const magicImports = state.opts.magicImports || DEFAULT_MAGIC_IMPORTS
@@ -547,8 +575,9 @@ function getUsedCompilers ($program, state) {
547
575
  for (const $specifier of $import.get('specifiers')) {
548
576
  if (!$specifier.isImportSpecifier()) continue
549
577
  const { local, imported } = $specifier.node
550
- if (COMPILERS.includes(imported.name)) {
551
- res.set(local.name, true)
578
+ // it's important to use hasOwnProperty here to avoid prototype pollution issues, like 'toString'
579
+ if (Object.prototype.hasOwnProperty.call(COMPILERS, imported.name)) {
580
+ res.set(local.name, COMPILERS[imported.name])
552
581
  $specifier.remove()
553
582
  }
554
583
  }
@@ -591,3 +620,16 @@ function addNamedImport ($program, name, sourceName) {
591
620
  importPosition: 'after'
592
621
  })
593
622
  }
623
+
624
+ function insertAfterImports ($program, expressionStatement) {
625
+ const lastImport = $program
626
+ .get('body')
627
+ .filter($i => $i.isImportDeclaration())
628
+ .pop()
629
+
630
+ if (lastImport) {
631
+ lastImport.insertAfter(expressionStatement)
632
+ } else {
633
+ $program.unshift(expressionStatement)
634
+ }
635
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cssxjs/babel-plugin-rn-stylename-to-style",
3
- "version": "0.2.14",
3
+ "version": "0.2.16",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -24,18 +24,16 @@
24
24
  },
25
25
  "dependencies": {
26
26
  "@babel/helper-module-imports": "^7.0.0",
27
+ "@babel/parser": "^7.0.0",
27
28
  "@babel/template": "^7.4.0",
28
29
  "@babel/types": "^7.0.0",
29
- "@cssxjs/runtime": "^0.2.14"
30
+ "@cssxjs/runtime": "^0.2.16"
30
31
  },
31
32
  "devDependencies": {
32
33
  "@babel/plugin-syntax-jsx": "^7.0.0",
33
- "@cssxjs/babel-plugin-react-pug": "^0.2.14",
34
+ "@cssxjs/babel-plugin-react-pug": "^0.2.16",
34
35
  "babel-plugin-tester": "^9.1.0",
35
36
  "jest": "^30.0.4"
36
37
  },
37
- "peerDependencies": {
38
- "teamplay": "*"
39
- },
40
- "gitHead": "72b2f3d63ebe86ab75b398036ff27f8abe99f1d4"
38
+ "gitHead": "4b62363af9606001df70548a69afc655545edab7"
41
39
  }