Skip to content

A CLI to compile an entire folder with StyleX - #412

Closed
nmn wants to merge 26 commits into
mainfrom
feat/cli
Closed

A CLI to compile an entire folder with StyleX#412
nmn wants to merge 26 commits into
mainfrom
feat/cli

Conversation

@nmn

@nmn nmn commented Feb 2, 2024

Copy link
Copy Markdown
Collaborator

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:

  • 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.
  • While transforming it will collect the generated CSS for each file and output a CSS bundle at src/stylex-bundle.css.
  • 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:

  • Have a watch mode so that only the files that are edited are recompiled, and the generated CSS file is updated accordingly.
  • Can be configured to also pre-compile a given list of node_modules packages and write the compiled files in some locations.
    • 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):

  • The basic configuration options should be possible with both CLI args and with a file config.
  • 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)
  • It should be possible to run additional Babel transforms in addition to the StyleX Babel plugin

Stretch Goals

  • 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

@nmn nmn assigned Jta26 Feb 2, 2024
@facebook-github-bot facebook-github-bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Feb 2, 2024
@necolas

necolas commented Feb 2, 2024

Copy link
Copy Markdown
Contributor

Can be configured to also pre-compile a given list of node_modules packages

Note that this is kind of how the RN ecosystem (Expo) handles compiling RN packages for web, and it's pretty fragile because someone has to know a list of all dependencies and sub-dependencies that might be need processing. Probably a bit of a challenge to reliably do that automatically. Do you know if the other CLI-based projects have any alternatives, or does everything expect the developer to list out the packages to be processed?

@nmn

nmn commented Feb 2, 2024

Copy link
Copy Markdown
Collaborator Author

I know that Next has a transpilePackages option to compile packages manually. I'm following their lead on this since this.

I understand that the node_modules processing is going to be a challenge. I avoided doing this for a while, but there are simply too many esoteric build setups where such a system will always be needed. It unblocks StyleX usage without a huge ecosystem of bundler and framework plugins.

@github-actions

Copy link
Copy Markdown

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

Copy link
Copy Markdown

compressed-size: e2e bundles

Size change: 0.00 kB
Total size: 1128.55 kB

View unchanged
Filename: gzip (minify) kB size kB change % change
./apps/rollup-example/.build/bundle.js 1005.20 (10185.36) 0.00 (0.00) 0.0% (0.0%)
./apps/rollup-example/.build/stylex.css 123.34 (773.82) 0.00 (0.00) 0.0% (0.0%)

@nmn

nmn commented Feb 10, 2024

Copy link
Copy Markdown
Collaborator Author

Converting to draft while it's progress. Mark it as ready for review, when it's ... ready for review.

@Jta26

Jta26 commented Feb 14, 2024

Copy link
Copy Markdown
Contributor

This is ready for an initial review.

I have no idea how to make eslint ignore my test files that are transfomed by babel. I tried adding to the ignorePatterns in .eslintrc.js, but it doesn't seem to work. I'm open to ideas.

@Jta26

Jta26 commented Feb 14, 2024

Copy link
Copy Markdown
Contributor

This is ready for an initial review.

I have no idea how to make eslint ignore my test files that are transfomed by babel. I tried adding to the ignorePatterns in .eslintrc.js, but it doesn't seem to work. I'm open to ideas.

I figured it out

@shawngustaw

Copy link
Copy Markdown

@nmn any word on when this will land? If this is close I don't mind using a beta version and testing it out if you push a release!

Comment thread packages/cli/README.md Outdated
@@ -0,0 +1,257 @@
# @stylexjs/stylex

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't forget to replace this README

var stylex = _interopRequireWildcard(require("@stylexjs/stylex"));
var _otherStyles = _interopRequireDefault(require("./otherStyles"));
var _npmStyles = _interopRequireDefault(require("./npmStyles"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if for the sake of making these snapshots more readable we can avoid the babel module interop code appearing here

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this an option that can be passed into babel? These files are supposed to be the expected output of the CLI, so I think adding a specific option for tests degrades the integrity of the tests a bit.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, this is an option that can be passed into Babel. We don't want any transform other than StyleX to run. So we probably just need to set babelrc: false to ensure that is the case.

@@ -0,0 +1,40 @@
'use strict';

Object.defineProperty(exports, "__esModule", {

@necolas necolas Feb 21, 2024

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are these files mock snapshots? Or snapshots that accidentally got saved in the mocks directory? (File path is __mocks__/snapshot)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are files I created by manually running mocks/source through the CLI in order to use in my tests to validate the output.

Comment thread packages/cli/src/index.js Outdated
Comment on lines +22 to +47
chalk.green(`\n
______ _ _ __ __
/ ____| | | | | \\ \\ / /
| (___ | |_ _ _ | | ___ \\ V /
\\___ \\ | __| | | | | | | / _ \\ > <
____) | | |_ | |_| | | | | __/ / . \\
|_____/ \\__| \\__, | |_| \\___| /_/ \\_\\
__/ |
|___/
`),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't looks particularly readable

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's some escaped characters. I'll attach a screenshot of what it looks like in the CLI.

@Jta26 Jta26 Feb 24, 2024

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought it would add more flavor to the cli :)

If you feel like it gets in the way we can remove it obviously
image

Comment thread packages/cli/src/options.js Outdated
export default {
directory: {
alias: 'd',
describe: 'The directory to compile with Stylex',

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
describe: 'The directory to compile with Stylex',
describe: 'The directory to compile with StyleX',

@nmn

nmn commented Feb 21, 2024

Copy link
Copy Markdown
Collaborator Author

Looks like a few improvements still need to be made. I'll try to do this on my end shortly.

Comment thread packages/cli/package.json Outdated
Use the `lib` folder, not the `src` folder for the output of the package.
Comment thread packages/cli/package.json Outdated
@Jta26

Jta26 commented Mar 12, 2024

Copy link
Copy Markdown
Contributor

Closing to open a new one because something is messed up with github

@Jta26 Jta26 closed this Mar 12, 2024
@nmn nmn mentioned this pull request Apr 9, 2024
10 tasks
@Jta26 Jta26 mentioned this pull request Apr 29, 2024
10 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants