Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: add nx to the repo #65

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open

Conversation

vsavkin
Copy link

@vsavkin vsavkin commented May 4, 2022

This PR is a follow-up of my conversation with Kent.

This PR shows how to add Nx to this repo, make some operations faster, and improve some dev ergonomics.

  1. Everything but "npm run dev" is cacheable now, so if you run "npm run build" twice, the second time will always be free.
  2. "npm run dev"'s output is nicer (see the video below).
  3. This PR enables Nx Cloud, which provides distributed caching and nicer UI for the invoked commands (see the video below). This is optional. Nx Cloud GitHub app can be enabled to post a comment to every PR with the links to the commands the PR ran.

Watch this video to see how everything works now: LINK

I intentionally didn't change anything about the repo itself to make it less overwhelming. So I want to mention that this isn't the best way to use Nx (or any such tool really). For instance, cypress and prisma can be made separate from app, which would make the dev ergonomics nicer etc.

This repo is also small, so both DX and performance advantages Nx offers aren't really that important here. The build command is fast enough without caching and distribution, and the output of say "validate" is understandable without the niceties Nx and Nx Cloud offer. It would have been easier to show the before and after if, say, all the stacks were in the same repo.

@kentcdodds
Copy link
Member

Even though you say this doesn't really suite the best use case scenario for the blues stack, I'm already really impressed. I think this is very cool. It's not that we need Nx to help with development of the stack. What we're doing here is making it so when people generate a Remix stack the output is a project pre-configured with Nx so people building their remix app have the best possible experience with the CLI during development. So Nx isn't for us developing the template, it's for everyone else using the template. I think this is a nice step up!

Copy link
Member

@kentcdodds kentcdodds left a comment

Choose a reason for hiding this comment

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

Thank you so much for taking the time to do this. I really like what I'm seeing here.

To be clear, this is a template project which people use to create new Remix apps. So anything in here that needs to be unique per user and per project needs to be accounted for in the remix.init/index.js script. Additionally, we should probably avoid including anything people need an account for by default.

I think there's a lot of benefit in starting people off with a basic nx config just by virtue of it being a great process manager. They can add more if they want to.

package.json Outdated Show resolved Hide resolved
project.json Outdated Show resolved Hide resolved
nx.json Outdated Show resolved Hide resolved
@vsavkin
Copy link
Author

vsavkin commented May 6, 2022

Made the changes:

  1. Remove all nx-cloud related stuff, remove unused npm dep.

  2. On "name": "blues-stack"

Nx most of the time is used for managing repos with multiple projects in them. There is no restriction on what that name is. You change the name to any value. You just need to make sure to change the following in nx.json to the same value:

  "cli": {
    "defaultProjectName": "blues-stack"
  },
  1. I want to mention that I marked pretty much everything (except dev) cacheable. Caching is cool etc, but you don't have to use it if you only care about process orchestration and the terminal output. If that's the case the cacheableOperations in nx.json can be removed, and the nx section in package.json can be reduced to this:
    "targets": {
      "test:e2e:run": { "dependsOn": [ "build-all" ] },
      "test:e2e:dev": { "dependsOn": [ "build-all" ] }
    }

@kentcdodds
Copy link
Member

This is looking good. I've updated things a bit to make the name that shows up in the output be what they called their app. One issue I bumped into is I did the following:

  1. Run npm run build
  2. Change server.ts
  3. Run npm run build

And I noticed that it didn't rebuild the server.ts file. It said it could use the cache. In looking at the config it looks like we only show where the output files go, but we don't say anything about the input files. How does nx know that it can trust the cache without knowing which input files there are? In this case, it's wrong 😬

Comment on lines +19 to +20

/.idea
Copy link
Member

Choose a reason for hiding this comment

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

@@ -95,5 +95,39 @@
},
"prisma": {
"seed": "ts-node --require tsconfig-paths/register prisma/seed.ts"
},
"nx": {
"targets": {
Copy link
Member

Choose a reason for hiding this comment

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

@vsavkin If I'm correct, this can be in the nx.json/project.json file as well?

Copy link
Member

Choose a reason for hiding this comment

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

Agreed. If we're going to have the other config files then let's keep all config in those files.

"@iarna/toml": "^2.2.5",
"sort-package-json": "^1.55.0"
}
"dependencies": {}
Copy link
Member

Choose a reason for hiding this comment

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

This file can be removed completely I think, since we don't have any dependencies anymore?

Copy link
Member

Choose a reason for hiding this comment

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

Yeah, we can probably remove this 👍

Copy link
Member

Choose a reason for hiding this comment

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

Unfortunately, we can't remove until remix-run/remix#3146 is merged/released

Copy link
Collaborator

Choose a reason for hiding this comment

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

Released in 1.5.0

@machour machour added the needs-response We need a response from the original author about the issue label Jun 8, 2022
@machour
Copy link
Collaborator

machour commented Jun 8, 2022

@vsavkin could you bring this PR up to date and go through the remarks? Thank you 🙏🏼

@MichaelDeBoey
Copy link
Member

@vsavkin Could you please rebase on latest main & resolve conflicts + conversations?

@jrestall
Copy link

jrestall commented Sep 12, 2022

Here's a sample remix.config.js I'm using to define routes in each Nx lib project under libs/example-feature/src/lib/routes/ instead of defining all routes in apps/remix-app/app/routes. It also uses watchPaths to only watch referenced libs for file changes rather than everything in the monorepo.

It's not thoroughly tested yet but maybe others using Nx will find it useful. You could consider adding the watchPaths example to this PR.

For the below to work you will need to patch out the code in emptyModulesPlugin that limits it to working on files under /app. https://github.com/remix-run/remix/blob/fd00bc657ef7f2b55c53e5f9dbd77185fa7d5734/packages/remix-dev/compiler/plugins/emptyModulesPlugin.ts#L20

const { createGlobPatternsForDependencies } = require("@nrwl/react/tailwind");
const { defineConventionalRoutes } = require("@remix-run/dev/dist/config/routesConvention");
const path = require("path");
const fs = require("fs");

/**
 * @type {import('@remix-run/dev').AppConfig}
 */
module.exports = {
  // ignore all files in routes folder
  ignoredRouteFiles: ["**/.*"],
  // add routes for all referenced lib projects
  routes: defineLibraryRoutes,
  // watch referenced libs for file changes during dev
  watchPaths: () => createGlobPatternsForDependencies(__dirname, "/**"),
};

async function defineLibraryRoutes() {
  let routeManifest;
  const appFolder = path.join(__dirname, "app");

  const libDirectories = createGlobPatternsForDependencies(__dirname, "/lib/");
  for (const dir of libDirectories) {
    // check if referenced library has routes defined
    const routesFolder = path.join(dir, "routes");
    if (!fs.existsSync(routesFolder)) continue;

    // get all routes from library based on default conventions
    let manifest = defineConventionalRoutes(dir, ["**/*.test.{js,jsx,ts,tsx}"]);

    // convert route file paths to be relative to app directory
    for (const [, route] of Object.entries(manifest)) {
      const routeFile = path.join(dir, route.file);
      route.file = path.relative(appFolder, routeFile);
    }

    routeManifest = { ...routeManifest, ...manifest };
  }

  return routeManifest;
}

@MichaelDeBoey
Copy link
Member

@vsavkin Are you still interested in adding NX to the repo?
I'd love to get this merged if you're still up for it!

@github-actions github-actions bot removed the needs-response We need a response from the original author about the issue label Apr 17, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants