@stylexjs/babel-plugin 0.15.0 → 0.15.1

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/lib/index.js CHANGED
@@ -4,8 +4,8 @@ var t = require('@babel/types');
4
4
  var path = require('path');
5
5
  var fs = require('fs');
6
6
  var url$1 = require('url');
7
- var require$$0 = require('assert');
8
7
  var importMetaResolve = require('@dual-bundle/import-meta-resolve');
8
+ var require$$0 = require('assert');
9
9
  var core = require('@babel/core');
10
10
  var traverse = require('@babel/traverse');
11
11
  var stylex = require('@stylexjs/stylex');
@@ -655,6 +655,121 @@ function requireLib$2 () {
655
655
 
656
656
  var libExports$2 = requireLib$2();
657
657
 
658
+ function hoistExpression(path, astExpression) {
659
+ const programStatementPath = getProgramStatement(path);
660
+ if (programStatementPath == null) {
661
+ return astExpression;
662
+ }
663
+ const hoistedIdent = path.scope.generateUidIdentifier();
664
+ programStatementPath.insertBefore(t__namespace.variableDeclaration('const', [t__namespace.variableDeclarator(hoistedIdent, astExpression)]));
665
+ return hoistedIdent;
666
+ }
667
+ function pathReplaceHoisted(path, astExpression) {
668
+ if (isProgramLevel(path)) {
669
+ path.replaceWith(astExpression);
670
+ return;
671
+ }
672
+ const programStatementPath = getProgramStatement(path);
673
+ if (programStatementPath == null) {
674
+ path.replaceWith(astExpression);
675
+ return;
676
+ }
677
+ const nameIdent = path.scope.generateUidIdentifier('styles');
678
+ programStatementPath.insertBefore(t__namespace.variableDeclaration('const', [t__namespace.variableDeclarator(nameIdent, astExpression)]));
679
+ path.replaceWith(nameIdent);
680
+ }
681
+ function getProgramPath(path) {
682
+ let programPath = path;
683
+ while (programPath != null && !programPath.isProgram()) {
684
+ if (programPath.parentPath) {
685
+ programPath = programPath.parentPath;
686
+ } else {
687
+ return null;
688
+ }
689
+ }
690
+ return programPath;
691
+ }
692
+ function addNamedImport(statementPath, as, from, options) {
693
+ const identifier = libExports$2.addNamed(statementPath, as, from, options);
694
+ const programPath = getProgramPath(statementPath);
695
+ if (programPath == null) {
696
+ return identifier;
697
+ }
698
+ const bodyPath = programPath.get('body');
699
+ let targetImportIndex = -1;
700
+ for (let i = 0; i < bodyPath.length; i++) {
701
+ const statement = bodyPath[i];
702
+ if (statement.isImportDeclaration()) {
703
+ targetImportIndex = i;
704
+ if (statement.node.specifiers.find(s => s.type === 'ImportSpecifier' && s.local.type === 'Identifier' && s.local.name === identifier.name)) {
705
+ break;
706
+ }
707
+ }
708
+ }
709
+ if (targetImportIndex === -1) {
710
+ return identifier;
711
+ }
712
+ const lastImport = bodyPath[targetImportIndex];
713
+ if (lastImport == null) {
714
+ return identifier;
715
+ }
716
+ const importName = statementPath.scope.generateUidIdentifier(as);
717
+ lastImport.insertAfter(t__namespace.variableDeclaration('var', [t__namespace.variableDeclarator(importName, identifier)]));
718
+ return importName;
719
+ }
720
+ function addDefaultImport(statementPath, from, options) {
721
+ const identifier = libExports$2.addDefault(statementPath, from, options);
722
+ const programPath = getProgramPath(statementPath);
723
+ if (programPath == null) {
724
+ return identifier;
725
+ }
726
+ const bodyPath = programPath.get('body');
727
+ let targetImportIndex = -1;
728
+ for (let i = 0; i < bodyPath.length; i++) {
729
+ const statement = bodyPath[i];
730
+ if (statement.isImportDeclaration()) {
731
+ targetImportIndex = i;
732
+ if (statement.node.specifiers.find(s => s.type === 'ImportDefaultSpecifier' && s.local.type === 'Identifier' && s.local.name === identifier.name)) {
733
+ break;
734
+ }
735
+ }
736
+ }
737
+ if (targetImportIndex === -1) {
738
+ return identifier;
739
+ }
740
+ const lastImport = bodyPath[targetImportIndex];
741
+ if (lastImport == null) {
742
+ return identifier;
743
+ }
744
+ const importName = statementPath.scope.generateUidIdentifier('inject');
745
+ lastImport.insertAfter(t__namespace.variableDeclaration('var', [t__namespace.variableDeclarator(importName, identifier)]));
746
+ return importName;
747
+ }
748
+ function isProgramLevel(path) {
749
+ let programPath = path;
750
+ if (programPath.isStatement() && programPath?.parentPath?.isProgram()) {
751
+ return true;
752
+ }
753
+ while (programPath.parentPath != null) {
754
+ const parentPath = programPath.parentPath;
755
+ if (programPath.isStatement() && !programPath.parentPath?.isProgram() && !programPath.parentPath?.isExportDeclaration()) {
756
+ return false;
757
+ }
758
+ if (programPath.isFunction()) {
759
+ return false;
760
+ }
761
+ programPath = parentPath;
762
+ }
763
+ return true;
764
+ }
765
+ function getProgramStatement(path) {
766
+ let programPath = path;
767
+ while (programPath.parentPath != null && !programPath.parentPath.isProgram() && programPath.parentPath != null) {
768
+ programPath = programPath.parentPath;
769
+ }
770
+ return programPath;
771
+ }
772
+
658
773
  const CheckModuleResolution = unionOf3(object({
659
774
  type: literal('commonJS'),
660
775
  rootDir: unionOf(nullish(), string()),
@@ -790,62 +905,6 @@ class StateManager {
790
905
  from: runInj
791
906
  } : runInj || null;
792
907
  }
793
- addNamedImport(statementPath, as, from, options) {
794
- const identifier = libExports$2.addNamed(statementPath, as, from, options);
795
- const programPath = getProgramPath(statementPath);
796
- if (programPath == null) {
797
- return identifier;
798
- }
799
- const bodyPath = programPath.get('body');
800
- let targetImportIndex = -1;
801
- for (let i = 0; i < bodyPath.length; i++) {
802
- const statement = bodyPath[i];
803
- if (statement.isImportDeclaration()) {
804
- targetImportIndex = i;
805
- if (statement.node.specifiers.find(s => s.type === 'ImportSpecifier' && s.local.type === 'Identifier' && s.local.name === identifier.name)) {
806
- break;
807
- }
808
- }
809
- }
810
- if (targetImportIndex === -1) {
811
- return identifier;
812
- }
813
- const lastImport = bodyPath[targetImportIndex];
814
- if (lastImport == null) {
815
- return identifier;
816
- }
817
- const importName = statementPath.scope.generateUidIdentifier(as);
818
- lastImport.insertAfter(t__namespace.variableDeclaration('var', [t__namespace.variableDeclarator(importName, identifier)]));
819
- return importName;
820
- }
821
- addDefaultImport(statementPath, from, options) {
822
- const identifier = libExports$2.addDefault(statementPath, from, options);
823
- const programPath = getProgramPath(statementPath);
824
- if (programPath == null) {
825
- return identifier;
826
- }
827
- const bodyPath = programPath.get('body');
828
- let targetImportIndex = -1;
829
- for (let i = 0; i < bodyPath.length; i++) {
830
- const statement = bodyPath[i];
831
- if (statement.isImportDeclaration()) {
832
- targetImportIndex = i;
833
- if (statement.node.specifiers.find(s => s.type === 'ImportDefaultSpecifier' && s.local.type === 'Identifier' && s.local.name === identifier.name)) {
834
- break;
835
- }
836
- }
837
- }
838
- if (targetImportIndex === -1) {
839
- return identifier;
840
- }
841
- const lastImport = bodyPath[targetImportIndex];
842
- if (lastImport == null) {
843
- return identifier;
844
- }
845
- const importName = statementPath.scope.generateUidIdentifier('inject');
846
- lastImport.insertAfter(t__namespace.variableDeclaration('var', [t__namespace.variableDeclarator(importName, identifier)]));
847
- return importName;
848
- }
849
908
  get opts() {
850
909
  return {
851
910
  ...this.options
@@ -973,9 +1032,9 @@ class StateManager {
973
1032
  from,
974
1033
  as
975
1034
  } = runtimeInjection;
976
- injectName = as != null ? this.addNamedImport(statementPath, as, from, {
1035
+ injectName = as != null ? addNamedImport(statementPath, as, from, {
977
1036
  nameHint: 'inject'
978
- }) : this.addDefaultImport(statementPath, from, {
1037
+ }) : addDefaultImport(statementPath, from, {
979
1038
  nameHint: 'inject'
980
1039
  });
981
1040
  this.injectImportInserted = injectName;
@@ -1048,24 +1107,6 @@ const addFileExtension = (importedFilePath, sourceFile) => {
1048
1107
  return importedFilePath + fileExtension;
1049
1108
  };
1050
1109
  const matchesFileSuffix = allowedSuffix => filename => ['', ...EXTENSIONS].some(extension => filename.endsWith(`${allowedSuffix}${extension}`));
1051
- const getProgramPath = path => {
1052
- let programPath = path;
1053
- while (programPath != null && !programPath.isProgram()) {
1054
- if (programPath.parentPath) {
1055
- programPath = programPath.parentPath;
1056
- } else {
1057
- return null;
1058
- }
1059
- }
1060
- return programPath;
1061
- };
1062
- const getProgramStatement = path => {
1063
- let programPath = path;
1064
- while (programPath.parentPath != null && !programPath.parentPath.isProgram() && programPath.parentPath != null) {
1065
- programPath = programPath.parentPath;
1066
- }
1067
- return programPath;
1068
- };
1069
1110
  function getRelativePath(from, to) {
1070
1111
  const relativePath = path.relative(path.parse(from).dir, to);
1071
1112
  return formatRelativePath(toPosixPath(relativePath));
@@ -7279,34 +7320,59 @@ function transformStyleXCreate(path, state) {
7279
7320
  }
7280
7321
  if (t__namespace.isObjectExpression(prop.value)) {
7281
7322
  const value = prop.value;
7323
+ let cssTagValue = t__namespace.booleanLiteral(true);
7324
+ const staticProps = [];
7282
7325
  const conditionalProps = [];
7283
7326
  value.properties.forEach(prop => {
7284
7327
  if (!t__namespace.isObjectProperty(prop) || t__namespace.isPrivateName(prop.key)) {
7285
7328
  return;
7286
7329
  }
7287
7330
  const objProp = prop;
7288
- const propKey = objProp.key.type === 'Identifier' && !objProp.computed ? objProp.key.name : objProp.key.type === 'StringLiteral' ? objProp.key.value : null;
7289
- if (propKey == null || propKey === '$$css') {
7290
- conditionalProps.push(objProp);
7331
+ const propKey = t__namespace.isIdentifier(objProp.key) && !objProp.computed ? objProp.key.name : t__namespace.isStringLiteral(objProp.key) ? objProp.key.value : null;
7332
+ if (propKey == null) {
7333
+ staticProps.push(objProp);
7334
+ return;
7335
+ }
7336
+ if (propKey === '$$css') {
7337
+ cssTagValue = objProp.value;
7291
7338
  return;
7292
7339
  }
7293
7340
  const classList = t__namespace.isStringLiteral(objProp.value) ? objProp.value.value.split(' ') : [];
7341
+ let isStatic = true;
7294
7342
  const exprList = [];
7295
7343
  classList.forEach(cls => {
7296
7344
  const expr = dynamicStyles.find(({
7297
7345
  path
7298
7346
  }) => origClassPaths[cls] === path)?.expression;
7299
7347
  if (expr && !isSafeToSkipNullCheck(expr)) {
7348
+ isStatic = false;
7300
7349
  exprList.push(t__namespace.conditionalExpression(t__namespace.binaryExpression('!=', expr, t__namespace.nullLiteral()), t__namespace.stringLiteral(cls), expr));
7301
7350
  } else {
7302
7351
  exprList.push(t__namespace.stringLiteral(cls));
7303
7352
  }
7304
7353
  });
7305
7354
  const joined = exprList.length === 0 ? t__namespace.stringLiteral('') : exprList.reduce((acc, curr) => t__namespace.binaryExpression('+', acc, curr));
7306
- conditionalProps.push(t__namespace.objectProperty(objProp.key, joined));
7355
+ if (isStatic) {
7356
+ staticProps.push(t__namespace.objectProperty(objProp.key, joined));
7357
+ } else {
7358
+ conditionalProps.push(t__namespace.objectProperty(objProp.key, joined));
7359
+ }
7307
7360
  });
7308
- const conditionalObj = t__namespace.objectExpression(conditionalProps);
7309
- prop.value = t__namespace.arrowFunctionExpression(params, t__namespace.arrayExpression([conditionalObj, t__namespace.objectExpression(Object.entries(inlineStyles).map(([key, val]) => t__namespace.objectProperty(t__namespace.stringLiteral(key), val.expression)))]));
7361
+ let staticObj = null;
7362
+ let conditionalObj = null;
7363
+ if (staticProps.length > 0) {
7364
+ staticProps.push(t__namespace.objectProperty(t__namespace.stringLiteral('$$css'), cssTagValue));
7365
+ staticObj = t__namespace.objectExpression(staticProps);
7366
+ }
7367
+ if (conditionalProps.length > 0) {
7368
+ conditionalProps.push(t__namespace.objectProperty(t__namespace.identifier('$$css'), cssTagValue));
7369
+ conditionalObj = t__namespace.objectExpression(conditionalProps);
7370
+ }
7371
+ let finalFnValue = t__namespace.objectExpression(Object.entries(inlineStyles).map(([key, val]) => t__namespace.objectProperty(t__namespace.stringLiteral(key), val.expression)));
7372
+ if (staticObj != null || conditionalObj != null) {
7373
+ finalFnValue = t__namespace.arrayExpression([staticObj && hoistExpression(path, staticObj), conditionalObj, finalFnValue].filter(Boolean));
7374
+ }
7375
+ prop.value = t__namespace.arrowFunctionExpression(params, finalFnValue);
7310
7376
  }
7311
7377
  }
7312
7378
  }
@@ -7318,7 +7384,7 @@ function transformStyleXCreate(path, state) {
7318
7384
  ...rest
7319
7385
  }]) => [key, rest, priority]);
7320
7386
  state.registerStyles(listOfStyles, path);
7321
- path.replaceWith(resultAst);
7387
+ pathReplaceHoisted(path, resultAst);
7322
7388
  if (Object.keys(injectedStyles).length === 0) {
7323
7389
  return;
7324
7390
  }
@@ -7329,10 +7395,6 @@ function validateStyleXCreate(path) {
7329
7395
  if (path.parentPath == null || path.parentPath.isExpressionStatement()) {
7330
7396
  throw path.buildCodeFrameError(messages.unboundCallValue('create'), SyntaxError);
7331
7397
  }
7332
- const nearestStatement = findNearestStatementAncestor(path);
7333
- if (!nearestStatement.parentPath.isProgram() && !nearestStatement.parentPath.isExportNamedDeclaration()) {
7334
- throw path.buildCodeFrameError(messages.ONLY_TOP_LEVEL, SyntaxError);
7335
- }
7336
7398
  if (path.node.arguments.length !== 1) {
7337
7399
  throw path.buildCodeFrameError(messages.illegalArgumentLength('create', 1), SyntaxError);
7338
7400
  }
@@ -7345,15 +7407,6 @@ function validateStyleXCreate(path) {
7345
7407
  throw path.buildCodeFrameError(messages.NO_OBJECT_SPREADS, SyntaxError);
7346
7408
  }
7347
7409
  }
7348
- function findNearestStatementAncestor(path) {
7349
- if (path.isStatement()) {
7350
- return path;
7351
- }
7352
- if (path.parentPath == null) {
7353
- throw new Error('Unexpected Path found that is not part of the AST.');
7354
- }
7355
- return findNearestStatementAncestor(path.parentPath);
7356
- }
7357
7410
  function legacyExpandShorthands(dynamicStyles) {
7358
7411
  const expandedKeysToKeyPaths = dynamicStyles.flatMap(({
7359
7412
  key
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ *
8
+ */
9
+
10
+ import type { ImportOptions } from '@babel/helper-module-imports';
11
+ import type { NodePath } from '@babel/traverse';
12
+ type ImportAdditionOptions = Omit<
13
+ Partial<ImportOptions>,
14
+ 'ensureLiveReference' | 'ensureNoContext'
15
+ >;
16
+ import * as t from '@babel/types';
17
+ export declare function hoistExpression(
18
+ path: NodePath,
19
+ astExpression: t.Expression,
20
+ ): t.Expression;
21
+ export declare function pathReplaceHoisted(
22
+ path: NodePath,
23
+ astExpression: t.Expression,
24
+ ): void;
25
+ export declare function addNamedImport(
26
+ statementPath: NodePath,
27
+ as: string,
28
+ from: string,
29
+ options: ImportAdditionOptions,
30
+ ): t.Identifier;
31
+ export declare function addDefaultImport(
32
+ statementPath: NodePath,
33
+ from: string,
34
+ options: ImportAdditionOptions,
35
+ ): t.Identifier;
36
+ export declare function isProgramLevel(path: NodePath): boolean;
37
+ export declare function getProgramStatement(path: NodePath): NodePath;
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ * @flow strict
8
+ */
9
+
10
+ import type { ImportOptions } from '../../flow_modules/@babel/helper-module-imports';
11
+ import type { NodePath } from '../../flow_modules/@babel/traverse';
12
+ type ImportAdditionOptions = Omit<
13
+ Partial<ImportOptions>,
14
+ 'ensureLiveReference' | 'ensureNoContext',
15
+ >;
16
+
17
+ import * as t from '../../flow_modules/@babel/types';
18
+
19
+ declare export function hoistExpression(
20
+ path: NodePath<>,
21
+ astExpression: t.Expression,
22
+ ): t.Expression;
23
+
24
+ declare export function pathReplaceHoisted(
25
+ path: NodePath<>,
26
+ astExpression: t.Expression,
27
+ ): void;
28
+
29
+ declare export function addNamedImport(
30
+ statementPath: NodePath<>,
31
+ as: string,
32
+ from: string,
33
+ options: ImportAdditionOptions,
34
+ ): t.Identifier;
35
+
36
+ declare export function addDefaultImport(
37
+ statementPath: NodePath<>,
38
+ from: string,
39
+ options: ImportAdditionOptions,
40
+ ): t.Identifier;
41
+
42
+ declare export function isProgramLevel(path: NodePath<>): boolean;
43
+
44
+ declare export function getProgramStatement(path: NodePath<>): NodePath<>;
@@ -13,12 +13,7 @@ import type {
13
13
  CompiledNamespaces,
14
14
  StyleXOptions as RuntimeOptions,
15
15
  } from '../shared';
16
- import type { ImportOptions } from '@babel/helper-module-imports';
17
16
  import * as t from '@babel/types';
18
- type ImportAdditionOptions = Omit<
19
- Partial<ImportOptions>,
20
- 'ensureLiveReference' | 'ensureNoContext'
21
- >;
22
17
  export type ImportPathResolution =
23
18
  | false
24
19
  | ['themeNameRef' | 'filePath', string];
@@ -145,17 +140,6 @@ declare class StateManager {
145
140
  | null
146
141
  | undefined
147
142
  | Readonly<{ from: string; as?: null | undefined | string }>;
148
- addNamedImport(
149
- statementPath: NodePath,
150
- as: string,
151
- from: string,
152
- options: ImportAdditionOptions,
153
- ): t.Identifier;
154
- addDefaultImport(
155
- statementPath: NodePath,
156
- from: string,
157
- options: ImportAdditionOptions,
158
- ): t.Identifier;
159
143
  get opts(): StyleXStateOptions;
160
144
  get isDebug(): boolean;
161
145
  get isDev(): boolean;
@@ -13,14 +13,7 @@ import type {
13
13
  CompiledNamespaces,
14
14
  StyleXOptions as RuntimeOptions,
15
15
  } from '../shared';
16
- import type { ImportOptions } from '../../flow_modules/@babel/helper-module-imports';
17
-
18
16
  import * as t from '../../flow_modules/@babel/types';
19
- type ImportAdditionOptions = Omit<
20
- Partial<ImportOptions>,
21
- 'ensureLiveReference' | 'ensureNoContext',
22
- >;
23
-
24
17
  export type ImportPathResolution =
25
18
  | false
26
19
  | ['themeNameRef' | 'filePath', string];
@@ -100,17 +93,6 @@ declare export default class StateManager {
100
93
  get canReferenceTheme(): boolean;
101
94
  get metadata(): { [key: string]: any };
102
95
  get runtimeInjection(): ?$ReadOnly<{ from: string, as?: ?string }>;
103
- addNamedImport(
104
- statementPath: NodePath<>,
105
- as: string,
106
- from: string,
107
- options: ImportAdditionOptions,
108
- ): t.Identifier;
109
- addDefaultImport(
110
- statementPath: NodePath<>,
111
- from: string,
112
- options: ImportAdditionOptions,
113
- ): t.Identifier;
114
96
  get opts(): StyleXStateOptions;
115
97
  get isDebug(): boolean;
116
98
  get isDev(): boolean;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stylexjs/babel-plugin",
3
- "version": "0.15.0",
3
+ "version": "0.15.1",
4
4
  "description": "StyleX babel plugin.",
5
5
  "main": "lib/index.js",
6
6
  "repository": {
@@ -21,9 +21,9 @@
21
21
  "@babel/traverse": "^7.26.8",
22
22
  "@babel/types": "^7.26.8",
23
23
  "@dual-bundle/import-meta-resolve": "^4.1.0",
24
- "@stylexjs/stylex": "0.15.0",
24
+ "@stylexjs/stylex": "0.15.1",
25
25
  "postcss-value-parser": "^4.1.0",
26
- "style-value-parser": "0.15.0"
26
+ "style-value-parser": "0.15.1"
27
27
  },
28
28
  "devDependencies": {
29
29
  "@rollup/plugin-alias": "^5.1.1",
@@ -34,7 +34,7 @@
34
34
  "@rollup/plugin-replace": "^6.0.1",
35
35
  "babel-plugin-syntax-hermes-parser": "^0.26.0",
36
36
  "rollup": "^4.24.0",
37
- "scripts": "0.15.0"
37
+ "scripts": "0.15.1"
38
38
  },
39
39
  "files": [
40
40
  "flow_modules/*",