@cssxjs/babel-plugin-rn-stylename-to-style 0.2.15 → 0.2.17
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 +24 -0
- package/README.md +12 -5
- package/index.js +86 -53
- package/package.json +5 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,27 @@
|
|
|
1
|
+
# v0.2.17 (Mon Nov 10 2025)
|
|
2
|
+
|
|
3
|
+
#### 🐛 Bug Fix
|
|
4
|
+
|
|
5
|
+
- fix(babel-plugin-rn-stylename-to-style): change the default extensions to compile to .cssx.css and .cssx.styl (cray0000@gmail.com)
|
|
6
|
+
|
|
7
|
+
#### Authors: 1
|
|
8
|
+
|
|
9
|
+
- Pavel Zhukov (cray0000@gmail.com)
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# v0.2.16 (Sun Nov 09 2025)
|
|
14
|
+
|
|
15
|
+
#### 🚀 Enhancement
|
|
16
|
+
|
|
17
|
+
- feat(babel-plugin-rn-stylename-to-style): Support compiling css file imports in Babel itself ([@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.15 (Sun Nov 09 2025)
|
|
2
26
|
|
|
3
27
|
#### 🐛 Bug Fix
|
package/README.md
CHANGED
|
@@ -103,7 +103,7 @@ You must give one or more file extensions inside an array in the plugin options.
|
|
|
103
103
|
|
|
104
104
|
#### `extensions`
|
|
105
105
|
|
|
106
|
-
**
|
|
106
|
+
**Default** `['cssx.css', 'cssx.styl']`
|
|
107
107
|
|
|
108
108
|
List of css extensions to process (`css`, `styl`, `sass`, etc.)
|
|
109
109
|
|
|
@@ -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
|
-
#### `
|
|
116
|
+
#### `compileCssImports`
|
|
117
117
|
|
|
118
|
-
**Default:** `
|
|
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
|
-
|
|
121
|
-
|
|
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,15 @@
|
|
|
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 =
|
|
9
|
+
const COMPILERS = require('@cssxjs/loaders/compilers')
|
|
8
10
|
const RUNTIME_LIBRARY = 'cssxjs/runtime'
|
|
11
|
+
const DEFAULT_PLATFORM = 'web'
|
|
12
|
+
const DEFAULT_EXTENSIONS = ['cssx.css', 'cssx.styl']
|
|
9
13
|
const STYLE_NAME_REGEX = /(?:^s|S)tyleName$/
|
|
10
14
|
const STYLE_REGEX = /(?:^s|S)tyle$/
|
|
11
15
|
const ROOT_STYLE_PROP_NAME = 'style'
|
|
@@ -21,18 +25,19 @@ const buildSafeVar = template.expression(`
|
|
|
21
25
|
typeof %%variable%% !== 'undefined' && %%variable%%
|
|
22
26
|
`)
|
|
23
27
|
|
|
24
|
-
const buildJsonParse = template(`
|
|
25
|
-
const %%name%% = JSON.parse(%%jsonStyle%%)
|
|
26
|
-
`)
|
|
27
|
-
|
|
28
28
|
const buildRuntimeVar = template(`
|
|
29
29
|
const %%name%% = %%imported%%
|
|
30
30
|
`)
|
|
31
31
|
|
|
32
|
+
const buildConst = template(`
|
|
33
|
+
const %%variable%% = %%value%%
|
|
34
|
+
`)
|
|
35
|
+
|
|
32
36
|
module.exports = function (babel) {
|
|
33
37
|
let styleHash = {}
|
|
34
38
|
let cssIdentifier
|
|
35
39
|
let hasObserver
|
|
40
|
+
let hasFrameworkImport
|
|
36
41
|
let $program
|
|
37
42
|
let usedCompilers
|
|
38
43
|
let runtime
|
|
@@ -267,6 +272,7 @@ module.exports = function (babel) {
|
|
|
267
272
|
styleHash = {}
|
|
268
273
|
cssIdentifier = undefined
|
|
269
274
|
hasObserver = undefined
|
|
275
|
+
hasFrameworkImport = undefined
|
|
270
276
|
$program = undefined
|
|
271
277
|
usedCompilers = undefined
|
|
272
278
|
runtime = undefined
|
|
@@ -282,29 +288,31 @@ module.exports = function (babel) {
|
|
|
282
288
|
// 2. Run early traversal of everything
|
|
283
289
|
$this.traverse({
|
|
284
290
|
ImportDeclaration ($this, state) {
|
|
291
|
+
// refactor this to check if we have the magic import and observer in Program:enter
|
|
292
|
+
// since there is now a race condition - if observer import is after css file import
|
|
293
|
+
// then it won't be detected
|
|
285
294
|
if (!hasObserver) hasObserver = checkObserverImport($this, state)
|
|
295
|
+
if (!hasFrameworkImport) hasFrameworkImport = checkHasFrameworkImport($this, state)
|
|
286
296
|
|
|
287
|
-
const extensions =
|
|
288
|
-
Array.isArray(state.opts.extensions) &&
|
|
289
|
-
state.opts.extensions
|
|
297
|
+
const extensions = state.opts.extensions ?? DEFAULT_EXTENSIONS
|
|
290
298
|
|
|
291
|
-
if (!extensions) {
|
|
292
|
-
throw
|
|
293
|
-
|
|
294
|
-
|
|
299
|
+
if (!Array.isArray(extensions)) {
|
|
300
|
+
throw Error(`
|
|
301
|
+
You have not specified any extensions in the plugin options.
|
|
302
|
+
The 'extensions' option must be an array of strings like ['styl', 'css'].
|
|
303
|
+
If you don't want to handle any CSS file imports then specify an empty array.
|
|
304
|
+
`)
|
|
295
305
|
}
|
|
296
306
|
|
|
297
|
-
const
|
|
307
|
+
const source = $this.node.source.value
|
|
308
|
+
if (!extensions.some(ext => source.endsWith(`.${ext}`))) return
|
|
309
|
+
const compilerName = source.split('.').pop()
|
|
298
310
|
|
|
299
|
-
|
|
300
|
-
return
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
const anonymousImports = $this.container.filter(n => {
|
|
311
|
+
const anonymousImports = $this.container.filter(node => {
|
|
304
312
|
return (
|
|
305
|
-
t.isImportDeclaration(
|
|
306
|
-
|
|
307
|
-
extensions.
|
|
313
|
+
t.isImportDeclaration(node) &&
|
|
314
|
+
node.specifiers.length === 0 &&
|
|
315
|
+
extensions.some(ext => node.source.value.endsWith(`.${ext}`))
|
|
308
316
|
)
|
|
309
317
|
})
|
|
310
318
|
|
|
@@ -314,35 +322,50 @@ module.exports = function (babel) {
|
|
|
314
322
|
)
|
|
315
323
|
}
|
|
316
324
|
|
|
317
|
-
let specifier = node.specifiers[0]
|
|
325
|
+
let specifier = $this.node.specifiers[0]
|
|
318
326
|
|
|
319
327
|
if (!specifier) {
|
|
320
328
|
specifier = t.ImportDefaultSpecifier(
|
|
321
329
|
$this.scope.generateUidIdentifier('css')
|
|
322
330
|
)
|
|
323
|
-
node.specifiers = [specifier]
|
|
331
|
+
$this.node.specifiers = [specifier]
|
|
324
332
|
}
|
|
325
333
|
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
334
|
+
const compileCssImports = state.opts.compileCssImports ?? true
|
|
335
|
+
// if we compile css imports, we need to replace the import with a variable declaration
|
|
336
|
+
if (compileCssImports) {
|
|
337
|
+
const localName = specifier.local.name
|
|
338
|
+
const filename = state.file?.opts?.filename
|
|
339
|
+
const platform = state.opts?.platform || state.file?.opts?.caller?.platform || DEFAULT_PLATFORM
|
|
340
|
+
// resolve the full path to the style file relative to the current file
|
|
341
|
+
const styleFilepath = nodePath.resolve(nodePath.dirname(filename), source)
|
|
342
|
+
// read the style file content
|
|
343
|
+
const styleFileContent = fs.readFileSync(styleFilepath, 'utf8')
|
|
344
|
+
// find the appropriate compiler
|
|
345
|
+
const compiler = COMPILERS[compilerName]
|
|
346
|
+
if (!compiler) {
|
|
347
|
+
throw $this.buildCodeFrameError(
|
|
348
|
+
`No compiler found for imported extension: "${source}"`
|
|
349
|
+
)
|
|
350
|
+
}
|
|
351
|
+
const compiledString = compiler(
|
|
352
|
+
styleFileContent,
|
|
353
|
+
styleFilepath,
|
|
354
|
+
{ platform }
|
|
345
355
|
)
|
|
356
|
+
const compiledExpression = parser.parseExpression(compiledString)
|
|
357
|
+
|
|
358
|
+
cssIdentifier = t.identifier(localName)
|
|
359
|
+
const varDeclaration = buildConst({
|
|
360
|
+
variable: cssIdentifier,
|
|
361
|
+
value: compiledExpression
|
|
362
|
+
})
|
|
363
|
+
insertAfterImports($program, varDeclaration)
|
|
364
|
+
// remove the original import and insert the variable declaration instead
|
|
365
|
+
$this.remove()
|
|
366
|
+
} else {
|
|
367
|
+
// otherwise just keep the import as is
|
|
368
|
+
cssIdentifier = specifier.local
|
|
346
369
|
}
|
|
347
370
|
},
|
|
348
371
|
JSXOpeningElement: {
|
|
@@ -412,14 +435,6 @@ module.exports = function (babel) {
|
|
|
412
435
|
}
|
|
413
436
|
}
|
|
414
437
|
|
|
415
|
-
function isRequire (node) {
|
|
416
|
-
return node?.declarations?.[0]?.init?.callee?.name === 'require'
|
|
417
|
-
}
|
|
418
|
-
|
|
419
|
-
function getExt (node) {
|
|
420
|
-
return nodePath.extname(node.source.value).replace(/^\./, '')
|
|
421
|
-
}
|
|
422
|
-
|
|
423
438
|
function convertStyleName (name) {
|
|
424
439
|
return name.replace(/Name$/, '')
|
|
425
440
|
}
|
|
@@ -515,6 +530,11 @@ function checkObserverImport ($import, state) {
|
|
|
515
530
|
}
|
|
516
531
|
}
|
|
517
532
|
|
|
533
|
+
function checkHasFrameworkImport ($import, state) {
|
|
534
|
+
const magicImports = state.opts.magicImports || DEFAULT_MAGIC_IMPORTS
|
|
535
|
+
return magicImports.includes($import.node.source.value)
|
|
536
|
+
}
|
|
537
|
+
|
|
518
538
|
// find topmost function (which is not a lowercase named one).
|
|
519
539
|
// .getFunctionParent() returns undefined when we reach Program
|
|
520
540
|
function findReactFnComponent ($jsxAttribute) {
|
|
@@ -537,7 +557,6 @@ function findReactFnComponent ($jsxAttribute) {
|
|
|
537
557
|
return $potentialComponentFn
|
|
538
558
|
}
|
|
539
559
|
|
|
540
|
-
// Get compilers from the magic import
|
|
541
560
|
function getUsedCompilers ($program, state) {
|
|
542
561
|
const res = new Map()
|
|
543
562
|
const magicImports = state.opts.magicImports || DEFAULT_MAGIC_IMPORTS
|
|
@@ -547,8 +566,9 @@ function getUsedCompilers ($program, state) {
|
|
|
547
566
|
for (const $specifier of $import.get('specifiers')) {
|
|
548
567
|
if (!$specifier.isImportSpecifier()) continue
|
|
549
568
|
const { local, imported } = $specifier.node
|
|
550
|
-
|
|
551
|
-
|
|
569
|
+
// it's important to use hasOwnProperty here to avoid prototype pollution issues, like 'toString'
|
|
570
|
+
if (Object.prototype.hasOwnProperty.call(COMPILERS, imported.name)) {
|
|
571
|
+
res.set(local.name, COMPILERS[imported.name])
|
|
552
572
|
$specifier.remove()
|
|
553
573
|
}
|
|
554
574
|
}
|
|
@@ -591,3 +611,16 @@ function addNamedImport ($program, name, sourceName) {
|
|
|
591
611
|
importPosition: 'after'
|
|
592
612
|
})
|
|
593
613
|
}
|
|
614
|
+
|
|
615
|
+
function insertAfterImports ($program, expressionStatement) {
|
|
616
|
+
const lastImport = $program
|
|
617
|
+
.get('body')
|
|
618
|
+
.filter($i => $i.isImportDeclaration())
|
|
619
|
+
.pop()
|
|
620
|
+
|
|
621
|
+
if (lastImport) {
|
|
622
|
+
lastImport.insertAfter(expressionStatement)
|
|
623
|
+
} else {
|
|
624
|
+
$program.unshift(expressionStatement)
|
|
625
|
+
}
|
|
626
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cssxjs/babel-plugin-rn-stylename-to-style",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.17",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -24,15 +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.
|
|
30
|
+
"@cssxjs/runtime": "^0.2.17"
|
|
30
31
|
},
|
|
31
32
|
"devDependencies": {
|
|
32
33
|
"@babel/plugin-syntax-jsx": "^7.0.0",
|
|
33
|
-
"@cssxjs/babel-plugin-react-pug": "^0.2.
|
|
34
|
+
"@cssxjs/babel-plugin-react-pug": "^0.2.17",
|
|
34
35
|
"babel-plugin-tester": "^9.1.0",
|
|
35
36
|
"jest": "^30.0.4"
|
|
36
37
|
},
|
|
37
|
-
"gitHead": "
|
|
38
|
+
"gitHead": "02b76ae074674c67f8d50a85b091e1190648449d"
|
|
38
39
|
}
|