Repository: facebook/stylex
Pull request #953: Reorganize monorepo scripts
Author: login: necolas
Labels: name: CLA Signed
description: This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed.
Created: 2025-03-18T23:37:02Z | Merged: 2025-03-19T19:07:12Z

## What changed / motivation ?

Minor reorganization of the repo's scripts and tools. Private package names aren't scoped to `@stylexjs` and the release tooling is moved up to the root package.


Diff:
diff --git a/package-lock.json b/package-lock.json
index deae3ffae..69ccece5a 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -32,7 +32,7 @@
         "prettier": "^3.5.0",
         "prettier-plugin-hermes-parser": "^0.26.0",
         "rimraf": "^5.0.10",
-        "typescript": "^5.3.3"
+        "yargs": "17.7.2"
       }
     },
     "examples/example-cli": {
@@ -6399,10 +6399,6 @@
       "resolved": "packages/rollup-plugin",
       "link": true
     },
-    "node_modules/@stylexjs/scripts": {
-      "resolved": "packages/scripts",
-      "link": true
-    },
     "node_modules/@stylexjs/shared": {
       "resolved": "packages/shared",
       "link": true
@@ -11039,9 +11035,9 @@
       "license": "MIT"
     },
     "node_modules/electron-to-chromium": {
-      "version": "1.5.119",
-      "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.119.tgz",
-      "integrity": "sha512-Ku4NMzUjz3e3Vweh7PhApPrZSS4fyiCIbcIrG9eKrriYVLmbMepETR/v6SU7xPm98QTqMSYiCwfO89QNjXLkbQ==",
+      "version": "1.5.120",
+      "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.120.tgz",
+      "integrity": "sha512-oTUp3gfX1gZI+xfD2djr2rzQdHCwHzPQrrK0CD7WpTdF0nPdQ/INcRVjWgLdCT4a9W3jFObR9DAfsuyFQnI8CQ==",
       "license": "ISC"
     },
     "node_modules/emittery": {
@@ -21815,6 +21811,10 @@
         "url": "https://opencollective.com/webpack"
       }
     },
+    "node_modules/scripts": {
+      "resolved": "packages/scripts",
+      "link": true
+    },
     "node_modules/search-insights": {
       "version": "2.17.3",
       "resolved": "https://registry.npmjs.org/search-insights/-/search-insights-2.17.3.tgz",
@@ -25851,7 +25851,7 @@
         "stylex": "lib/index.js"
       },
       "devDependencies": {
-        "@stylexjs/scripts": "0.11.1"
+        "scripts": "0.11.1"
       }
     },
     "packages/cli/node_modules/@babel/core": {
@@ -26022,7 +26022,6 @@
       }
     },
     "packages/scripts": {
-      "name": "@stylexjs/scripts",
       "version": "0.11.1",
       "license": "MIT",
       "dependencies": {
@@ -26030,8 +26029,8 @@
         "yargs": "17.7.2"
       },
       "bin": {
-        "gen-types": "gen-types.js",
-        "rewrite-imports": "rewrite-imports.js"
+        "gen-types": "flow-translator/generate-types.js",
+        "rewrite-imports": "flow-translator/rewrite-imports.js"
       }
     },
     "packages/shared": {
@@ -26050,8 +26049,8 @@
         "@babel/preset-flow": "^7.25.9",
         "@babel/preset-react": "^7.26.3",
         "@babel/preset-typescript": "^7.26.0",
-        "@stylexjs/scripts": "0.11.1",
-        "babel-plugin-syntax-hermes-parser": "^0.26.0"
+        "babel-plugin-syntax-hermes-parser": "^0.26.0",
+        "scripts": "0.11.1"
       }
     },
     "packages/style-value-parser": {
@@ -26091,10 +26090,10 @@
         "@rollup/plugin-json": "^6.1.0",
         "@rollup/plugin-node-resolve": "^15.3.0",
         "@rollup/plugin-replace": "^6.0.1",
-        "@stylexjs/scripts": "0.11.1",
         "babel-plugin-syntax-hermes-parser": "^0.26.0",
         "cross-env": "^7.0.3",
-        "rollup": "^4.24.0"
+        "rollup": "^4.24.0",
+        "scripts": "0.11.1"
       }
     },
     "packages/webpack-plugin": {
diff --git a/package.json b/package.json
index 7e945c11e..983434a76 100644
--- a/package.json
+++ b/package.json
@@ -11,7 +11,8 @@
     "prettier": "prettier --write \"**/*.js\" \"**/*.ts\"",
     "prettier:report": "prettier --check \"**/*.js\"",
     "lint": "npm run lint:report -- --fix",
-    "lint:report": "eslint",
+    "lint:report": "eslint packages tools",
+    "release": "tools/npm/release.js",
     "test:packages": "npm run test --workspaces --if-present",
     "test": "npm run build && npm run flow && npm run test:packages && npm run prettier:report && npm run lint:report"
   },
@@ -38,7 +39,7 @@
     "prettier": "^3.5.0",
     "prettier-plugin-hermes-parser": "^0.26.0",
     "rimraf": "^5.0.10",
-    "typescript": "^5.3.3"
+    "yargs": "17.7.2"
   },
   "prettier": {
     "singleQuote": true,
diff --git a/packages/cli/package.json b/packages/cli/package.json
index b7bb39057..b6fd62f51 100644
--- a/packages/cli/package.json
+++ b/packages/cli/package.json
@@ -27,7 +27,7 @@
     "yargs": "^17.7.2"
   },
   "devDependencies": {
-    "@stylexjs/scripts": "0.11.1"
+    "scripts": "0.11.1"
   },
   "bin": {
     "stylex": "./lib/index.js"
diff --git a/packages/scripts/README.md b/packages/scripts/README.md
index b44293d0e..797405c9f 100644
--- a/packages/scripts/README.md
+++ b/packages/scripts/README.md
@@ -1,37 +1,3 @@
-# @stylexjs/scripts
+# scripts
 
-Private scripts used by the monorepo.
-
-## How to create a release
-
-The release script (run from the monorepo root) must be used to create and publish releases.
-
-```shell
-npm run release
-  # workspace
-  -w @stylexjs/scripts --
-  # package version (required)
-  --pkg-version 0.10.2
-  # creates git commit and tag
-  --commit
-  # publishes to npm using 2fa
-  --publish --otp 123456
-```
-
-You can perform a dry run by only specifying the new version for a release:
-
-```shell
-npm run release -w @stylexjs/scripts -- --pkg-version 0.10.2
-```
-
-To commit and tag the release:
-
-```shell
-npm run release -w @stylexjs/scripts -- --pkg-version 0.10.2 --commit
-```
-
-To publish the release:
-
-```shell
-npm run release -w @stylexjs/scripts -- --pkg-version 0.10.2 --publish
-```
+Private CLI scripts that can be installed and used by packages within the monorepo as part of their dev and build processes.
diff --git a/packages/scripts/handle-flow-modules.js b/packages/scripts/flow-translator/flow-module-utils.js
similarity index 100%
rename from packages/scripts/handle-flow-modules.js
rename to packages/scripts/flow-translator/flow-module-utils.js
diff --git a/packages/scripts/gen-types.js b/packages/scripts/flow-translator/generate-types.js
similarity index 95%
rename from packages/scripts/gen-types.js
rename to packages/scripts/flow-translator/generate-types.js
index 707f6bee0..40dbe9637 100755
--- a/packages/scripts/gen-types.js
+++ b/packages/scripts/flow-translator/generate-types.js
@@ -9,19 +9,15 @@
  */
 
 const fsPromises = require('fs/promises');
-const monorepoPackage = require('../../package.json');
+const monorepoPackage = require('../../../package.json');
 const path = require('path');
 const translate = require('flow-api-translator');
+const utils = require('./flow-module-utils');
 const yargs = require('yargs/yargs');
 
-const {
-  findFlowModules,
-  patchFlowModulePaths,
-} = require('./handle-flow-modules');
-
 async function generateTypes(inputDir, outputDir, rootDir) {
   const rootPath = rootDir ?? path.resolve(inputDir, '../');
-  const flowModules = await findFlowModules(inputDir, rootPath);
+  const flowModules = await utils.findFlowModules(inputDir, rootPath);
 
   await fsPromises.mkdir(outputDir, { recursive: true });
   let dirents = await fsPromises.readdir(inputDir, { withFileTypes: true });
@@ -85,7 +81,7 @@ async function generateTypes(inputDir, outputDir, rootDir) {
 
           await fsPromises.writeFile(
             `${outputFullPath}.flow`,
-            patchFlowModulePaths(
+            utils.patchFlowModulePaths(
               outputFullPath,
               outputFlowContents,
               flowModules,
diff --git a/packages/scripts/rewrite-imports.js b/packages/scripts/flow-translator/rewrite-imports.js
similarity index 99%
rename from packages/scripts/rewrite-imports.js
rename to packages/scripts/flow-translator/rewrite-imports.js
index 8bede3c8d..491030687 100755
--- a/packages/scripts/rewrite-imports.js
+++ b/packages/scripts/flow-translator/rewrite-imports.js
@@ -5,7 +5,7 @@
  * This source code is licensed under the MIT license found in the
  * LICENSE file in the root directory of this source tree.
  *
- * @flow
+ *
  */
 
 const fs = require('fs').promises;
diff --git a/packages/scripts/package.json b/packages/scripts/package.json
index 0046a4a33..1dc4ac427 100644
--- a/packages/scripts/package.json
+++ b/packages/scripts/package.json
@@ -1,15 +1,12 @@
 {
   "private": true,
-  "name": "@stylexjs/scripts",
+  "name": "scripts",
   "version": "0.11.1",
   "description": "Helper scripts for stylex monorepo.",
   "license": "MIT",
   "bin": {
-    "gen-types": "./gen-types.js",
-    "rewrite-imports": "./rewrite-imports.js"
-  },
-  "scripts": {
-    "release": "./create-release.js"
+    "gen-types": "./flow-translator/generate-types.js",
+    "rewrite-imports": "./flow-translator/rewrite-imports.js"
   },
   "dependencies": {
     "flow-api-translator": "0.26.0",
diff --git a/packages/shared/package.json b/packages/shared/package.json
index 1a7e67460..18cc26c3f 100644
--- a/packages/shared/package.json
+++ b/packages/shared/package.json
@@ -24,8 +24,8 @@
     "@babel/preset-flow": "^7.25.9",
     "@babel/preset-react": "^7.26.3",
     "@babel/preset-typescript": "^7.26.0",
-    "@stylexjs/scripts": "0.11.1",
-    "babel-plugin-syntax-hermes-parser": "^0.26.0"
+    "babel-plugin-syntax-hermes-parser": "^0.26.0",
+    "scripts": "0.11.1"
   },
   "jest": {
     "snapshotFormat": {
diff --git a/packages/stylex/package.json b/packages/stylex/package.json
index 8fb975b40..170851227 100644
--- a/packages/stylex/package.json
+++ b/packages/stylex/package.json
@@ -63,10 +63,10 @@
     "@rollup/plugin-json": "^6.1.0",
     "@rollup/plugin-node-resolve": "^15.3.0",
     "@rollup/plugin-replace": "^6.0.1",
-    "@stylexjs/scripts": "0.11.1",
     "babel-plugin-syntax-hermes-parser": "^0.26.0",
     "cross-env": "^7.0.3",
-    "rollup": "^4.24.0"
+    "rollup": "^4.24.0",
+    "scripts": "0.11.1"
   },
   "jest": {},
   "files": [
diff --git a/tools/README.md b/tools/README.md
new file mode 100644
index 000000000..45deb4932
--- /dev/null
+++ b/tools/README.md
@@ -0,0 +1,35 @@
+# Tools
+
+Tools used to manage monorepo tasks like pre-commit hooks and npm releases.
+
+## How to create a release
+
+The release script (run from the monorepo root) must be used to create and publish releases.
+
+```shell
+npm run release
+  # package version (required)
+  --pkg-version 0.10.2
+  # creates git commit and tag
+  --commit
+  # publishes to npm using 2fa
+  --publish --otp 123456
+```
+
+You can perform a dry run by only specifying the new version for a release:
+
+```shell
+npm run release -- --pkg-version 0.10.2
+```
+
+To commit and tag the release:
+
+```shell
+npm run release -- --pkg-version 0.10.2 --commit
+```
+
+To publish the release:
+
+```shell
+npm run release -- --pkg-version 0.10.2 --publish
+```
diff --git a/packages/scripts/create-release.js b/tools/npm/release.js
similarity index 100%
rename from packages/scripts/create-release.js
rename to tools/npm/release.js


Reviews:
user: login: necolas
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-18T23:45:45Z
user: login: mellyeliu
state: APPROVED
author_association: MEMBER
submitted_at: 2025-03-19T18:09:15Z
user: login: necolas
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-19T18:56:10Z

Review comments:
diff_hunk: @@ -11,7 +11,8 @@
     "prettier": "prettier --write \"**/*.js\" \"**/*.ts\"",
     "prettier:report": "prettier --check \"**/*.js\"",
     "lint": "npm run lint:report -- --fix",
-    "lint:report": "eslint",
+    "lint:report": "eslint packages tools",
path: package.json
user: login: necolas
body: eslint wasn't linting
created_at: 2025-03-18T23:39:37Z
author_association: CONTRIBUTOR
diff_hunk: @@ -38,7 +39,7 @@
     "prettier": "^3.5.0",
     "prettier-plugin-hermes-parser": "^0.26.0",
     "rimraf": "^5.0.10",
-    "typescript": "^5.3.3"
path: package.json
user: login: necolas
body: typescript doesn't seem to be used by any monorepo tooling
created_at: 2025-03-18T23:45:36Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1,37 +1,3 @@
-# @stylexjs/scripts
+# scripts
path: packages/scripts/README.md
user: login: mellyeliu
body: what's the distinction we're making here between `scripts` and `tools` here? `tools` specifically as broader developer tooling unrelated to code logic?
created_at: 2025-03-19T18:08:30Z
author_association: MEMBER
diff_hunk: @@ -1,37 +1,3 @@
-# @stylexjs/scripts
+# scripts
path: packages/scripts/README.md
user: login: necolas
body: At the moment, everything left in `scripts` is installed as a `bin` in the dependent packages - so they're basically CLI tools used within some of the packages. The root tools are limited to managing monorepo-wide devx tasks like publishing to npm, precommit checks, etc. I'll add these notes to the READMEs
created_at: 2025-03-19T18:56:10Z
author_association: CONTRIBUTOR

PR comments:
user: login: github-actions[bot]
created_at: 2025-03-18T23:41:08Z
body: <!-- workflow-benchmarks-size-data -->
### workflow: benchmarks/size
Comparison of minified (terser) and compressed (brotli) size results, measured in bytes. Smaller is better.

> benchmarks@0.11.1 size:compare
> node size/compare.js /tmp/tmp.4PkNH9LUsz /tmp/tmp.2jjcDf9unL

| **Results** | **Base** | **Patch** | **Ratio** |  |
| :--- | ---: | ---: | ---: | ---: |
|  |  |  |  |
| **stylex/lib/stylex.js** |  |  |  |  |
| &middot; compressed | 985 | 985 | 1.00 |  |
| &middot; minified | 3,154 | 3,154 | 1.00 |  |
|  |  |  |  |
| **stylex/lib/StyleXSheet.js** |  |  |  |  |
| &middot; compressed | 1,266 | 1,266 | 1.00 |  |
| &middot; minified | 3,776 | 3,776 | 1.00 |  |
|  |  |  |  |
| **benchmarks/size/.build/bundle.js** |  |  |  |  |
| &middot; compressed | 537,611 | 537,611 | 1.00 |  |
| &middot; minified | 7,435,904 | 7,435,904 | 1.00 |  |
|  |  |  |  |
| **benchmarks/size/.build/stylex.css** |  |  |  |  |
| &middot; compressed | 100,609 | 100,609 | 1.00 |  |
| &middot; minified | 755,721 | 755,721 | 1.00 |  |
author_association: NONE
user: login: necolas
created_at: 2025-03-19T17:56:56Z
body: ping @mellyeliu 
author_association: CONTRIBUTOR