41
loading...
This website collects cookies to deliver better user experience
Related Article - Share Code Between React Native & React.js
Learn more about Yarn Workspaces - Monorepo Approach
npm install --global lerna
npx lerna init // initialize lerna workspace
lerna-workspace
/packages
lerna.json
package.json
{
- "name": "root",
+ "name": "@workspace/root",
}
{
"packages": [
"packages/*"
],
+ "version": "independent",
+ "npmClient": "yarn",
+ "useWorkspaces": true
}
{
"name": "@workspace/root",
"private": true,
"devDependencies": {
"lerna": "^4.0.0"
},
+ "workspaces": {
+ "packages": [
+ "packages/**"
+ ]
+ }
}
cd packages
npx create-react-app components --template typescript // common component
npx create-react-app app --template typescript // react.js web application
lerna-workspace
/node_modules
/packages
/app
package.json
...
/components
package.json
...
lerna.json
package.json
yarn.lock
yarn add --dev craco -W
/packages/app/package.json
{
- "name": "app",
+ "name": "@workspace/app",
}
{
- "name": "components",
- "name": "@workspace/components",
}
{
"dependencies": {
+ "@workspace/components": "0.1.0",
...
}
}
{
"scripts": {
+ "start": "craco start",
+ "build": "craco build",
+ "test": "craco test",
+ "eject": "craco eject"
}
}
/package.json
{
+ "scripts": {
+ "start": "lerna exec --scope @workspace/app -- yarn start"
+ }
}
{
"scripts": {
+ "start": "react-scripts start"
}
}
function App() {
const [count, setCount] = useState(0);
return (
<button
onClick={() => setCount((prev) => ++prev)}
>
Increment
</button>
)
}
cd components
cd src
mkdir components
import * as React from "react";
interface Props {
onClick: () => void;
}
const Button: React.FC<Props> = (props) => {
return <button {...props}>Increment</button>;
};
export default Button;
import Button from "./components/Button";
export { Button };
Let's add to packages/app/src/App.js
+ import { Button } from "@workspace/components";
function App() {
const [count, setCount] = useState(0);
console.log(Button);
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
+ Your count is {count}
+ <Button onClick={() => setCount((prev) => ++prev)} />
</header>
</div>
);
}
export default App;
{
+ "main": "./src/index.tsx"
}
yarn lerna bootstrap // this will bootstrap application and make shared components/links components
yarn start
cd packages/app/
touch craco.config.js
const path = require("path");
const { getLoader, loaderByName } = require("@craco/craco");
const packages = [];
packages.push(path.join(__dirname, "../components"));
module.exports = {
webpack: {
configure: (webpackConfig, arg) => {
const { isFound, match } = getLoader(
webpackConfig,
loaderByName("babel-loader")
);
if (isFound) {
const include = Array.isArray(match.loader.include)
? match.loader.include
: [match.loader.include];
match.loader.include = include.concat(packages);
}
return webpackConfig;
},
},
};
{
"scripts": {
+ "start": "craco start",
}
}
// package.json
{
+ "scripts": {
+ "test": "lerna run test"
+ }
}
// packages/app/package.json
{
+ "scripts": {
+ "test": "echo app packages test scripts"
+ }
}
// packages/components/package.json
{
+ "scripts": {
+ "test": "echo component packages test scripts"
+ }
}
lerna info Executing command in 2 packages: "yarn run test"
lerna info run Ran npm script 'test' in '@workspace/components' in 0.5s:
$ echo component packages test scripts
component packages test scripts
lerna info run Ran npm script 'test' in '@workspace/app' in 0.4s:
$ echo app packages test scripts
app packages test scripts
lerna success run Ran npm script 'test' in 2 packages in 0.9s:
lerna success - @workspace/app
lerna success - @workspace/components
// package.json
{
+ "scripts": {
+ "test": "lerna run test --scope=@workspace/app"
+ }
}
lerna notice filter including "@workspace/app"
lerna info filter [ '@workspace/app' ]
lerna info Executing command in 1 package: "yarn run test"
lerna info run Ran npm script 'test' in '@workspace/app' in 0.7s:
$ echo app packages test scripts
app packages test scripts
lerna success run Ran npm script 'test' in 1 package in 0.7s:
lerna success - @workspace/app
// package.json
{
+ "scripts": {
+ "test": "lerna run test --scope={@workspace/app,@workspace/components}"
+ }
}
lerna notice filter including ["@workspace/app","@workspace/components"]
lerna info filter [ '@workspace/app', '@workspace/components' ]
lerna info Executing command in 2 packages: "yarn run test"
lerna info run Ran npm script 'test' in '@workspace/components' in 0.6s:
$ echo component packages test scripts
component packages test scripts
lerna info run Ran npm script 'test' in '@workspace/app' in 0.3s:
$ echo app packages test scripts
app packages test scripts
lerna success run Ran npm script 'test' in 2 packages in 0.9s:
lerna success - @workspace/app
lerna success - @workspace/components
{
+ "scripts": {
+ "new-version": "lerna version --conventional-commits --yes",
+ }
}
> [email protected] new-version /Users/kpiteng/lerna
> lerna version --conventional-commits --yes
lerna notice cli v4.0.0
lerna info current version 1.0.0
lerna info Looking for changed packages since v1.0.0
lerna info getChangelogConfig Successfully resolved preset "conventional-changelog-angular"
Changes:
- @workspace/app: 1.0.0 => 1.0.1
- @workspace/components: 1.0.0 => 1.0.1
lerna info auto-confirmed
lerna info execute Skipping releases
lerna info git Pushing tags...
lerna success version finished
// packages/app/package.json
{
"name": "@workspace/app"
"version": "1.0.1"
}
// packages/components/package.json
{
"name": "@workspace/components",
"version": "1.0.1"
}
// package.json
{
"scripts": {
+ "test": "lerna run test --since"
+ "diff": "lerna diff"
}
}
// packages/app/src/App.js
function App() {
+ const [counter, setCounter] = useState(0);
}
> [email protected] diff /Users/kpiteng/lerna
> lerna diff
lerna notice cli v4.0.0
diff --git a/packages/app/src/App.js
module.exports = () => {
const [count, setCount] = useState(0);
+ const [counter, setCounter] = useState(0);
}