{"id":14958060,"url":"https://github.com/liujingbreak/plink","last_synced_at":"2025-10-24T14:30:43.554Z","repository":{"id":37982149,"uuid":"180063206","full_name":"liujingbreak/plink","owner":"liujingbreak","description":"Monorepo and multi-repo management tool, an extensible command line, comprehensive utitilies to organize your project in form of Node.js packages, work with create-react-app, @angular/cli, express.js... (mainly written in Typescript)","archived":false,"fork":false,"pushed_at":"2024-07-18T11:43:43.000Z","size":105838,"stargazers_count":7,"open_issues_count":8,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-10-05T14:03:12.261Z","etag":null,"topics":["bazel","lerna","monorepo","node-js","typescript","workspaces","yarn"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/liujingbreak.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-04-08T03:32:48.000Z","updated_at":"2023-11-05T11:20:45.000Z","dependencies_parsed_at":"2023-10-11T17:52:02.171Z","dependency_job_id":"5ba479e0-75b5-4afc-b8e0-0f4368aef38c","html_url":"https://github.com/liujingbreak/plink","commit_stats":{"total_commits":1011,"total_committers":8,"mean_commits":126.375,"dds":"0.19881305637982194","last_synced_commit":"e485147177a0a6060abba06e2ef33694d3bd05db"},"previous_names":["liujingbreak/dr-comp-package"],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/liujingbreak%2Fplink","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/liujingbreak%2Fplink/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/liujingbreak%2Fplink/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/liujingbreak%2Fplink/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/liujingbreak","download_url":"https://codeload.github.com/liujingbreak/plink/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":219868597,"owners_count":16555871,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bazel","lerna","monorepo","node-js","typescript","workspaces","yarn"],"created_at":"2024-09-24T13:16:08.429Z","updated_at":"2025-10-24T14:30:38.508Z","avatar_url":"https://github.com/liujingbreak.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# More than package and project link toolkit\n\n```\n ██████╗  ██╗      ██╗ ███╗   ██╗ ██╗  ██╗ \n ██╔══██╗ ██║      ██║ ████╗  ██║ ██║ ██╔╝ \n ██████╔╝ ██║      ██║ ██╔██╗ ██║ █████╔╝  \n ██╔═══╝  ██║      ██║ ██║╚██╗██║ ██╔═██╗  \n ██║      ███████╗ ██║ ██║ ╚████║ ██║  ██╗ \n ╚═╝      ╚══════╝ ╚═╝ ╚═╝  ╚═══╝ ╚═╝  ╚═╝ \n```\n\n## 0. The repositity of this package itself is not only a toolkit, but also a gathering of projects in form of monorepo\n\nSome of the top important projects it involves are:\n\n- @wfh/reactivizer - [an Reactive programming library based on top of RxJS](./main/packages/reactivizer/README.md)\n- @wfh/algorithms - [Extensible algorithms and data structure that Plink's project depends on](./main/packages/algorithms/README.md)\n\nIf heard about **Lerna**, **Yarn**'s workspace concept and [Nx](https://nx.dev), yes this tool is a little bit in the same category.\n\n\u003c!-- vscode-markdown-toc --\u003e\n* 1. [Introduction of this source code repository](#Introductionofthissourcecoderepository)\n* 2. [Purpose](#Purpose)\n* 3. [A command line tool](#Acommandlinetool)\n\t* 3.1. [Why Monorepos ?](#WhyMonorepos)\n\t* 3.2. [Plink monorepo multiple-repo style](#Plinkmonorepomultiple-repostyle)\n\t* 3.3. [Directory structure may look like:](#Directorystructuremaylooklike:)\n\t\t* 3.3.1. [Dependency installation space](#Dependencyinstallationspace)\n\t\t* 3.3.2. [Project and Packages directory](#ProjectandPackagesdirectory)\n\t* 3.4. [How it works](#Howitworks)\n* 4. [Features](#Features)\n* 5. [Environment variables and working directories](#Environmentvariablesandworkingdirectories)\n\t\t* 5.1. [Change `dist` to other directory](#Changedisttootherdirectory)\n* 6. [Unlike Yarn workspaces](#UnlikeYarnworkspaces)\n* 7. [Dependency Hoist](#DependencyHoist)\n\n\u003c!-- vscode-markdown-toc-config\n\tnumbering=true\n\tautoSave=true\n\t/vscode-markdown-toc-config --\u003e\n\u003c!-- /vscode-markdown-toc --\u003e\n##  1. \u003ca name='Introductionofthissourcecoderepository'\u003e\u003c/a\u003eIntroduction of this repository\nThis repoistory of **Plink** is a monorepo, it contains multiple packages with comprehensive functions for developing web application based on Typescript and Node.js.\n| package | directory | function\n| - | - | -\n| @wfh/plink | main/wfh | Plink's main package, basis of Plink, extensible command line core, monorepo/multrepo management, configuration core, graph algorithm utility...\n| @wfh/plink-cli | main/install-cli | Plink's command line entry package for globally installation\n|              @wfh/cra-scripts  | src\\internal\\cra-scripts          | A monorepo supported **create-react-app** monkey-patch tool\n|           @wfh/ng-app-builder  | src\\internal\\ng-app-builder       | A monorepo supported **Angular cli** extension tool (Angular 8+)\n|           @wfh/webpack-common  | src\\internal\\webpack-common       | A common dependency of Plink's React and Angular project builder tool\n|         @wfh/assets-processer  | src\\runtime\\assets-processer      | Comprehensive Express.js based middleware for HTTP static resource, HTTP proxy server...\n|              @wfh/express-app  | src\\runtime\\express-app           | Express.js engine of Plink's extensible HTTP server\n|              @wfh/http-server  | src\\runtime\\http-server           | Plink's extensible HTTP server\n|          @wfh/json-schema-gen  | src\\tools\\json-schema-gen         | Cmd line tool of JSON schema generation, Typescript file AST analysis\n|       @wfh/log4js-pm2intercom  | src\\tools\\log4js-intercom         | A fixing package for PM2 multi-process logger management\n|                 @wfh/prebuild  | src\\tools\\prebuild                | Node.js server hot deployment tool for Plink node server based application\n|                @wfh/tool-misc  | src\\tools\\tool-misc               | Typescript source code generation tool for Plink setting file, React component, RTK slice definition\n| @wfh/redux-toolkit-observable  | main\\redux-toolkit-observable     | A better Typescript encapsulated library of Redux-toolkit (RTK) + Redux-observable combination \n|      @wfh/thread-promise-pool  | main\\thread-promise-pool          | Utility of Node.js thread / process pool\n|                @wfh/doc-entry  | doc-app\\doc-entry                 | Plink documentation site\n|            @wfh/doc-ui-common  | doc-app\\doc-ui-common             | Reusable UI goods, including Material components, reactive canvas\n|@wfh/material-components-react  | doc-app/material-components-react | Google's material-components-web encapsulated in React and RxJS\n\n##  2. \u003ca name='Purpose'\u003e\u003c/a\u003ePurpose\nTo embrace **Monorepo** and **Multiple-repo** at same time.\n\nWeb (or Node.js) frameworks or libraries like Angular, React, Vue, NestJS, they all come up with command line tools which help developer to initialize web projects, most of them are like scaffolding tool. Most of the tools are limited at or totally not supporting monorepo/library authoring. Which brings a lot room for enterprise developer to improve for sharing and maintaining resuable modules or functions cross multiple projects.\n\nWe want to offer similar experience of developing Web appliactions like authoring Chrome extension for a Chrome browser, composing extension for Visual studio code. Easy to extend under certain standards.\n\nWe want our appliactions be able to share fundations of UI, state management, server side functions and tools while different application goes separate CI/CD process like microservice.\n\n##  3. \u003ca name='Acommandlinetool'\u003e\u003c/a\u003eA command line tool\n- to manipulate monorepo style projects and also connect multiple repos.\n\n- to resue and share packages/components/tools between multiple projects or repos.\n\n  \u003ch4\u003eExtensible sub commands\u003c/h4\u003e\n  \u003cdiv class=\"round-corner\"\u003e\n    \u003cimg src=\"doc-app/doc-entry/docs/zh/architecture/plink-cli-screenshot-01-min.png\"\u003e\n  \u003c/div\u003e\n  \u003cdiv class=\"round-corner\"\u003e\n    \u003cimg src=\"doc-app/doc-entry/docs/zh/architecture/plink-cli-screenshot-02-min.png\"\u003e\n  \u003c/div\u003e\n  \u003ch4\u003eConfiguration visualization for each package\u003c/h4\u003e\n  \u003cdiv class=\"round-corner\"\u003e\n    \u003cimg src=\"doc-app/doc-entry/docs/zh/architecture/plink-cli-screenshot-07-min.png\"\u003e\n  \u003c/div\u003e\n  \u003ch4\u003eConfiguration visualization for each package\u003c/h4\u003e\n  \u003cdiv class=\"round-corner\"\u003e\n    \u003cimg src=\"doc-app/doc-entry/docs/zh/architecture/plink-cli-screenshot-04-min.png\"\u003e\n  \u003c/div\u003e\n  \u003cdiv class=\"round-corner\"\u003e\n    \u003cimg src=\"doc-app/doc-entry/docs/zh/architecture/plink-cli-screenshot-05-min.png\"\u003e\n  \u003c/div\u003e\n  \u003cdiv class=\"round-corner\"\u003e\n    \u003cimg src=\"doc-app/doc-entry/docs/zh/architecture/plink-cli-screenshot-06-min.png\"\u003e\n  \u003c/div\u003e\n\n###  3.1. \u003ca name='WhyMonorepos'\u003e\u003c/a\u003eWhy Monorepos ?\n[A perfect monorepo pitch in Nx](https://nx.dev/latest/node/core-concepts/why-monorepos)\n\nA monorepo is a single git repository that holds the source code for multiple applications and libraries, along with the tooling for them.\n\nWhat are the benefits of a monorepo?\n- **Shared code** - Keep your code DRY across your entire organization. Reuse validation code, UI components and types across the code base. Reuse code between the backend and the frontend.\n\n- **Atomic changes** - Change a server API and modify the clients that consume that API in the same commit. You can change a button component in a shared library and the applications that use that component in the same commit. This saves the pain of trying to coordinate commits across multiple repositories.\n\n- **Developer mobility** - Get a consistent way of building and testing applications written using different tools and technologies. Developers can confidently contribute to other teams’ applications and verify that their changes are safe.\n\n- **Single set of dependencies** - Use a single version of third party dependencies for all your apps. Less frequently used applications don’t get left behind with a 3 year old version of a framework library or an old version of webpack.\n###  3.2. \u003ca name='Plinkmonorepomultiple-repostyle'\u003e\u003c/a\u003ePlink monorepo multiple-repo style\n\u003e Node packages are first class citizen in Plink project. Plink enforce project source code structure in form of multiple packages.\n\n- You may have multiple web (Node.js) projects, some are based on Node.js Express.js framework, some are based on React and Redux, and some are based on Angular.\n\n- You may have a single source code directory contains reusable (partially) modules, some Redux code could be shared cross React projects and Angular project, some isomophic Node.js code may be reused on all web projects as backend server or build process enhancement.\n\n- Source code is organized in form of Node packages at first place, so that they can be shared cross repositaries. Projects in the same repo can directly reference relative source code. Other project can install them as node package to their build and deploy environment.\n\n- **You may link multiple projects that is inside or outside current repository, build them together, run them together, without**\n\n###  3.3. \u003ca name='Directorystructuremaylooklike:'\u003e\u003c/a\u003eDirectory structure may look like:\n- A simple Plink style repo is basically same as Lerna project structure\n```\n/- \u003c Repository root directory \u003e\n  |- package.json\n  |- node_modules\n  |- dist/\n  |   |- plink-state.json\n  |\n  |- packages/\n      |- app-entry-1\n      |     |- src/\n      |     |- package.json\n      |\n      |- app-entry-2\n      |     |- src/\n      |     |- package.json\n      |\n      |- commons/\n            |- animation/\n            |    |- package.json\n            |- isomophic-utils/\n            |    |- package.json\n            |- other-nested-package...\n                |- package.json\n```\n\n- A Plink style monorepo with multiple dependency installation space\n```\n/- \u003c Repository root directory \u003e\n  |- react-space (created with create-react-app)\n  |     |- package.json\n  |     |- node_modules/\n  |\n  |- angular-space/ (created with @angular/cli )\n  |     |- package.json\n  |     |- node_modules/\n  |\n  |- node-space/\n  |     |- package.json\n  |     |- node_modules/\n  |\n  |- package.json\n  |- node_modules/\n  |     |- @wfh/plink\n  |     |- ... (symlinks to package directories)\n  |\n  |- dist/\n  |   |- plink-state.json\n  +- packages/\n        |- redux-slice-A/\n        |     |- src/\n        |     |- package.json\n        |\n        |- redux-slice-B/\n        |     |- src/\n        |     |- package.json\n        |\n        |- ng-components/\n        |     |- src/\n        |     |- package.json\n        |\n        |- react-widgets/\n        |     |- src/\n        |     |- package.json\n        |\n        |- server-feature-A\n        |     |- src/\n        |     |- package.json\n        |\n        |- server-feature-B\n        |     |- src/\n        |     |- package.json\n        |\n        |- app-entry-1\n        |     |- src/\n        |     |- package.json\n        |\n        |- app-entry-2\n        |     |- src/\n        |     |- package.json\n        |\n        |- commons/\n             |- animation/\n             |    |- package.json\n             |- isomophic-utils/\n             |    |- package.json\n             |- other-nested-package...\n                  |- package.json\n\n```\n####  3.3.1. \u003ca name='Dependencyinstallationspace'\u003e\u003c/a\u003eDependency installation space\n`react-space`, `angular-space`, `node-space` are quite like Yarn's workspace tree concept. Basically, these are the places where we install dependency, build client side application and run web server or tools.\n\n####  3.3.2. \u003ca name='ProjectandPackagesdirectory'\u003e\u003c/a\u003eProject and Packages directory\n`packages/` are where Plink scans for source code packages, we organize raw source code in form of packages, reference each other like a regular package module:\n```js\nimport something from '@foobar/redux-slice-A';\n```\n\n**Project** is a repository which contains `packages/` like directory.\n\n###  3.4. \u003ca name='Howitworks'\u003e\u003c/a\u003eHow it works\n\u003e Relationship, symlinks, NODE_PATH, Webpack module.resolve...\n(WIP)\n\n##  4. \u003ca name='Features'\u003e\u003c/a\u003eFeatures\n - Support monorepo project structure.\n - Hoist and merge dependencies of nested packages.\n - Work with tools like `create-react-app` and `@angular/cli`\n - Share reusable component, features, functions between different projects.\n - Share file structure, configurations between different projects.\n - Easy to upgrade.\n - Opinionated cross framework solutions, web components, libraries, tools.\n - Automation code generator for configuration, UI components, state management slice...\n - Source code dependency analysis tool\n\n##  5. \u003ca name='Environmentvariablesandworkingdirectories'\u003e\u003c/a\u003eEnvironment variables and working directories\n- **dist**\n\n  Plink needs a directory to save cached state file, generated files, report and any other temporary data.\n  Such a directory should not be checked in Git repo, by default this directory is named \"dist\", and Plink will assign an\n  environment vararible `PLINK_DATA_DIR` with this default directory path `dist`, all pluggable command line extension modules and\n  forked process (or thread worker) can access this variable `process.env.PLINK_DATA_DIR`.\n####  5.1. \u003ca name='Changedisttootherdirectory'\u003e\u003c/a\u003eChange `dist` to other directory\n\n  Simple assign environment variable PLINK_DATA_DIR to any relative path name before start plink command.\n  \u003e PLINK_DATA_DIR must be a relative path, not absolute path.\n\n##  6. \u003ca name='UnlikeYarnworkspaces'\u003e\u003c/a\u003eUnlike Yarn workspaces\n(WIP)\n\n##  7. \u003ca name='DependencyHoist'\u003e\u003c/a\u003eDependency Hoist\n\nThe idea is a bit like Java Maven's Dependency Mechanism (Transitive dependencies)\nhttps://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html\n\nLike Maven, we treat dependencies of linked packages as \"Transitive dependencies\", linked packages do not need to\ninstall their dependencies in their own `node_modules`, instead we install all dependencies of all related linked\npackages in current space's node_modules directory as being shared.\n\nUnlike Maven, to resolve the conflict of transitive dependency, we only use \"the highest version\" of conflict dependencies, not the first version. https://dzone.com/articles/solving-dependency-conflicts-in-maven\n\n## Using Plink command line\nThrough npm run scripts:\nchange project's package.json to add:\n```json\n{\n  scripts: {\n    \"plink\": \"plink\"\n  },\n  ...\n}\n```\n\n```bash\nnpm run plink -- \u003csub-command\u003e [options...] [arguments...]\n```\nOr install globally by `npm i -g @wfh/plink-cli`\n\nPlink provides help command in form of:\n```bash\nplink -h\nplink \u003csub-command\u003e -h\n# or\nplink help \u003csub-command\u003e\n```\n\nEasy source code generating (@wfh/tool-misc must installed to worktree space),\n```bash\n# Plink's more pluggable sub-commands are available under each worktree space directory, as long as they are installed.\ncd cra-space\n# Generate \"internal\" Redux slice for a component\nplink cra-gen-slice --internal ../packages/aw-main/containers landing\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fliujingbreak%2Fplink","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fliujingbreak%2Fplink","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fliujingbreak%2Fplink/lists"}