{"id":19529910,"url":"https://github.com/loopmode/crosslink","last_synced_at":"2025-04-26T12:30:34.101Z","repository":{"id":44176270,"uuid":"136461485","full_name":"loopmode/crosslink","owner":"loopmode","description":"Creates symlinks across yarn workspaces","archived":false,"fork":false,"pushed_at":"2022-12-03T18:45:29.000Z","size":314,"stargazers_count":3,"open_issues_count":7,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-10-14T04:18:09.545Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/loopmode.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-06-07T10:31:08.000Z","updated_at":"2020-07-29T13:57:38.000Z","dependencies_parsed_at":"2023-01-23T14:30:19.378Z","dependency_job_id":null,"html_url":"https://github.com/loopmode/crosslink","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/loopmode%2Fcrosslink","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/loopmode%2Fcrosslink/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/loopmode%2Fcrosslink/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/loopmode%2Fcrosslink/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/loopmode","download_url":"https://codeload.github.com/loopmode/crosslink/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":224034657,"owners_count":17244828,"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":[],"created_at":"2024-11-11T01:28:05.424Z","updated_at":"2024-11-11T01:28:07.108Z","avatar_url":"https://github.com/loopmode.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# crosslink\n\nA utility for creating symlinks to node packages.\nUseful for combining multiple yarn workspaces.\n\nSupports scoped package names.\n\n## Installation\n\nInstall it as a global tool or as a dependency in your project.\n\n```sh\n# global install\nnpm install -g @loopmode/crosslink\n\n# just in this project\nyarn add @loopmode/crosslink --dev\n```\n\nOr don't install at all and use `npx` instead (available since npm@5.2.0).\nUnfortunately, when using `npx`, you must specify the full package name including scope: `npx @loopmode/crosslink`.\n\n# Usage\n\n## Default command\n\nThe default command will run with default settings, look for definitions and try to create symlinks.\nIt checks package.json and .crosslink files for `\"crosslink\": []` definitions.\n\n```sh\ncrosslink\n\n# same recursively for all nested directories\ncrosslink -r\n\n\n# dry run, report but don't create the symlinks\ncrosslink -d\n\n\n# load definitions from a file other than .crosslink or package.json\ncrosslink . -f symlinks.json\n\n\n# recurse all workspace packages, use package.json files and the \"symlinks\" property inside them\ncrosslink workspace --f package.json -p symlinks -r\n```\n\nSee `crosslink --help` for an overview:\n\n```sh\n$ crosslink --help\n\n  Usage: crosslink [target]\n\n  Options:\n\n    -V, --version                output the version number\n    -f, --filename [filename]    Name of definition files to use. (default: .crosslink)\n    -p, --propname [propname]    Name of property to use in JSON definitions. (default: crosslink)\n    -r, --recursive [recursive]  Scan for crosslink definitions recursively. (default: false)\n    -d, --dry [dry]              Perform a dry run without actually creating any symlinks. (default: false)\n    -h, --help                   output usage information\n```\n\n## link command\n\nThe link command takes one definition and executes it in the current directory. Make sure to wrap your definition in quotes.\n\n```\n link \"./a/* -\u003e ../b\"\n```\n\nSee `crosslink link --help` for an overview:\n\n```sh\n$ crosslink link --help\n\n  Usage: link [options] \u003cdefinition\u003e\n\n  Options:\n\n    -d, --dry [dry]  perform a dry run and report, do not create symlinks (default: false)\n    -h, --help       output usage information\n\n  Arguments:\n\n     definition                  A definition in the format source-\u003etarget\n```\n\nCreate a `.crosslink` file or add a `\"crosslink\"` array in your package.json, then run `npx @loopmode/crosslink` in the directory.\n\n## 1) definitions file\n\nBy default, you can provide a file named `.crosslink` and define instructions in it, or a field `\"crosslink\"` in your package.json file.\nYou can specify a different filename using the `--filename` parameter.\n\nIn any case: A definitions file can be either a textfile with one instruction per line, or a json file with an `\"crosslink\"` array of instructions.\n\nRunning `crosslink` against such a file is basically the same as calling a bunch of `crosslink link \u003cinstruction\u003e` commands manually.\n\n## 2) instructions\n\nAn instruction is a string in the format `sourceGlob-\u003etargetGlob`: it consists of two globs combined with a dash and an arrow.\nAny glob pattern supported by [glob](http://npmjs.com/package/glob) should work.\n\nNote: This is for symlinking node packages, therefore the left-hand side glob will only match target directories that contain a `package.json` file.\n\n- The right-hand side will match any target directories.\n- All left-hand matches will be symlinked to all right-hand matches.\n- Missing folder structures will be created, e.g. `a/* -\u003e b/sub/node_modules` works even when there is no `b` folder yet\n\nConsider this folder structure:\n\n```sh\n$ find .\n.\n./a\n./a/bar\n./a/bar/package.json\n./a/baz\n./a/baz/baz.txt\n./a/foo\n./a/foo/package.json\n./b\n```\n\nNow we run the `link` command with a single instruction:\n\n```sh\n$ crosslink link \"./a/*-\u003e./b\"\n[crosslink] created: D:/Projects/npm/crosslink/examples/simple/a/bar → D:/Projects/npm/crosslink/examples/simple/b/@a/bar\n[crosslink] created: D:/Projects/npm/crosslink/examples/simple/a/foo → D:/Projects/npm/crosslink/examples/simple/b/@a/foo\n```\n\nThe result is that we have symlinks to `a/foo` and `a/bar`, but not to `a/baz` because it had no `package.json` file:\n\n## Definition file: text format\n\nIf the definitions file is a textfile, place one instruction per line:\n\n```\ncommon/packages/* -\u003e client/node_modules\ncommon/packages/* -\u003e server/node_modules\n```\n\n## Definition file: JSON format\n\nIf the definitions file is a json file, place a `\"crosslink\"` array of instructions in it:\n\n```\n{\n    \"crosslink\": [\n        \"common/packages/* -\u003e client/node_modules\",\n        \"common/packages/* -\u003e server/node_modules\"\n    ]\n}\n```\n\nIf you prefer to use a different property name than \"crosslink\", you can use the `-p` or `--propname` flag.\n\n### Using package.json\n\nYou might just as well use your existing `package.json` and define a `\"crosslink\"` array inside of it.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Floopmode%2Fcrosslink","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Floopmode%2Fcrosslink","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Floopmode%2Fcrosslink/lists"}