-
Notifications
You must be signed in to change notification settings - Fork 509
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
Changes from all commits
2084750
eb7ff55
7c98c94
3b333fe
56a75c2
49689f5
6096e7d
4b6f445
c825a88
4d0bfa3
1597c33
d761586
155b7d2
9ef4bca
70058f0
83b1419
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
*.log | ||
.DS_Store | ||
node_modules | ||
dist | ||
|
||
node_modules | ||
package-lock.json | ||
yarn.lock | ||
!/yarn.lock | ||
|
||
.yalc | ||
yalc.lock |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
MIT License | ||
|
||
Copyright (c) <year> <author> | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
in the Software without restriction, including without limitation the rights | ||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the Software is | ||
furnished to do so, subject to the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be included in all | ||
copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
SOFTWARE. |
Original file line number | Diff line number | Diff line change | ||||||||
---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,85 @@ | ||||||||||
# TSDX Monorepo User Guide | ||||||||||
|
||||||||||
## Usage | ||||||||||
|
||||||||||
This monorepo is setup for a dummy `@mono/` NPM organization. There are 2 packages by default: | ||||||||||
|
||||||||||
- `@mono/react` - A placholder React component | ||||||||||
- `@mono/utils` - A utils 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. | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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. There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 |
||||||||||
|
||||||||||
After that you can install all the dependencies in the root directory. Since the monorepo uses Lerna and Yarn Workspaces, npm CLI is not supported (only yarn). | ||||||||||
|
||||||||||
```sh | ||||||||||
yarn install | ||||||||||
``` | ||||||||||
|
||||||||||
This will install all dependencies in each project, build them, and symlink them via Lerna | ||||||||||
|
||||||||||
## Development workflow | ||||||||||
|
||||||||||
In one terminal, run tsdx watch in parallel: | ||||||||||
|
||||||||||
```sh | ||||||||||
yarn start | ||||||||||
``` | ||||||||||
|
||||||||||
This builds each package to `<packages>/<package>/dist` and runs the project in watch mode so any edits you save inside `<packages>/<package>/src` cause a rebuild to `<packages>/<package>/dist`. The results will stream to to the terminal. | ||||||||||
|
||||||||||
### Using the example/playground | ||||||||||
|
||||||||||
You can play with local packages in the Parcel-powered example/playground. | ||||||||||
|
||||||||||
```sh | ||||||||||
cd example | ||||||||||
yarn install # or yarn install | ||||||||||
yarn start | ||||||||||
``` | ||||||||||
|
||||||||||
This will start the example/playground on `localhost:1234`. If you have lerna running watch in parallel mode in one terminal, and then you run parcel, your playground will hot reload when you make changes to any imported module whose source is inside of `packages/*/src/*`. Note that to accomplish this, each package's `start` command passes TDSX the `--noClean` flag. This prevents Parcel from exploding between rebuilds because of File Not Found errors. | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This helps readability, please approve. |
||||||||||
|
||||||||||
Important Safety Tip: When adding/altering packages in the playground, use `alias` object in package.json. This will tell Parcel to resolve them to the filesystem instead of trying to install the package from NPM. It also fixes duplicate React errors you may run into. | ||||||||||
|
||||||||||
#### Yalc | ||||||||||
|
||||||||||
[Yalc](https://github.com/whitecolor/yalc) is an alternative to `yarn/npm link` (and Parcel aliasing) that many developers find useful because it more closely mimics how NPM works. It works kind of like a local package registry via filesystem and symlinking magic. | ||||||||||
|
||||||||||
To do this, install yalc globally. | ||||||||||
|
||||||||||
Using NPM: | ||||||||||
|
||||||||||
```sh | ||||||||||
npm i yalc -g | ||||||||||
``` | ||||||||||
|
||||||||||
Using Yarn: | ||||||||||
|
||||||||||
```sh | ||||||||||
yarn global add yalc | ||||||||||
``` | ||||||||||
|
||||||||||
Then in each package's `start` command add a [`yalc publish`](https://github.com/whitecolor/yalc#publish) or `yalc push` as an TSDX `--onSuccess` hook. | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
an TSDX -> a TSDX |
||||||||||
|
||||||||||
```diff | ||||||||||
"scripts": { | ||||||||||
- "start": "tsdx watch --verbose --noClean", | ||||||||||
+ "start": "tsdx watch --verbose --noClean --onSuccess yalc publish", | ||||||||||
Comment on lines
+68
to
+69
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Should be updated to match the updated watch command that uses
This comment was marked as spam.
Sorry, something went wrong. |
||||||||||
"build": "tsdx build --tsconfig tsconfig.build.json", | ||||||||||
"test": "tsdx test", | ||||||||||
"lint": "tsdx lint", | ||||||||||
"prepublish": "npm run build" | ||||||||||
}, | ||||||||||
``` | ||||||||||
|
||||||||||
In your example directory, now add each package via yalc | ||||||||||
|
||||||||||
```sh | ||||||||||
yalc add <package> | ||||||||||
# or | ||||||||||
yalc link <package> | ||||||||||
``` | ||||||||||
|
||||||||||
There's definitely room for improvement with this workflow, so please contribute if you come up with something better. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
node_modules | ||
.cache | ||
dist |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="UTF-8" /> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> | ||
<meta http-equiv="X-UA-Compatible" content="ie=edge" /> | ||
<title>Playground</title> | ||
</head> | ||
|
||
<body> | ||
<div id="root"></div> | ||
<script src="./index.tsx"></script> | ||
</body> | ||
</html> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import 'react-app-polyfill/ie11'; | ||
import * as React from 'react'; | ||
import * as ReactDOM from 'react-dom'; | ||
import { Thing } from '@mono/react'; | ||
|
||
const App = () => { | ||
return ( | ||
<div> | ||
<Thing message="hello worldzz" /> | ||
</div> | ||
); | ||
}; | ||
|
||
ReactDOM.render(<App />, document.getElementById('root')); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
{ | ||
"name": "@mono/example", | ||
"version": "1.0.0", | ||
"main": "index.js", | ||
"license": "MIT", | ||
"scripts": { | ||
"start": "parcel index.html", | ||
"build": "parcel build index.html" | ||
}, | ||
"dependencies": { | ||
"react-app-polyfill": "^1.0.0" | ||
}, | ||
"alias": { | ||
"@mono/react": "../packages/react", | ||
"react": "../node_modules/react", | ||
"react-dom": "../node_modules/react-dom/profiling", | ||
"scheduler/tracing": "../node_modules/scheduler/tracing-profiling" | ||
agilgur5 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
}, | ||
"devDependencies": { | ||
"@types/react": "^16.9.11", | ||
"@types/react-dom": "^16.8.4", | ||
"parcel": "^1.12.3", | ||
"typescript": "^3.4.5" | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
{ | ||
"compilerOptions": { | ||
"allowSyntheticDefaultImports": false, | ||
"target": "es5", | ||
"module": "commonjs", | ||
"jsx": "react", | ||
"moduleResolution": "node", | ||
"noImplicitAny": false, | ||
"noUnusedLocals": false, | ||
"noUnusedParameters": false, | ||
"removeComments": true, | ||
"strictNullChecks": true, | ||
"preserveConstEnums": true, | ||
"sourceMap": true, | ||
"lib": ["es2015", "es2016", "dom"], | ||
"types": ["node"] | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
{ | ||
"version": "0.0.0", | ||
"registry": "https://registry.npmjs.org/", | ||
"publishConfig": { | ||
"access": "public" | ||
agilgur5 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
}, | ||
Comment on lines
+3
to
+6
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. are these necessary? I believe these are the defaults There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. not for scoped packages |
||
"npmClient": "yarn", | ||
"useWorkspaces": true, | ||
"packages": ["packages/*"] | ||
} |
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,28 @@ | ||||||||||||||||||||||||
{ | ||||||||||||||||||||||||
"name": "mono", | ||||||||||||||||||||||||
"private": true, | ||||||||||||||||||||||||
"devDependencies": { | ||||||||||||||||||||||||
"@types/react": "^16.9.43", | ||||||||||||||||||||||||
"@types/react-dom": "^16.9.8", | ||||||||||||||||||||||||
"lerna": "^3.15.0", | ||||||||||||||||||||||||
"react": "^16.13.1", | ||||||||||||||||||||||||
"react-dom": "^16.13.1", | ||||||||||||||||||||||||
"tsdx": "^0.13.2", | ||||||||||||||||||||||||
"typescript": "^3.9.7" | ||||||||||||||||||||||||
}, | ||||||||||||||||||||||||
"workspaces": [ | ||||||||||||||||||||||||
"packages/*" | ||||||||||||||||||||||||
], | ||||||||||||||||||||||||
"scripts": { | ||||||||||||||||||||||||
"lerna": "lerna", | ||||||||||||||||||||||||
"start": "lerna run start --stream --parallel", | ||||||||||||||||||||||||
"test": "lerna run test --", | ||||||||||||||||||||||||
"build": "lerna run build", | ||||||||||||||||||||||||
"prepublish": "lerna run prepublish" | ||||||||||||||||||||||||
}, | ||||||||||||||||||||||||
"prettier": { | ||||||||||||||||||||||||
"trailingComma": "es5", | ||||||||||||||||||||||||
"singleQuote": true, | ||||||||||||||||||||||||
"semi": true | ||||||||||||||||||||||||
} | ||||||||||||||||||||||||
Comment on lines
+23
to
+27
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Let's keep consistent with what all the other templates use
This comment was marked as spam.
Sorry, something went wrong. |
||||||||||||||||||||||||
} | ||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. husky should be included in the root package.json, however its a nice to have feature compared to being able to init a mono repo with mostly the same tsdx configs. |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,5 @@ | ||||||
# @mono/react | ||||||
|
||||||
[![Stable release](https://img.shields.io/npm/v/@mono/utils.svg)](https://npm.im/@mono/utils) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
|
||||||
Official React SDK for @mono | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this a component or an SDK? In the README it says component. In If it's a component it might be more intuitive to rename this to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It can be either, it’s just a placeholder. I copied it from the project I’m working on. My plan was to make this fairly generic, and then build some more templates/plopfiles for different kinds of packages people will want. |
Original file line number | Diff line number | Diff line change | ||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,36 @@ | ||||||||||||||||
{ | ||||||||||||||||
"name": "@mono/react", | ||||||||||||||||
"version": "0.0.0", | ||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
MIT license missing. We probably want to include a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Lerna copies root license into each package before publishing There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh, does it do that for |
||||||||||||||||
"description": "Official React library for @mono", | ||||||||||||||||
"author": "Jared Palmer", | ||||||||||||||||
"repository": { | ||||||||||||||||
"type": "git", | ||||||||||||||||
"url": "git+https://github.com/mono/mono.git", | ||||||||||||||||
"directory": "packages/react" | ||||||||||||||||
}, | ||||||||||||||||
"scripts": { | ||||||||||||||||
"start": "tsdx watch --tsconfig tsconfig.build.json --verbose --noClean", | ||||||||||||||||
"build": "tsdx build --tsconfig tsconfig.build.json", | ||||||||||||||||
"test": "tsdx test", | ||||||||||||||||
"lint": "tsdx lint", | ||||||||||||||||
"prepublish": "npm run build" | ||||||||||||||||
}, | ||||||||||||||||
"main": "dist/index.js", | ||||||||||||||||
"module": "dist/react.esm.js", | ||||||||||||||||
"typings": "dist/index.d.ts", | ||||||||||||||||
"files": [ | ||||||||||||||||
"README.md", | ||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||
"dist" | ||||||||||||||||
], | ||||||||||||||||
"peerDependencies": { | ||||||||||||||||
"react": "^16.8.0", | ||||||||||||||||
"react-dom": "^16.8.0" | ||||||||||||||||
}, | ||||||||||||||||
Comment on lines
+25
to
+28
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Let's keep this consistent with the React templates There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 |
||||||||||||||||
"dependencies": { | ||||||||||||||||
"@mono/utils": "^0.0.0", | ||||||||||||||||
"tslib": "^2.0.0" | ||||||||||||||||
}, | ||||||||||||||||
"publishConfig": { | ||||||||||||||||
"access": "public" | ||||||||||||||||
} | ||||||||||||||||
Comment on lines
+33
to
+35
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. is this necessary? |
||||||||||||||||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import * as React from 'react'; | ||
import { toSlug } from '@mono/utils'; | ||
|
||
export interface ThingProps { | ||
message: string; | ||
} | ||
|
||
export function Thing(props: ThingProps) { | ||
return <>{toSlug(props.message)}</>; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
describe('@mono/react', () => { | ||
it('works', () => { | ||
expect(true).toBe(true); | ||
}); | ||
}); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's keep consistent with the test in the React template. Could add |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
{ | ||
"extends": "../../tsconfig.build.json", | ||
"include": ["src", "types", "../../types"] | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
# @mono/utils | ||
|
||
[![Stable release](https://img.shields.io/npm/v/@mono/utils.svg)](https://npm.im/@mono/utils) | ||
|
||
Shared utilities for various `@mono` packages. | ||
|
||
**Important:** This package is intended for internal use by the @mono libraries. You should not use it directly in your production projects, as the APIs can and will change often without regard to sem-ver. You have been warned! |
Original file line number | Diff line number | Diff line change | ||||||
---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,26 @@ | ||||||||
{ | ||||||||
"name": "@mono/utils", | ||||||||
"version": "0.0.0", | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
MIT license missing. We probably want to include a |
||||||||
"description": "Internal, shared utilities", | ||||||||
"author": "Jared Palmer <[email protected]>", | ||||||||
"scripts": { | ||||||||
"start": "tsdx watch --tsconfig tsconfig.build.json --verbose --noClean", | ||||||||
"build": "tsdx build --tsconfig tsconfig.build.json", | ||||||||
"test": "tsdx test", | ||||||||
"lint": "tsdx lint", | ||||||||
"prepublish": "npm run build" | ||||||||
}, | ||||||||
"main": "dist/index.js", | ||||||||
"module": "dist/utils.esm.js", | ||||||||
"typings": "dist/index.d.ts", | ||||||||
"files": [ | ||||||||
"README.md", | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||
"dist" | ||||||||
], | ||||||||
"dependencies": { | ||||||||
"tslib": "^2.0.0" | ||||||||
}, | ||||||||
"publishConfig": { | ||||||||
"access": "public" | ||||||||
} | ||||||||
Comment on lines
+23
to
+25
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. is this necessary? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, it allows you skip passing a flag when you publish a scoped package. However, when we revamp the create command, we should ask explicitly whether the repo is going to be private or public if it is scoped. |
||||||||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
/** | ||
* Return a slugified copy of a string. | ||
* | ||
* @param {string} str The string to be slugified | ||
* @return {string} The slugified string. | ||
*/ | ||
export function toSlug(str: string): string { | ||
let s = str; | ||
if (!s) { | ||
return ''; | ||
} | ||
s = s.toLowerCase().trim(); | ||
s = s.replace(/ & /g, ' and '); | ||
s = s.replace(/[ ]+/g, '-'); | ||
s = s.replace(/[-]+/g, '-'); | ||
s = s.replace(/[^a-z0-9-]+/g, ''); | ||
s = s.length > 32 ? s.substr(0, 32) : s; | ||
return s; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
describe('@mono/utils', () => { | ||
it('works', () => { | ||
expect(true).toBe(true); | ||
}); | ||
}); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's keep consistent with the test in the basic template or have a simple test for |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
{ | ||
"extends": "../../tsconfig.build.json", | ||
"include": ["src", "types", "../../types"] | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
{ | ||
"compilerOptions": { | ||
"module": "esnext", | ||
"lib": ["dom", "esnext"], | ||
"importHelpers": true, | ||
"declaration": true, | ||
"sourceMap": true, | ||
"strict": true, | ||
"noUnusedLocals": true, | ||
"noUnusedParameters": true, | ||
"noImplicitReturns": true, | ||
"noFallthroughCasesInSwitch": true, | ||
"moduleResolution": "node", | ||
"jsx": "react", | ||
"esModuleInterop": true | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why no lockfiles? is this a Lerna thing?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lerna thing. You don’t want lockfiles in packages/did because modules are hoisted to the yarn workspace
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But surely we still want the root yarn.lock on line 13?