Monorepo HowTo?

I’m trying to learn how to build Ember apps in a monorepo setting using pnpm. This is obviously possible and i found some examples ( eg.: GitHub - NullVoxPopuli/limber: Glimdown playground for documentation, demos, etc ).

What I have:

  • A monorepo with an apps and packages folder
  • A test app that works
  • A V1 addon with a single component

What I do not have:

  • Any idea how to patch all that together
  • How to even start anything so that the app can see/use the addon.

The addon is a dependency of the app, using the workspace: protocol, but on starting the app, the addon component isn’t found.

The question

Is there any tutorial on

  • how to use a pnpm based monorepo, maybe adding turbo into it
  • using a single app and a single addon
  • explaining how to get from an empty repo to a repo with one addon, one app
  • and how to develop in such a setup

A couple follow-up questions:

  • (i assume the answer is yes) does your pnpm-workspace.yaml have both packages added?
  • is the app (and/or addon) using gjs/gts components or “regular” loose mode glimmer components?
  • If “regular” components, and the addon is v1, do you have a re-export in /app for the component?
  • if gjs/gts what import path are you using?

Anyway to answer your actual questions…

I’m not aware of any great tutorials (there might be some, i just don’t know) although there are a ton of v2 addons now that are more or less great examples.

As long as you have the ember app/addon setup correctly nothing about the pnpm or monorepo setup should be particularly special. I think we have a lot of lint/type related packages in the root package.json of ours. You may want to keep common packages (e.g. ember-source or ember-data or some of the embroider or babel related packages) consistent with an override in the root package although i’m not sure if this is best practice or not.

Consider adding some handy scripts to your root package.json also. Turbo can be handy but I wouldn’t say it’s super necessary unless you find yourself waiting on slow scripts a lot (we added it for lint/ts checks on all our packages to speed things up).

(i assume the answer is yes) does your pnpm-workspace.yaml have both packages added?

Yes

is the app (and/or addon) using gjs/gts components or “regular” loose mode glimmer components?

Regular, it’s just a learning setup right now, so I didn’t wan’t to add even more complexity till it does anything.

If “regular” components, and the addon is v1, do you have a re-export in /app for the component?

Yes

Anyway to answer your actual questions…

Ignore the following, continue with the next comment in this thread.

I was more looking for some general pointers on how to work once I have a repo with an addon and an app (I’m mostly doing backend stuff in a huge Java/Kotlin monorepo, so a JS monorepo is as new to me as it gets). What my understanding is:

  • After addon and app have been created, remove their node_modules
  • From the repo root pnpm install

Then what? What’s the development workflow?

  • pnpm -F <addon-name> build? That crashes with ERR_PNPM_RECURSIVE_RUN_FIRST_FAIL
  • Or is it pnpm -F <addon-name> start? That doesn’t throw an error, but does it work?
  • Then start the app with pnpm -F <app-name> start? While that somehow works, it gives me a strange deprecation warning of:
DEPRECATION: ember-cli-babel 5.x has been deprecated. Please upgrade to at least ember-cli-babel 6.6. Version 5.2.8 located: test-app -> test-addon -> ember-cli-babel
DEPRECATION: ember-cli-babel 5.x has been deprecated. Please upgrade to at least ember-cli-babel 6.6. Version 5.2.8 located: test-app -> test-addon -> ember-cli-htmlbars-inline-precompile -> ember-cli-babel
WARNING: [DEPRECATION] [DEPRECATION] Usage of the Ember Global is deprecated. You should import the Ember module or the specific API instead.

That doesn’t make any sense, app and addon are both generated with the latest ember-cli, so there shouldn’t be anything outdated. The addon contains only a single component with a static template, the app is just what you get when you setup a new app, but with the addon’s component added to the application template.

I’m obviously doing something very wrong, but I have no clue what that is.

Sorry if that sounds wild, but I’m totally lost here. My JS/Ember knowledge ends at “Repo with a single ember app in it” and googling mostly returns +10 years old SO questions about Ember 1.0.

@dknutsen

So … I’m officially stupid.

While trying back and force, I somehow removed the workspace:* dependency to the addon from the app and replaced it by "test-addon":"0.0.1". And that introduced a dependency on this 9 year old package:

Bringing back in the workspace dependency and doing

  • pnpm -F test-addon start followed by
  • pnpm -F test-app start

now gives my an app and an addon that are both live reloaded.

Sorry for the confusion.

1 Like

Awesome! Glad you got it figured out. That also explains the weird deprecations you were seeing.

FWIW you only need to run the addon (pnpm -F test-addon start) if you are writing tests in the addon dummy app and want to run those tests “live”. If you’re just wanting to write code in either the app or addon and see it rebuild the app that should work fine without having to run the addon “dev server”.

I personally find it annoying typing filter commands even though they’re not super long so we just wrote a script in our root package.json:

  "start": "pnpm -F <app name> start"

and then run pnpm start. Kind of dumb but it saves typing 10 chars a bunch of times.

1 Like

I just tried it and yes, ItJustWorks™. This is frickin awesome, thank you so much.

Do you by any change know it that also works for transitive dependencies, so two addons in the monorepo, one is using the other and the app only importing the former?

:tada:

I believe that should work just fine as well but I don’t think i’ve actually tried it. Closest we have in our app is engines (which are addons) that depend on an addon, but the app also depends on the addon.

1 Like