stylex icon indicating copy to clipboard operation
stylex copied to clipboard

Feat/cli

Open Jta26 opened this issue 1 year ago • 2 comments

What changed / motivation ?

StyleX needs a bundler integration to work correctly. It also depends on Babel. However, this can be burden when trying to integrate into various projects built with project starters like Next.js, Solid Start and create-react-app. These projects have a complex bundler setup and it can be hard to integrate into them correctly. In some cases, like Next, the tooling may be written in Rust where an integration of the Babel plugin is impossible.

In order to provide a clean and reliable escape hatch for these scenarios, we should have a CLI that transforms an entire folder of JS files and outputs the resulting CSS file. (Tools like Tailwind and PandaCSS similarly side-step the built-in bundler because of how hard it is to integrate)

Expected Behaviour

For this example, consider a Next.js app configured to use the src/ folder with a src/app/ within that contains actual routes. When using the CLI, you'd be able to make another folder called, say, source/ and gitignore src/ folder. The source/ folder would contain all the same files that would normally be defined within the src/ folder, but you'd be able to use StyleX.

The CLI will then:

  • [x] Transform every single JS file within the source/ folder with the StyleX Babel plugin and output it at the same relative path in the src/ folder.
  • [x] While transforming it will collect the generated CSS for each file and output a CSS bundle at src/stylex-bundle.css.
  • [x] The transformed JS files should be updated to include an import of the stylex-bundle.css file. (Configurable)

With this process, the StyleX CLI would run first and generate an src/ folder with your actual source code. After this, the usual next dev script will be able to take over and run as usual.

Additionally, the CLI should also:

  • [x] Have a watch mode so that only the files that are edited are recompiled, and the generated CSS file is updated accordingly.
  • [x] Can be configured to also pre-compile a given list of node_modules packages and write the compiled files in some locations.
    • [x] Any processed JS files that import these packages, should be updated to rewrite their imports to point to the compiled location.

Finally, there are a few requirements for the configuration (This is probably a lot of the work):

  • [x] The basic configuration options should be possible with both CLI args and with a file config.
  • [x] It should be possible to configure the StyleX Babel plugin without a .babelrc file at the project root. (Next goes into Babel mode if it detect a .babelrc file)
  • [x] It should be possible to run additional Babel transforms in addition to the StyleX Babel plugin

Stretch Goals

  • [x] Avoid recompiling unchanged files between runs (even without watch mode).

Possible tools that can be used:

  • fb-watchman is a node client for watchman. A tool that tracks file changes within a folder
  • chokidar
  • node-watch

Recreated from https://github.com/facebook/stylex/pull/412

Jta26 avatar Apr 29 '24 18:04 Jta26

compressed-size: runtime library

Size change: 0.00 kB Total size: 2.52 kB

View unchanged
Filename: gzip (minify) kB size kB change % change
./packages/stylex/lib/stylex.js 1.04 (3.22) 0.00 (0.00) 0.0% (0.0%)
./packages/stylex/lib/StyleXSheet.js 1.48 (3.75) 0.00 (0.00) 0.0% (0.0%)

github-actions[bot] avatar Apr 29 '24 18:04 github-actions[bot]

compressed-size: e2e bundles

Size change: 0.00 kB Total size: 1132.93 kB

View unchanged
Filename: gzip (minify) kB size kB change % change
./apps/rollup-example/.build/bundle.js 1006.63 (10188.26) 0.00 (0.00) 0.0% (0.0%)
./apps/rollup-example/.build/stylex.css 126.30 (796.17) 0.00 (0.00) 0.0% (0.0%)

github-actions[bot] avatar Apr 29 '24 18:04 github-actions[bot]

This is looking good! One nit before we can ship it:

  • [ ] Way to ignore certain folders in "node_modules"

  • FUTURE:

    • [ ] Better logging! (This can wait)
      • Drop the file path prefix when logging
      • Don't log [Map Iterator]
    • [ ] Detect changed files since last run even outside of watch mode
      • There should also be a generated JSON file to track generated styles from each file so that the "merge" can happen without running compilation on all files again.
    • [ ] In watch mode, detect changes in all input directories
      • Currently it only detects changes in the "primary" directory
    • [ ] Use Node workers to compile in parallel

nmn avatar May 21 '24 10:05 nmn