{"id":51514578,"url":"https://github.com/cargo-fob/factorize","last_synced_at":"2026-07-08T10:00:48.442Z","repository":{"id":369257165,"uuid":"1197213992","full_name":"cargo-fob/factorize","owner":"cargo-fob","description":"JS bundler with a Rust core and napi-rs bindings","archived":false,"fork":false,"pushed_at":"2026-07-04T11:24:18.000Z","size":115,"stargazers_count":0,"open_issues_count":0,"forks_count":1,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-07-04T12:08:44.027Z","etag":null,"topics":["bundler","napi-rs","rolldown","rust"],"latest_commit_sha":null,"homepage":"","language":"Rust","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/cargo-fob.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-03-31T12:14:25.000Z","updated_at":"2026-07-04T11:24:22.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/cargo-fob/factorize","commit_stats":null,"previous_names":["cargo-fob/factorize"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/cargo-fob/factorize","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cargo-fob%2Ffactorize","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cargo-fob%2Ffactorize/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cargo-fob%2Ffactorize/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cargo-fob%2Ffactorize/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cargo-fob","download_url":"https://codeload.github.com/cargo-fob/factorize/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cargo-fob%2Ffactorize/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35260671,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-08T02:00:06.796Z","response_time":61,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["bundler","napi-rs","rolldown","rust"],"created_at":"2026-07-08T10:00:45.192Z","updated_at":"2026-07-08T10:00:48.376Z","avatar_url":"https://github.com/cargo-fob.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# factorize\n\nrolldown식 구조의 학습용 번들러 — **thin JS/TS ↔ napi-rs ↔ Rust core**.\n파이프라인(scan → link → generate)을 Rust core가 소유하고, JS는 옵션과 plugin 콜백만 넘긴다.\n\n## 아키텍처\n\n```mermaid\nflowchart TD\n    subgraph JS[\"packages/factorize (TS)\"]\n        A[\"factorize() / watch()\u003cbr/\u003ethin facade — 옵션·plugin만 전달\"]\n    end\n\n    subgraph Binding[\"crates/node_binding (napi-rs)\"]\n        B[\"BindingBundler\u003cbr/\u003ebuild / onModuleParsed / onTransform\"]\n        C[\"BindingWatcher\u003cbr/\u003eRust-owned watch 루프\"]\n    end\n\n    subgraph Core[\"crates/factorize_core (Rust)\"]\n        D[\"Bundler: scan → link → generate\"]\n        E[\"Plugin trait\"]\n    end\n\n    W[\"crates/factorize_watcher\u003cbr/\u003eFsWatcher (파일 감시)\"]\n\n    A -- napi --\u003e B\n    A -- napi --\u003e C\n    B --\u003e D\n    C --\u003e W\n    D -.-\u003e|ThreadsafeFunction| E\n    E -.-\u003e|JS 콜백 호출| A\n```\n\n- plugin 훅(`moduleParsed`, `transform`)은 **Rust core가 napi `ThreadsafeFunction`으로 JS를 다시 호출**한다.\n- watch 루프는 **Rust가 소유**하고, JS는 이벤트만 구독한다.\n\n## 파이프라인\n\n```mermaid\nflowchart LR\n    entry([\"entry.js\"]) --\u003e scan\n\n    subgraph scan[\"scan (worklist BFS)\"]\n        s1[\"파일 읽기\"] --\u003e s2[\"transform 훅\"]\n        s2 --\u003e s3[\"상대 import 파싱 + resolve\"]\n        s3 --\u003e s4[\"moduleParsed 훅\"]\n        s4 --\u003e|deps 큐에 push| s1\n    end\n\n    scan --\u003e|ModuleGraph| link\n    link[\"link\u003cbr/\u003e실행 순서 결정 (deps-first)\"] --\u003e generate\n    generate[\"generate\u003cbr/\u003e모듈 코드 이어붙이기\"] --\u003e out([\"Output.code\"])\n```\n\n| 단계 | 하는 일 |\n| --- | --- |\n| **scan** | entry에서 상대 import를 따라가며 module graph 구성 (worklist BFS) |\n| **link** | 실행 순서 결정 — deps가 먼저 오도록 정렬 |\n| **generate** | 모듈 코드를 순서대로 이어붙여 하나의 번들로 |\n\n## 실행\n\n### CLI\n\n```sh\ncargo run -p factorize_cli -- packages/factorize/fixture/entry.js\n```\n\n입력 (`fixture/entry.js` → `dep.js`, `meta/version.js` import):\n\n```js\n// entry.js\nimport { hello } from \"./dep.js\";\nimport { VERSION } from \"./meta/version.js\";\nconsole.log(hello(), VERSION);\n```\n\n실제 출력 — **의존성이 먼저(version → dep → entry) 배치**된 게 보인다:\n\n```js\n// === /.../fixture/meta/version.js ===\nexport const VERSION = \"0.1.0\";\n\n// === /.../fixture/dep.js ===\nexport function hello() {\n  return \"hello from factorize\";\n}\n\n// === /.../fixture/entry.js ===\nimport { hello } from \"./dep.js\";\nimport { VERSION } from \"./meta/version.js\";\n\nconsole.log(hello(), VERSION);\n```\n\n### JS API\n\n```sh\ncd packages/factorize\nnpm run build:binding   # Rust → .node 생성 (코드 바꿀 때마다)\nnpm start               # 빌드 데모 (plugin: moduleParsed + transform)\nnpm run watch           # watch 데모 (파일 변경 시 Rust가 rebuild)\n```\n\n```ts\nimport { factorize, watch } from \"./src/factorize\";\n\n// 빌드 + plugin\nconst build = factorize({ input: \"./entry.js\" }, [\n  {\n    moduleParsed: (id) =\u003e console.log(\"parsed:\", id),\n    transform: (code, id) =\u003e `/* ${id} */\\n${code}`,\n  },\n]);\nconst out = await build.build();\n\n// watch — 루프는 Rust가 소유, JS는 이벤트만 구독\nconst w = watch({ input: \"./entry.js\" });\nw.on(\"bundle_end\", (e) =\u003e console.log(`${e.modules.length} modules`));\nw.on(\"change\", (e) =\u003e console.log(\"changed:\", e.path));\n```\n\n## 스코프\n\n번들러 핵심을 최소로 구현해 **rolldown의 JS↔napi↔Rust 경계 패턴**을 익히는 게 목표.\n실제 파서(oxc)·tree-shaking·code-splitting은 단순화돼 있다 — 자세한 전환 기록은 `ROLLDOWN_MIGRATION.md`.\n\u003c/content\u003e\n\u003c/invoke\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcargo-fob%2Ffactorize","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcargo-fob%2Ffactorize","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcargo-fob%2Ffactorize/lists"}