PageSourceSearch

https://socket.io/assets/js/7d637a76.f6b7dc95.js

js socket.io collected 2026-09-24 07:26:17 UTC 10,540 bytes, 1 lines download raw bytes

1"use strict";(self.webpackChunksample_website=self.webpackChunksample_website||[]).push([[6530],{3905:(e,t,o)=>{o.d(t,{Zo:()=>c,kt:()=>k});var n=o(7294);function r(e,t,o){return t in e?Object.defineProperty(e,t,{value:o,enumerable:!0,configurable:!0,writable:!0}):e[t]=o,e}function a(e,t){var o=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),o.push.apply(o,n)}return o}function i(e){for(var t=1;t<arguments.length;t++){var o=null!=arguments[t]?arguments[t]:{};t%2?a(Object(o),!0).forEach((function(t){r(e,t,o[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(o)):a(Object(o)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(o,t))}))}return e}function s(e,t){if(null==e)return{};var o,n,r=function(e,t){if(null==e)return{};var o,n,r={},a=Object.keys(e);for(n=0;n<a.length;n++)o=a[n],t.indexOf(o)>=0||(r[o]=e[o]);return r}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n<a.length;n++)o=a[n],t.indexOf(o)>=0||Object.prototype.propertyIsEnumerable.call(e,o)&&(r[o]=e[o])}return r}var p=n.createContext({}),l=function(e){var t=n.useContext(p),o=t;return e&&(o="function"==typeof e?e(t):i(i({},t),e)),o},c=function(e){var t=l(e.components);return n.createElement(p.Provider,{value:t},e.children)},u="mdxType",h={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var o=e.components,r=e.mdxType,a=e.originalType,p=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),u=l(o),m=r,k=u["".concat(p,".").concat(m)]||u[m]||h[m]||a;return o?n.createElement(k,i(i({ref:t},c),{},{components:o})):n.createElement(k,i({ref:t},c))}));function k(e,t){var o=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var a=o.length,i=new Array(a);i[0]=m;var s={};for(var p in t)hasOwnProperty.call(t,p)&&(s[p]=t[p]);s.originalType=e,s[u]="string"==typeof e?e:r,i[1]=s;for(var l=2;l<a;l++)i[l]=o[l];return n.createElement.apply(null,i)}return n.createElement.apply(null,o)}m.displayName="MDXCreateElement"},1975:(e,t,o)=>{o.r(t),o.d(t,{assets:()=>p,contentTitle:()=>i,default:()=>h,frontMatter:()=>a,metadata:()=>s,toc:()=>l});var n=o(3117),r=(o(7294),o(3905));const a={title:"Socket.IO monorepo",slug:"/monorepo/",authors:["darrachequesne"]},i=void 0,s={permalink:"/blog/monorepo/",editUrl:"https://github.com/socketio/socket.io-website/edit/main/blog/2024-07-12-monorepo.md",source:"@site/blog/2024-07-12-monorepo.md",title:"Socket.IO monorepo",description:"Hello everyone!",date:"2024-07-12T00:00:00.000Z",formattedDate:"July 12, 2024",tags:[],readingTime:2.42,hasTruncateMarker:!0,authors:[{name:"Damien Arrachequesne",title:"Maintainer of Socket.IO",url:"https://github.com/darrachequesne",imageURL:"https://github.com/darrachequesne.png",key:"darrachequesne"}],frontMatter:{title:"Socket.IO monorepo",slug:"/monorepo/",authors:["darrachequesne"]},prevItem:{title:"npm package provenance",permalink:"/blog/npm-package-provenance/"},nextItem:{title:"Three new adapters",permalink:"/blog/three-new-adapters/"}},p={authorsImageUrls:[void 0]},l=[{value:"Modular architecture",id:"modular-architecture",level:2},{value:"Workspaces",id:"workspaces",level:2},{value:"Git history",id:"git-history",level:2},{value:"GitHub issues",id:"github-issues",level:2}],c={toc:l},u="wrapper";function h(e){let{components:t,...a}=e;return(0,r.kt)(u,(0,n.Z)({},c,a,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("p",null,"Hello everyone!"),(0,r.kt)("p",null,"We are happy to announce that the Socket.IO codebase has been merged into a monorepo."),(0,r.kt)("admonition",{type:"note"},(0,r.kt)("p",{parentName:"admonition"},"A monorepo is a single repository containing multiple distinct projects, with well-defined relationships."),(0,r.kt)("p",{parentName:"admonition"},"More info ",(0,r.kt)("a",{parentName:"p",href:"https://monorepo.tools"},"here"))),(0,r.kt)("h2",{id:"modular-architecture"},"Modular architecture"),(0,r.kt)("p",null,"As part of the work towards ",(0,r.kt)("a",{parentName:"p",href:"/blog/introducing-socket-io-1-0/"},"v1.0")," ten years ago (!), the Socket.IO codebase was split into several packages, each with its own responsibility:"),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"Diagram of the package inter-dependencies",src:o(6690).Z,width:"1074",height:"796"})),(0,r.kt)("p",null,"At the time, tools like ",(0,r.kt)("a",{parentName:"p",href:"https://lerna.js.org/"},(0,r.kt)("inlineCode",{parentName:"a"},"lerna"))," or ",(0,r.kt)("a",{parentName:"p",href:"https://pnpm.io/workspaces"},"pnpm workspaces")," that make it easier to develop and publish multiple JavaScript packages from the same repository did not exist yet, so the codebase was split into multiple GitHub repositories:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://github.com/socketio/socket.io"},"https://github.com/socketio/socket.io")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://github.com/socketio/socket.io-client"},"https://github.com/socketio/socket.io-client")),(0,r.kt)("li",{parentName:"ul"},(0,r.kt)("a",{parentName:"li",href:"https://github.com/socketio/socket.io-parser"},"https://github.com/socketio/socket.io-parser")),(0,r.kt)("li",{parentName:"ul"},"...")),(0,r.kt)("p",null,"However, this structure has several downsides:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"it's harder for newcomers to dig into the codebase and understand what's going on under the hood"),(0,r.kt)("li",{parentName:"ul"},"a change that affects multiple repositories is more difficult to test"),(0,r.kt)("li",{parentName:"ul"},"mundane tasks like configuring CI or updating development dependencies must be replicated across all repositories")),(0,r.kt)("p",null,"That's why we have made the decision to merge all repositories into ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/socketio/socket.io"},"a single one"),". The source codes for the different packages are now located in the ",(0,r.kt)("inlineCode",{parentName:"p"},"packages/")," directory:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre"},"packages/\n\u251c\u2500\u2500 engine.io\n\u251c\u2500\u2500 engine.io-client\n\u251c\u2500\u2500 engine.io-parser\n\u251c\u2500\u2500 socket.io\n\u251c\u2500\u2500 socket.io-ad
1apter\n\u251c\u2500\u2500 socket.io-client\n\u2514\u2500\u2500 socket.io-parser\n")),(0,r.kt)("h2",{id:"workspaces"},"Workspaces"),(0,r.kt)("p",null,"To manage the packages, we use ",(0,r.kt)("a",{parentName:"p",href:"https://docs.npmjs.com/cli/v10/using-npm/workspaces"},"npm workspaces")," which were introduced in npm v7 (bundled with Node.js v15). The ",(0,r.kt)("inlineCode",{parentName:"p"},"package.json")," file at the root of the repository lists all packages and their development dependencies:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-json",metastring:'title="package.json"',title:'"package.json"'},'{\n  "private": true,\n  "workspaces": [\n    "packages/engine.io-parser",\n    "packages/engine.io",\n    "packages/engine.io-client",\n    "packages/socket.io-adapter",\n    "packages/socket.io-parser",\n    "packages/socket.io-client",\n    "packages/socket.io"\n  ],\n  "devDependencies": {\n    // [...]\n  }\n}\n')),(0,r.kt)("p",null,"After cloning the repository, running ",(0,r.kt)("inlineCode",{parentName:"p"},"npm install")," will fetch all necessary dependencies and create the links between the packages:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-bash"},"$ npm ls\nsocket.io@ /git/socket.io\n\u2514\u2500\u252c [email protected] -> ./packages/socket.io\n  \u251c\u2500\u2500 [email protected]\n  \u251c\u2500\u2500 [email protected]\n  \u251c\u2500\u2500 [email protected]\n  \u251c\u2500\u2500 [email protected]\n# highlight-next-line\n  \u251c\u2500\u2500 [email protected] -> ./packages/engine.io\n# highlight-next-line\n  \u251c\u2500\u252c [email protected] -> ./packages/socket.io-adapter\n  \u2502 \u251c\u2500\u2500 [email protected] deduped\n  \u2502 \u2514\u2500\u2500 [email protected] overridden\n# highlight-next-line\n  \u2514\u2500\u252c [email protected] -> ./packages/socket.io-parser\n    \u251c\u2500\u2500 @socket.io/[email protected] -> ./packages/socket.io-component-emitter\n    \u2514\u2500\u2500 [email protected] deduped\n")),(0,r.kt)("p",null,"And finally, running ",(0,r.kt)("inlineCode",{parentName:"p"},"npm test --workspaces")," (or ",(0,r.kt)("inlineCode",{parentName:"p"},"npm test -ws"),") will run the tests on all workspaces, ensuring that any change is properly tested over the whole codebase."),(0,r.kt)("admonition",{type:"tip"},(0,r.kt)("p",{parentName:"admonition"},"Our ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/socketio/socket.io/blob/main/CONTRIBUTING.md"},"contributing guide")," has been updated accordingly.")),(0,r.kt)("h2",{id:"git-history"},"Git history"),(0,r.kt)("p",null,"Obviously, losing 10 years of git history from the other repositories was not an option. The repositories have thus been merged with the ",(0,r.kt)("inlineCode",{parentName:"p"},"--allow-unrelated-histories")," option, in order to include their history in the monorepo:"),(0,r.kt)("p",null,(0,r.kt)("img",{alt:"Schema of the preserved git history",src:o(8242).Z,width:"1468",height:"739"})),(0,r.kt)("p",null,"Reference: ",(0,r.kt)("a",{parentName:"p",href:"https://git-scm.com/docs/git-merge#Documentation/git-merge.txt---allow-unrelated-histories"},"https://git-scm.com/docs/git-merge#Documentation/git-merge.txt---allow-unrelated-histories")),(0,r.kt)("h2",{id:"github-issues"},"GitHub issues"),(0,r.kt)("p",null,"Similarly, it was not conceivable to lose the list of open GitHub issues across all repositories, since it is our most valuable source of user feedback, so they have been moved to the main repository: ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/socketio/socket.io/issues"},"https://github.com/socketio/socket.io/issues")),(0,r.kt)("p",null,"Hopefully, this change should make it easier for anyone to contribute to the project in the future."),(0,r.kt)("p",null,"That's all folks, thanks for reading!"))}h.isMDXComponent=!0},8242:(e,t,o)=>{o.d(t,{Z:()=>n});const n=o.p+"assets/images/git-history-df971b02f81f1370bf2410f76b1d16d9.png"},6690:(e,t,o)=>{o.d(t,{Z:()=>n});const n=o.p+"assets/images/packages-fc6d12d93e4f983adae7e09938deaf20.png"}}]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.