jaredpalmer / tsdx

Zero-config CLI for TypeScript package development
https://tsdx.io
MIT License
11.28k stars 507 forks source link

Add initial monorepo template #778

Closed jaredpalmer closed 2 years ago

jaredpalmer commented 4 years ago

This is a working monorepo template with tsdx.

I didn't bother with changing tsdx create yet. I will leave that work for others.

This template bootstraps a minimally viable monorepo project with 2 packages @mono/react and @mono/utils as well as an example playground. It's all powered by lerna, yarn workspaces, and tsdx. It has a similar workflow to regular tsdx: the example live reloads when changes are made to any package <package>/src/* folder that triggers a rebuild.

The onboarding for this template is more involved as we need to generate nested package.json's in addition to the root one. However, I'm comfortable with shipping this ASAP but telling users to search and replace @mono with @yourname until we integrate it more deeply into the create command.

Lastly, I think we will also want to add another few of templates to tsdx for packages within monorepos that assumes this core project structure.

Note: this is slightly different from multi-output #367. We still need that too. My idea is that this works today, and we can ship it. I'm already using this exact setup at work.

vercel[bot] commented 4 years ago

This pull request is being automatically deployed with Vercel (learn more).
To see the status of your deployment, click below or on the icon next to each commit.

🔍 Inspect: https://vercel.com/formium/tsdx/qg8qdasls
✅ Preview: https://tsdx-git-monorepo-template.formium.vercel.app

agilgur5 commented 4 years ago

Thanks for working on this Jared! This is top 3 or top 2 most-requested features and the only one I have no WIP for or much experience with.

I started reviewing this morning, will try to finish later tonight after work.


You may wanna mark this PR as resolves: #122

@kylemh per https://github.com/formium/tsdx/issues/122#issuecomment-661174229, without the tsdx create bit we shouldn't mark that one as resolved just yet. This should fix #275 though


The onboarding for this template is more involved as we need to generate nested package.json's in addition to the root one. However, I'm comfortable with shipping this ASAP but telling users to search and replace @mono with @yourname until we integrate it more deeply into the create command.

@jaredpalmer Agreed. I would say we might want to title the template as wip-monorepo instead, but as it's not integrated with tsdx create yet it's kind of WIP by definition and requires that manual step.

Lastly, I think we will also want to add another few of templates to tsdx for packages within monorepos that assumes this core project structure.

I was thinking we'd modify create to detect that it's in a monorepo (needed for #419 and #755 anyway) and alter the the output automatically based on that, but I'm not sure how involved that may be

Note: this is slightly different from multi-output #367. We still need that too.

Yes, multi-entry is very different; that's for multiple entries within one package. E.g. a component library like MUI or a utility library like Lodash, or, per my comments there, the two use-cases I already use it for, polyfill + ponyfill (window-resizeto, window-resizeto/polyfill) and library + built-in plugins (mst-persist, mst-persist/transforms). The recent #751 also goes over a difference between the two.

nareshbhatia commented 4 years ago

@jaredpalmer, this template looks great! I am in the process of porting over a hand-crafted monorepo to this template. So far so good - only thing I am missing is Storybook. Can you please provide some pointers on how to integrate storybook? I have seen the react + storybook template, however wondering how I could leverage it in the monorepo.

kylemh commented 4 years ago

Hey @nareshbhatia maybe this repo will help?

https://github.com/AirLabsTeam/air-core

nareshbhatia commented 4 years ago

Thank you, @kylemh - awesome resource! Good to see that your setup generates a single Storybook for all the packages.

kylemh commented 4 years ago

to be fair, only one package uses it, but if more do - it's ready for that

jaredpalmer commented 4 years ago

Probably not gonna have bandwidth to push this through for a week or 2, so if others want to jump on in and get this out feel free

nareshbhatia commented 4 years ago

@jaredpalmer, @kylemh - thanks for all your help. I have now successfully migrated a substantial monorepo to tsdx. Would love to have you take a quick glance and provide feedback.

The repo is here and the live Storybook is here. This repo essentially provides wrapper components over Material-UI and Formik. Also bunch of helper functions for date & time, http, web etc.

Some of the key challenges I solved were:

  1. A single Storybook encompassing multiple packages
  2. Replaced 'tsdx lint' with my own shareable eslint config
known-as-bmf commented 4 years ago

I fiddled around with tsdx and monorepo and came up with this: https://github.com/known-as-bmf/store

It uses rush and pnpm. I dont think pnpm is required, rush handles npm and yarn as well.

The philosophy of rush is to isolate packages/projects as much as possible from the "outside" (no relative references to things outside the project) and to have as little conf in each package as possible.

rush cli has a lot of commands to help managing a monorepo (from dev and devops standpoint) as well, which is a plus.

Also, there is no root package wrapping everything.

Quick overview

tools/

Under tools there are two "internal" packages.

toolchain

A project that depends on tsdx and re-exposes tsdx's bin. This package will be used as a build and test tool.

It also has base configurations for tsconfig and jest.

eslint-config-bmf

Custom eslint presets that extends the one provided by the "rush stack".

packages/

These are the actual projects I need to build, test and publish. Each package has a dev dependency to toolchain & eslint-config-bmf.

Configuration in each package is limited to very small files extending the base configurations.

For example:

.eslintrc.js

// some eslint patching stuff re-exported from rush
require('eslint-config-bmf/patch/modern-module-resolution');

module.exports = {
  root: true,
  extends: ['bmf'], // base conf from eslint-config-bmf
  parserOptions: { tsconfigRootDir: __dirname },
};

jest.config.js

module.exports = {
  preset: 'toolchain', // base conf from toolchain
};

tsconfig.json

{
  "extends": "./node_modules/toolchain/tsconfig.base.json",  // base conf from toolchain (no reference to ../tools/toolchain/...)
  "include": ["src", "test"]
}

The scripts in each package look like this:

package.json

{
  // ...
  "scripts": {
    "start": "",  // not figured that out yet 😁
    "build": "toolchain build", // basically a re-exported tsdx
    "test": "toolchain test", // basically a re-exported tsdx
    "test:coverage": "toolchain test --coverage", // basically a re-exported tsdx
    "lint": "toolchain lint" // basically a re-exported tsdx
  },
  // ...
}

Hope it helps someone.

sreimer15 commented 4 years ago

A small note on creating new packages (command or copying a template directory) that conform to the structure of the existing packages might be helpful. The PR looks great thank you!

GiancarlosIO commented 4 years ago

👀

OR13 commented 4 years ago

any update on this? really looking forward to something like npx tsdx create new-project --mono or similar...

timini commented 3 years ago

Will this work with yarn 2.0 berry?

jaredpalmer commented 3 years ago

@timini you can see it in action here https://github.com/jaredpalmer/tsdx-monorepo. I am pretty sure it doesn't work with it, but I haven't tested it.

rockmandash commented 2 years ago

Is there anyone know how to utilize tsdx with turborepo? I'd want to keep numerous packages in one place and publish them all with a single command.