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

Add initial monorepo template #778

Closed
wants to merge 16 commits into from
Closed

Add initial monorepo template #778

wants to merge 16 commits into from

Conversation

jaredpalmer
Copy link
Owner

@jaredpalmer jaredpalmer commented Jul 19, 2020

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

This comment has been minimized.

Copy link
Contributor

@kylemh kylemh left a comment

Choose a reason for hiding this comment

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

One simplification could be to just have 2 root-level tsconfigs and one top-level .prettierrc

You may wanna mark this PR as resolves: #122

Good work! I've also got: https://github.com/AirLabsTeam/air-core FWIW

Comment on lines 1 to 25
dist
compiled
*.log
coverage
.DS_Store
next.d.ts
legacy.d.ts
.idea
*.orig

node_modules
package-lock.json
yarn.lock
!/yarn.lock

website/translated_docs
website/build
website/yarn.lock
website/node_modules
website/i18n
!website/yarn.lock

.vercel
.yalc
yalc.lock
Copy link
Contributor

Choose a reason for hiding this comment

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

Would you need to do **/X to some of these?

templates/monorepo/package.json Outdated Show resolved Hide resolved
@agilgur5
Copy link
Collaborator

agilgur5 commented Jul 20, 2020

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 #122 (comment), 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.

@agilgur5 agilgur5 linked an issue Jul 20, 2020 that may be closed by this pull request
Copy link
Collaborator

@agilgur5 agilgur5 left a comment

Choose a reason for hiding this comment

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

Ok, here's a first pass. Still need to dive a bit into the README but otherwise have gone through almost everything with a lens.

Sorry that the comments are a bit scattered in terms of order as I made them throughout multiple days, GitHub doesn't let you sort them 😕

Main issues are around inconsistency with existing templates and tsconfig options that don't work with TSDX.

templates/monorepo/tsconfig.build.json Outdated Show resolved Hide resolved
templates/monorepo/.gitignore Outdated Show resolved Hide resolved
templates/monorepo/README.md Outdated Show resolved Hide resolved
templates/monorepo/packages/utils/tsconfig.build.json Outdated Show resolved Hide resolved
templates/monorepo/tsconfig.build.json Outdated Show resolved Hide resolved
Comment on lines +3 to +6
"registry": "https://registry.npmjs.org/",
"publishConfig": {
"access": "public"
},
Copy link
Collaborator

Choose a reason for hiding this comment

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

are these necessary? I believe these are the defaults

Copy link
Owner Author

Choose a reason for hiding this comment

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

not for scoped packages


Unlike other TSDX templates, the developer experience for this template is currently a bit more manual.

Your first order of business will be to search and replace `@mono` for the npm organization of your own.
Copy link
Collaborator

@agilgur5 agilgur5 Jul 24, 2020

Choose a reason for hiding this comment

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

Also need to change author/username and LICENSE file. And description of packages, though that one's a given since the other templates don't do that either.

Copy link
Owner Author

Choose a reason for hiding this comment

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

Lerna syncs the license from root prior to publishing for each package. lerna/lerna@5863564

Comment on lines +25 to +28
"peerDependencies": {
"react": "^16.8.0",
"react-dom": "^16.8.0"
},
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
"peerDependencies": {
"react": "^16.8.0",
"react-dom": "^16.8.0"
},
"peerDependencies": {
"react": ">=16",
},

Let's keep this consistent with the React templates

Copy link
Owner Author

Choose a reason for hiding this comment

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

Oof I didn't realize this was still there. Packages that use hooks actually need to specify React as peer dep as "react": "^16.8.0" (when hooks were introduced). We should discuss in another issue tho as we will need to change the other templates too

@@ -0,0 +1,36 @@
{
"name": "@mono/react",
"version": "0.0.0",
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
"version": "0.0.0",
"version": "0.0.0",
"license": "MIT",

MIT license missing. We probably want to include a LICENSE file in each package as well. NPM will automatically include any LICENSE file when publishing (similar to README.md)

Copy link
Owner Author

Choose a reason for hiding this comment

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

Lerna copies root license into each package before publishing

Copy link
Collaborator

Choose a reason for hiding this comment

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

Oh, does it do that for package.json.license too? Fancy

@@ -0,0 +1,26 @@
{
"name": "@mono/utils",
"version": "0.0.0",
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
"version": "0.0.0",
"version": "0.0.0",
"license": "MIT",

MIT license missing. We probably want to include a LICENSE file in each package as well. NPM will automatically include any LICENSE file when publishing (similar to README.md)

@nareshbhatia
Copy link

@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
Copy link
Contributor

kylemh commented Jul 27, 2020

Hey @nareshbhatia maybe this repo will help?

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

@nareshbhatia
Copy link

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

@kylemh
Copy link
Contributor

kylemh commented Jul 27, 2020

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

@jaredpalmer
Copy link
Owner Author

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
Copy link

@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
Copy link

known-as-bmf commented Aug 15, 2020

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.

@vercel vercel bot temporarily deployed to Preview September 11, 2020 13:58 Inactive
Co-authored-by: Anton Gilgur <agilgur5@gmail.com>
Co-authored-by: Anton Gilgur <agilgur5@gmail.com>
@vercel vercel bot temporarily deployed to Preview September 11, 2020 14:20 Inactive
Co-authored-by: Anton Gilgur <agilgur5@gmail.com>
@GiancarlosIO

This comment has been minimized.

@OR13
Copy link

OR13 commented Nov 6, 2020

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

@timini
Copy link

timini commented Nov 19, 2020

Will this work with yarn 2.0 berry?

@jaredpalmer
Copy link
Owner Author

@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
Copy link

rockmandash commented Dec 26, 2021

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
problem: stale Issue has not been responded to in some time scope: templates Related to an init template, not necessarily to core (but could influence core) topic: monorepo Related to Lerna monorepos
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Guidance on current usage with Lerna and Yarn Workspaces?