{"id":3566,"date":"2022-01-10T15:47:14","date_gmt":"2022-01-10T15:47:14","guid":{"rendered":"http:\/\/the-codest.localhost\/blog\/ruby-on-rails-modularization-with-packwerk-episode-ii\/"},"modified":"2026-04-28T14:05:25","modified_gmt":"2026-04-28T14:05:25","slug":"ruby-on-rails-moduliavimas-su-packwerk-ii-epizodas","status":"publish","type":"post","link":"https:\/\/thecodest.co\/lt\/blog\/ruby-on-rails-modularization-with-packwerk-episode-ii\/","title":{"rendered":"Ruby on Rails moduliavimas su \"Packwerk Episode II"},"content":{"rendered":"<h2 class=\"wp-block-heading\">Parai\u0161ka kaip paketas<\/h2>\n\n\n\n<p>M\u016bs\u0173 taikomosios programos moduliavimo b\u016bdas - vis\u0105 program\u0105 paversti paketu.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Sukurti strukt\u016br\u0105<\/h3>\n\n\n\n<p>Pirmiausia turime sukurti <code>app\/packages<\/code> aplank\u0105, \u012f kur\u012f d\u0117sime visus savo paketus. Nor\u0117dami atskirti savo paketus, turime atskirti kiekvien\u0105 <strong>MVC koncepcija<\/strong> viename aplanke. Pa\u0117mus <strong>CodeTriage <a href=\"https:\/\/thecodest.co\/lt\/dictionary\/why-do-projects-fail\/\">projektas<\/a><\/strong> kaip pavyzd\u012f galime pateikti tok\u012f paveiksl\u0117l\u012f.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"\/app\/uploads\/2024\/05\/2.png\" alt=\"paketo strukt\u016bra \" title=\"paketo strukt\u016bros pavyzdys\"\/><\/figure>\n\n\n\n<p>Jei bandysime paleisti server\u012f, jis neras konstant\u0173. \u0160tai kod\u0117l turime prid\u0117ti konfig\u016bracijos eilut\u0119 prie m\u016bs\u0173 <code>application.rb<\/code><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"ruby\" class=\"language-ruby\">config.paths.add 'app\/packages', glob: '*\/{*,*\/concerns}', eager_load:true<\/code><\/pre>\n\n\n\n<p>Dabar programa veikia, bet ji negali rasti rodini\u0173, tod\u0117l turime prid\u0117ti dar vien\u0105 konfig\u016bracijos eilut\u0119 \u012f m\u016bs\u0173 <code>application_controller.rb<\/code><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"ruby\" class=\"language-ruby\">append_view_path(Dir.glob(<a href=\"https:\/\/thecodest.co\/lt\/blog\/ways-to-increase-your-rails-performance\/\">B\u0117giai<\/a>.root.join('app\/packages\/*\/views')))<\/code><\/pre>\n\n\n\n<p><\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Sukurti paketus<\/h3>\n\n\n\n<p>M\u016bs\u0173 strukt\u016bra paruo\u0161ta, tod\u0117l dabar galime prad\u0117ti kurti paketus. Tam mums tereikia prid\u0117ti<code>package.yml<\/code> \u012f kiekvien\u0105 aplank\u0105 su tokia konfig\u016bracija:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"ruby\" class=\"language-ruby\">enforce_privacy: false\nenforce_dependencies: true<\/code><\/pre>\n\n\n\n<p><\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"\/app\/uploads\/2024\/05\/1.png\" alt=\"package.yml\" title=\"package.yml pavyzdys\"\/><\/figure>\n\n\n\n<p><code>enforce_privacy<\/code>pateikia . <a href=\"https:\/\/thecodest.co\/lt\/blog\/why-us-companies-are-opting-for-polish-developers\/\">mus<\/a> galimyb\u0117 izoliuoti visas paketo konstantas ir dirbti su vie\u0161\u0105ja <a href=\"https:\/\/thecodest.co\/lt\/blog\/compare-staff-augmentation-firms-that-excel-in-api-team-staffing-for-financial-technology-projects\/\">API<\/a>. Nor\u0117dami atskleisti vie\u0161\u0105sias konstantas, turime prid\u0117ti konstantas, pvz.&nbsp;<code>packages\/users\/app\/public.<\/code>Kol kas \u0161i\u0105 konfig\u016bracij\u0105 nustatysime \u012f <em> klaidinga<\/em>.<\/p>\n\n\n\n<p><code>enforce_dependencies<\/code> u\u017etikrins paketo priklausomyb\u0119 ir patikrins visas konstant\u0173 nuorodas. Jei priklausomyb\u0117 n\u0117ra ai\u0161kiai apibr\u0117\u017eta, tai bus ribos pa\u017eeidimas.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Paket\u0173 sistemos patvirtinimas<\/h3>\n\n\n\n<p><strong>Packwerk<\/strong> nustat\u0117 kriterij\u0173, kurio turime laikytis, kad tur\u0117tume galiojan\u010di\u0105 paket\u0173 sistem\u0105. Galime prad\u0117ti vykdyti <code>Packwerk patvirtinti<\/code> m\u016bs\u0173 konsol\u0117je.<\/p>\n\n\n\n<p>&nbsp;Patikrinsime aplank\u0173 strukt\u016br\u0105, <strong>paketo konfig\u016bracija<\/strong>, ir automatinis kelio talpyklos \u012fk\u0117limas.<\/p>\n\n\n\n<p>\u0160iuo metu m\u016bs\u0173 programa negalioja, tod\u0117l turime i\u0161taisyti apkrovos kelius<strong><code>packwerk.yml<\/code>.<\/strong> Tam tereikia prid\u0117ti tr\u016bkstamus kelius.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"ruby\" class=\"language-ruby\"># packwerk.yml\n\nload_paths:\n.\n.\n.\n\n# Vartotojai\n- app\/packages\/users\/controllers\n- app\/packages\/users\/models\n- app\/packages\/users\/package.yml\n- app\/packages\/users\/views<\/code><\/pre>\n\n\n\n<p>\u0160iuo metu esame pasiruo\u0161\u0119 patikrinti rib\u0173 pa\u017eeidimus savo programoje. Nor\u0117dami patikrinti pa\u017eeidimus, galime paleisti<code>packwerk update-deprecations<\/code> , \u0161i komanda sukurs <code>deprecated_references.yml<\/code> kiekvieno paketo fail\u0105. Kiekviename faile rasime paketo pavadinim\u0105, pa\u017eeidimo tip\u0105 ir failo keli\u0105. Tur\u0117dami vis\u0105 \u0161i\u0105 informacij\u0105 \u017einome, kur yra pa\u017eeidimas, ir galime priimti sprendim\u0105, kaip j\u012f pa\u0161alinti.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"\/app\/uploads\/2024\/05\/4.png\" alt=\"deprecated_references.yml\" title=\"deprecated_references.yml pavyzdys\"\/><\/figure>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"ruby\" class=\"language-ruby\"># deprecated_references.yml\n\n.\n.\n.\n\napp\/packages\/repos:\n  \"::Repo\":\n    : \"Repo:\": pa\u017eeidimai:\n    - priklausomyb\u0117\n    failai:\n    - app\/packages\/users\/models\/user.rb<\/code><\/pre>\n\n\n\n<p>Remdamiesi pavyzd\u017eiu, apra\u0161ysime kiekvien\u0105 sukurtos informacijos dal\u012f.<br>pagal <strong>Packwerk<\/strong>.<\/p>\n\n\n\n<p>- <code>app\/packages\/repos<\/code> &nbsp;- paketas, kuriame pastovus pa\u017eeidimas yra<br>rasta.<\/p>\n\n\n\n<p>- <code>::Repo<\/code> &nbsp;- kelias iki failo, kuriame yra pa\u017eeista konstanta.<\/p>\n\n\n\n<p>- <code>priklausomyb\u0117<\/code> &nbsp;- tam tikros r\u016b\u0161ies pa\u017eeidimas - priklausomyb\u0117s arba privatumo.<\/p>\n\n\n\n<p>- <code>app\/packages\/users\/models\/user.rb<\/code> &nbsp;- kelias iki failo, kuriame yra pa\u017eeista konstanta.<\/p>\n\n\n\n<p>Baigdami \u0161\u012f skyri\u0173, nepamir\u0161kite prid\u0117ti nauj\u0173 sugeneruot\u0173 fail\u0173 keli\u0173 prie <code>packwerk.ym<\/code>l ir dar kart\u0105 paleiskite patvirtinimus.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Priklausomyb\u0117s vizualizavimas<\/h3>\n\n\n\n<p>Naudodami vis\u0105 informacij\u0105, pateikt\u0105 package.yml ir <code>deprecated_references.yml<\/code>tada galime<br>vizualizuoti priklausomybi\u0173 grafik\u0105. Tam reikia prid\u0117ti dar vien\u0105 brangakmen\u012f, \u0161iuo atveju naudosime <a href=\"https:\/\/github.com\/mquan\/pocky\" rel=\"nofollow\">Pocky<\/a>.<\/p>\n\n\n\n<p>Veikiamas gr\u0117blys <code>Pocky:generuoti<\/code> sukursime fail\u0105, pavadint\u0105 <code>packwerk.png<\/code> kuriame galime vizualizuoti pirm\u0105j\u012f priklausomybi\u0173 grafik\u0105.<\/p>\n\n\n\n<p>Apibr\u0117\u017eus visus paketus, m\u016bs\u0173 diagrama atrodys taip.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"\/app\/uploads\/2024\/05\/5.png\" alt=\"grafas be priimt\u0173 priklausomybi\u0173\" title=\"grafo be priimt\u0173 priklausomybi\u0173 pavyzdys\"\/><\/figure>\n\n\n\n<p>priklausomyb\u0117s jau egzistuoja, bet tai nerei\u0161kia, kad jos priimamos <strong>Packwerk<\/strong>. \u012e<br>priimti priklausomyb\u0119, turime prid\u0117ti priklausomybi\u0173 konfig\u016bracij\u0105 prie <code>package.yml<\/code><br>kiekvienoje pakuot\u0117je. Daugiausia d\u0117mesio skirsime <code>mail_builders<\/code> nes tai paketas be \u017eiedin\u0117s priklausomyb\u0117s. Verta pamin\u0117ti, kad <strong>Packwerk<\/strong> neleid\u017eia mums priimti \u017eiedini\u0173 priklausomybi\u0173.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"ruby\" class=\"language-ruby\"># app\/packages\/mail_builders\/package.yml\n\n````ruby\nenforce_privacy: false\nenforce_dependencies: true\ndependencies:\n- app\/packages\/docs\n- app\/packages\/issues\n- app\/packages\/repos<\/code><\/pre>\n\n\n\n<p>Prid\u0117jus \u0161i\u0105 konfig\u016bracij\u0105, <strong>Pocky<\/strong> priimtinas priklausomybes nuspalvins \u017ealiai.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"\/app\/uploads\/2024\/05\/6.png\" alt=\"grafas su priimtomis priklausomyb\u0117mis \" title=\"grafo be priimt\u0173 priklausomybi\u0173 pavyzdys\"\/><\/figure>\n\n\n\n<p>Galime i\u0161trinti <code>deprecated_references.yml<\/code> i\u0161 <code>app\/packages\/mail_builders<\/code> ir paleiskite<br><code>packwerk update-deprecations<\/code> dar kart\u0105. Failas nebus generuojamas i\u0161 naujo, nes visi<br>\u0161iame pakete i\u0161taisyti pa\u017eeidimai. Svarbu pamin\u0117ti, kad net jei mes ne Grafikas su priimtomis priklausomyb\u0117mis<\/p>\n\n\n\n<p><strong><a href=\"https:\/\/thecodest.co\/lt\/blog\/hire-ror-developer\/\">Ruby<\/a> apie \"Rails\" moduliavim\u0105 su \"Packwerk<\/strong> priimti priklausomybes, m\u016bs\u0173 programa veiks kaip ir anks\u010diau, ta\u010diau dabar turime daugiau<br>informacij\u0105, kad gal\u0117tum\u0117te priimti sprendimus ir keisti strukt\u016br\u0105.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Pa\u0161alinti \u017eiedines priklausomybes<\/h3>\n\n\n\n<p>Ankstesn\u0117je diagramoje buvo daug \u017eiedini\u0173 priklausomybi\u0173, kurias reik\u0117jo ka\u017ekaip i\u0161spr\u0119sti. Turime \u012fvairi\u0173 strategij\u0173, kaip tai padaryti:<\/p>\n\n\n\n<p>- Nieko nedarykite,<\/p>\n\n\n\n<p>- Priimti priklausomybes, Sujungti paketus,<\/p>\n\n\n\n<p>- Perkelti <a href=\"https:\/\/thecodest.co\/lt\/dictionary\/what-is-code-refactoring\/\">kodas<\/a> tarp paket\u0173,<\/p>\n\n\n\n<p>- Dubliuoti funkcij\u0105,&nbsp;<\/p>\n\n\n\n<p>- Atlikite priklausomyb\u0117s \u012fskiepijim\u0105 arba priklausomyb\u0117s \u012fskiepijim\u0105 su ra\u0161ymu.<\/p>\n\n\n\n<p>Viena i\u0161 problem\u0173 yra ta, kad, nor\u0117dami tinkamai atlikti refaktori\u0173, turime \u017einoti kod\u0173 baz\u0119. Nesu gerai susipa\u017ein\u0119s su \u0161io projekto kod\u0173 baze, nes j\u012f \u0117miau kaip pavyzd\u012f, tod\u0117l praktiniais sumetimais pasirinksime pirm\u0105j\u0105 strategij\u0105 - nieko nedaryti. Net jei i\u0161vengsime did\u017eiosios dalies refaktorizavimo, norime dirbti su priklausomyb\u0117mis <em>root<\/em> pakuot\u0117.<\/p>\n\n\n\n<p>\u012e \u0161aknin\u012f paket\u0105 \u012ftraukti visi klijai i\u0161 <strong>\"Rails\" sistema<\/strong>, visas klases, i\u0161 kuri\u0173 paveldime, ir priversti jas veikti kartu. Taigi, kad i\u0161spr\u0119stume \u017eiedini\u0173 priklausomybi\u0173 problem\u0105, toliau nurodytais veiksmais sukursime nauj\u0105 paket\u0105, pavadint\u0105 rails:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Perkelkite visus programos_ failus ir aplankus i\u0161 programos \u012f <code>app\/packages\/rails<\/code>.<\/li>\n\n\n\n<li>Sukurti<code>package.yml<\/code> paket\u0105, kurio konfig\u016bracija tokia pati kaip ankstesni\u0173 paket\u0173.<\/li>\n\n\n\n<li>Prid\u0117kite visus naujus fail\u0173 kelius \u012f <code>packwerk.yml<\/code>.<\/li>\n\n\n\n<li>Prid\u0117ti <code>app\/packages\/rails<\/code> kaip priklausomyb\u0119 nuo kit\u0173 paket\u0173.<\/li>\n<\/ol>\n\n\n\n<p>Suk\u016br\u0119 paket\u0105 prad\u0117sime pasteb\u0117ti daug fail\u0173, kuri\u0173 strukt\u016br\u0105 galima pakeisti. Visk\u0105 perk\u0117lus \u012f atitinkam\u0105 paket\u0105 ir pri\u0117mus<br>priklausomybi\u0173, tur\u0117sime nauj\u0105 strukt\u016br\u0105 ir \u0161varesn\u012f grafik\u0105.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"\/app\/uploads\/2024\/05\/graph.png\" alt=\"Paketo strukt\u016bra su b\u0117gi\u0173 paketu \" title=\"Paketo strukt\u016bra su &quot;rails&quot; paketo pavyzd\u017eiu\"\/><\/figure>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"\/app\/uploads\/2024\/05\/8.png\" alt=\"Grafikas be \u0161aknini\u0173 \u017eiedini\u0173 priklausomybi\u0173\" title=\"Grafikas be \u0161aknini\u0173 \u017eiedini\u0173 priklausomybi\u0173 pavyzdys\"\/><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Priklausomybi\u0173 pa\u0161alinimas i\u0161 \u0161akninio paketo<\/h3>\n\n\n\n<p>Dabar m\u016bs\u0173 grafikas atrodo daug geriau, b\u016bt\u0173 puiku, jei gal\u0117tume pa\u0161alinti visas priklausomybes i\u0161 \u0161akninio paketo. Jei patikrinsime deprecated_references.yml \u0161akniniame pakete, pasteb\u0117sime, kad dauguma j\u0173 yra i\u0161 <code>testas<\/code> , <code>lib\/tasks<\/code> , <code>db<\/code> ir <code>konfig\u016bracija<\/code><br>aplankas. Nor\u0117dami i\u0161spr\u0119sti \u0161ias priklausomybes, kiekviename pakete sukursime bandym\u0173 aplank\u0105. Tur\u0117dami ka\u017ek\u0105 pana\u0161aus \u012f <code>app\/packages\/users\/test<\/code>. Toliau ketiname i\u0161skirti <code>lib\/tasks<\/code> , <code>db<\/code> ir <code>konfig\u016bracija<\/code>tarp kit\u0173 aplank\u0173 i\u0161 <strong>Packwerk<\/strong> analiz\u0119, nes \u0161ios priklausomyb\u0117s n\u0117ra labai svarbios m\u016bs\u0173 analiz\u0117je ir neturime paprasto b\u016bdo jas i\u0161spr\u0119sti. Mes prid\u0117sime prie savo <em>packwerk.yml<\/em>.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"ruby\" class=\"language-ruby\">atmesti:\n- \"{bin,node_modules,script,tmp,vendor,lib,db,config,perf_scripts}\/**\/*\"\n- \"lib\/tasks\/**\/*.rake\"<\/code><\/pre>\n\n\n\n<p>Perk\u0117lus visus testus i\u0161 \u0161akninio paketo ir pa\u0161alinus aplankus i\u0161 analiz\u0117s, tur\u0117sime nauj\u0105 grafik\u0105 be \u0161aknini\u0173 priklausomybi\u0173.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"\/app\/uploads\/2024\/05\/9.png\" alt=\"Grafikas be \u0161aknini\u0173 priklausomybi\u0173\" title=\"Grafikas be \u0161aknini\u0173 priklausomybi\u0173\"\/><\/figure>\n\n\n\n<p>Kaip matome, vis dar turime \u017eiedini\u0173 priklausomybi\u0173<code>vartotojai<\/code> , <code>atliekynai<\/code> , ir <code>dokumentai<\/code> . Nors j\u0173 nei\u0161sprend\u0117me, dabar turime perduoti svarbios informacijos. Mes \u017einome, kad kiekvienas <a href=\"https:\/\/thecodest.co\/lt\/blog\/how-to-hire-the-best-outsourced-development-team-for-a-scaleup\/\">komanda<\/a> kuris atlieka pakeitimus viename i\u0161 \u0161i\u0173 paket\u0173, tikriausiai tur\u0117s atlikti pakeitimus ir paketuose, turin\u010diuose \u017eiedin\u0119 priklausomyb\u0119. Kita vertus, \u017einome, kad team gali veikti <code>github_fetchers<\/code> tik \u017einant, kokie paketai yra<br>kiekvien\u0105 akimirk\u0105 patiria poky\u010dius.<\/p>\n\n\n\n<p>Galutin\u012f projekto rezultat\u0105 galite rasti <a href=\"https:\/\/github.com\/niconisoria\/codetriage-packwerk\" rel=\"nofollow\">\u010dia<\/a>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Kitas \u017eingsnis<\/h3>\n\n\n\n<p>Kitas \u017eingsnis - kiekviename pakete galite u\u017etikrinti nuolatin\u012f privatum\u0105 ir atskleisti tik vie\u0161\u0105 API, kuri bus prieinama i\u0161 kit\u0173 paket\u0173. Galite lengvai konfig\u016bruoti, kur j\u016bs\u0173 API bus patalpinta <em>package.yml<\/em>.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"ruby\" class=\"language-ruby\">enforce_privacy: true\nenforce_dependencies: true\npublic_path: my\/custom\/path\/<\/code><\/pre>\n\n\n\n<p><code> <\/code><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">I\u0161vados<\/h2>\n\n\n\n<p><strong>Packwerk<\/strong> suteikia mums daug informacijos apie m\u016bs\u0173 taikom\u0105j\u0105 program\u0105 ir, naudodamiesi \u0161ia informacija, galime priimti sprendimus, kaip pagerinti team darbo eig\u0105. Nors procesas atrod\u0117 ilgas ir su daugybe konfig\u016bracij\u0173, jis neb\u016btinai turi b\u016bti toks visada. Galime prad\u0117ti kurti paketus tik naujam kodui, prid\u0117tam prie m\u016bs\u0173 taikomosios programos, o v\u0117liau palaipsniui modulizuoti. Taigi dabar galime prad\u0117ti kalb\u0117ti apie laipsni\u0161k\u0105 moduliavim\u0105 - \u0161i\u0105 koncepcij\u0105 pristat\u0117 Stephanas Hagemannas <em>\u201cPirm\u0105 kart\u0105 galime nuspr\u0119sti prad\u0117ti modulizuoti dal\u012f kodo siekiamyb\u0117s b\u016bdu... Tai leid\u017eia mums sukurti palaipsniui besiple\u010dian\u010di\u0105 paramos sistem\u0105 geresnei taikomosios programos strukt\u016brai\u201d.<\/em><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\u0160altiniai<\/h2>\n\n\n\n<ol class=\"wp-block-list\">\n<li><a href=\"https:\/\/leanpub.com\/package-based-rails-applications\" rel=\"nofollow\">Laipsni\u0161kas Ruby on Rails moduliavimas - Stephan Hagemann<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/shopify.engineering\/enforcing-modularity-rails-apps-packwerk\">Moduliarumo u\u017etikrinimas \"Rails\" program\u0117l\u0117se naudojant \"Packwerk<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/github.com\/Shopify\/packwerk\">Packwerk Github<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/github.com\/niconisoria\/codetriage-packwerk\">Straipsnio \u0161altinio kodas<\/a><\/li>\n<\/ol>\n\n\n\n<figure class=\"wp-block-image\"><a href=\"https:\/\/thecodest.co\/contact\"><img decoding=\"async\" src=\"\/app\/uploads\/2024\/05\/cta_2.jpeg\" alt=\"Skaitmenini\u0173 produkt\u0173 k\u016brimo konsultacijos\"\/><\/a><\/figure>\n\n\n\n<p><strong>Skaityti daugiau<\/strong><\/p>\n\n\n\n<p><a href=\"https:\/\/thecodest.co\/blog\/graphql-ruby-what-about-performance\">\"GraphQL Ruby\". O kaip d\u0117l na\u0161umo?<\/a><\/p>\n\n\n\n<p><a href=\"https:\/\/thecodest.co\/blog\/rails-and-other-means-of-transport\">B\u0117giai ir kitos transporto priemon\u0117s<\/a><\/p>\n\n\n\n<p><a href=\"https:\/\/thecodest.co\/blog\/rails-development-with-tmux-vim-fzf-ripgrep\">\"Rails\" k\u016brimas naudojant TMUX, \"Vim\", Fzf + Ripgrep<\/a><\/p>","protected":false},"excerpt":{"rendered":"<p>Antrajame m\u016bs\u0173 Ruby on Rails moduliavimo su \"Packwerk\" epizode atid\u017eiau ap\u017evelgsime parai\u0161kos kaip paketo koncepcij\u0105.<\/p>","protected":false},"author":2,"featured_media":3567,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"footnotes":""},"categories":[8],"tags":[],"class_list":["post-3566","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-software-development"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v27.3 (Yoast SEO v27.3) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Ruby on Rails modularization with Packwerk Episode II - The Codest<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/thecodest.co\/lt\/tinklarastis\/ruby-on-rails-moduliavimas-su-packwerk-ii-epizodas\/\" \/>\n<meta property=\"og:locale\" content=\"lt_LT\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Ruby on Rails modularization with Packwerk Episode II\" \/>\n<meta property=\"og:description\" content=\"In the second episode of our Ruby on Rails modularization with Packwerk we will take a close look at the concept of application as an package.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/thecodest.co\/lt\/tinklarastis\/ruby-on-rails-moduliavimas-su-packwerk-ii-epizodas\/\" \/>\n<meta property=\"og:site_name\" content=\"The Codest\" \/>\n<meta property=\"article:published_time\" content=\"2022-01-10T15:47:14+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2026-04-28T14:05:25+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/thecodest.co\/app\/uploads\/2024\/05\/ruby_on_rails_modularization_with_packwerk_-__-_episode_2.png\" \/>\n\t<meta property=\"og:image:width\" content=\"960\" \/>\n\t<meta property=\"og:image:height\" content=\"540\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"thecodest\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"thecodest\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"8 minut\u0117s\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/thecodest.co\\\/blog\\\/ruby-on-rails-modularization-with-packwerk-episode-ii\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/thecodest.co\\\/blog\\\/ruby-on-rails-modularization-with-packwerk-episode-ii\\\/\"},\"author\":{\"name\":\"thecodest\",\"@id\":\"https:\\\/\\\/thecodest.co\\\/#\\\/schema\\\/person\\\/7e3fe41dfa4f4e41a7baad4c6e0d4f76\"},\"headline\":\"Ruby on Rails modularization with Packwerk Episode II\",\"datePublished\":\"2022-01-10T15:47:14+00:00\",\"dateModified\":\"2026-04-28T14:05:25+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/thecodest.co\\\/blog\\\/ruby-on-rails-modularization-with-packwerk-episode-ii\\\/\"},\"wordCount\":1295,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/thecodest.co\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/thecodest.co\\\/blog\\\/ruby-on-rails-modularization-with-packwerk-episode-ii\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/thecodest.co\\\/app\\\/uploads\\\/2024\\\/05\\\/ruby_on_rails_modularization_with_packwerk_-__-_episode_2.png\",\"articleSection\":[\"Software Development\"],\"inLanguage\":\"lt-LT\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/thecodest.co\\\/blog\\\/ruby-on-rails-modularization-with-packwerk-episode-ii\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/thecodest.co\\\/blog\\\/ruby-on-rails-modularization-with-packwerk-episode-ii\\\/\",\"url\":\"https:\\\/\\\/thecodest.co\\\/blog\\\/ruby-on-rails-modularization-with-packwerk-episode-ii\\\/\",\"name\":\"Ruby on Rails modularization with Packwerk Episode II - The Codest\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/thecodest.co\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/thecodest.co\\\/blog\\\/ruby-on-rails-modularization-with-packwerk-episode-ii\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/thecodest.co\\\/blog\\\/ruby-on-rails-modularization-with-packwerk-episode-ii\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/thecodest.co\\\/app\\\/uploads\\\/2024\\\/05\\\/ruby_on_rails_modularization_with_packwerk_-__-_episode_2.png\",\"datePublished\":\"2022-01-10T15:47:14+00:00\",\"dateModified\":\"2026-04-28T14:05:25+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/thecodest.co\\\/blog\\\/ruby-on-rails-modularization-with-packwerk-episode-ii\\\/#breadcrumb\"},\"inLanguage\":\"lt-LT\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/thecodest.co\\\/blog\\\/ruby-on-rails-modularization-with-packwerk-episode-ii\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"lt-LT\",\"@id\":\"https:\\\/\\\/thecodest.co\\\/blog\\\/ruby-on-rails-modularization-with-packwerk-episode-ii\\\/#primaryimage\",\"url\":\"https:\\\/\\\/thecodest.co\\\/app\\\/uploads\\\/2024\\\/05\\\/ruby_on_rails_modularization_with_packwerk_-__-_episode_2.png\",\"contentUrl\":\"https:\\\/\\\/thecodest.co\\\/app\\\/uploads\\\/2024\\\/05\\\/ruby_on_rails_modularization_with_packwerk_-__-_episode_2.png\",\"width\":960,\"height\":540},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/thecodest.co\\\/blog\\\/ruby-on-rails-modularization-with-packwerk-episode-ii\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/thecodest.co\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Ruby on Rails modularization with Packwerk Episode II\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/thecodest.co\\\/#website\",\"url\":\"https:\\\/\\\/thecodest.co\\\/\",\"name\":\"The Codest\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\\\/\\\/thecodest.co\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/thecodest.co\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"lt-LT\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/thecodest.co\\\/#organization\",\"name\":\"The Codest\",\"url\":\"https:\\\/\\\/thecodest.co\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"lt-LT\",\"@id\":\"https:\\\/\\\/thecodest.co\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/thecodest.co\\\/app\\\/uploads\\\/2024\\\/03\\\/thecodest-logo.svg\",\"contentUrl\":\"https:\\\/\\\/thecodest.co\\\/app\\\/uploads\\\/2024\\\/03\\\/thecodest-logo.svg\",\"width\":144,\"height\":36,\"caption\":\"The Codest\"},\"image\":{\"@id\":\"https:\\\/\\\/thecodest.co\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/pl.linkedin.com\\\/company\\\/codest\",\"https:\\\/\\\/clutch.co\\\/profile\\\/codest\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/thecodest.co\\\/#\\\/schema\\\/person\\\/7e3fe41dfa4f4e41a7baad4c6e0d4f76\",\"name\":\"thecodest\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"lt-LT\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/5dbfe6a1e8c86e432e8812759e34e6fe82ebac75119ae3237a6c1311fa19caf4?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/5dbfe6a1e8c86e432e8812759e34e6fe82ebac75119ae3237a6c1311fa19caf4?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/5dbfe6a1e8c86e432e8812759e34e6fe82ebac75119ae3237a6c1311fa19caf4?s=96&d=mm&r=g\",\"caption\":\"thecodest\"},\"url\":\"https:\\\/\\\/thecodest.co\\\/lt\\\/author\\\/thecodest\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Ruby on Rails moduliavimas su \"Packwerk\" II epizodas - The Codest","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/thecodest.co\/lt\/tinklarastis\/ruby-on-rails-moduliavimas-su-packwerk-ii-epizodas\/","og_locale":"lt_LT","og_type":"article","og_title":"Ruby on Rails modularization with Packwerk Episode II","og_description":"In the second episode of our Ruby on Rails modularization with Packwerk we will take a close look at the concept of application as an package.","og_url":"https:\/\/thecodest.co\/lt\/tinklarastis\/ruby-on-rails-moduliavimas-su-packwerk-ii-epizodas\/","og_site_name":"The Codest","article_published_time":"2022-01-10T15:47:14+00:00","article_modified_time":"2026-04-28T14:05:25+00:00","og_image":[{"width":960,"height":540,"url":"https:\/\/thecodest.co\/app\/uploads\/2024\/05\/ruby_on_rails_modularization_with_packwerk_-__-_episode_2.png","type":"image\/png"}],"author":"thecodest","twitter_card":"summary_large_image","twitter_misc":{"Written by":"thecodest","Est. reading time":"8 minut\u0117s"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/thecodest.co\/blog\/ruby-on-rails-modularization-with-packwerk-episode-ii\/#article","isPartOf":{"@id":"https:\/\/thecodest.co\/blog\/ruby-on-rails-modularization-with-packwerk-episode-ii\/"},"author":{"name":"thecodest","@id":"https:\/\/thecodest.co\/#\/schema\/person\/7e3fe41dfa4f4e41a7baad4c6e0d4f76"},"headline":"Ruby on Rails modularization with Packwerk Episode II","datePublished":"2022-01-10T15:47:14+00:00","dateModified":"2026-04-28T14:05:25+00:00","mainEntityOfPage":{"@id":"https:\/\/thecodest.co\/blog\/ruby-on-rails-modularization-with-packwerk-episode-ii\/"},"wordCount":1295,"commentCount":0,"publisher":{"@id":"https:\/\/thecodest.co\/#organization"},"image":{"@id":"https:\/\/thecodest.co\/blog\/ruby-on-rails-modularization-with-packwerk-episode-ii\/#primaryimage"},"thumbnailUrl":"https:\/\/thecodest.co\/app\/uploads\/2024\/05\/ruby_on_rails_modularization_with_packwerk_-__-_episode_2.png","articleSection":["Software Development"],"inLanguage":"lt-LT","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/thecodest.co\/blog\/ruby-on-rails-modularization-with-packwerk-episode-ii\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/thecodest.co\/blog\/ruby-on-rails-modularization-with-packwerk-episode-ii\/","url":"https:\/\/thecodest.co\/blog\/ruby-on-rails-modularization-with-packwerk-episode-ii\/","name":"Ruby on Rails moduliavimas su \"Packwerk\" II epizodas - The Codest","isPartOf":{"@id":"https:\/\/thecodest.co\/#website"},"primaryImageOfPage":{"@id":"https:\/\/thecodest.co\/blog\/ruby-on-rails-modularization-with-packwerk-episode-ii\/#primaryimage"},"image":{"@id":"https:\/\/thecodest.co\/blog\/ruby-on-rails-modularization-with-packwerk-episode-ii\/#primaryimage"},"thumbnailUrl":"https:\/\/thecodest.co\/app\/uploads\/2024\/05\/ruby_on_rails_modularization_with_packwerk_-__-_episode_2.png","datePublished":"2022-01-10T15:47:14+00:00","dateModified":"2026-04-28T14:05:25+00:00","breadcrumb":{"@id":"https:\/\/thecodest.co\/blog\/ruby-on-rails-modularization-with-packwerk-episode-ii\/#breadcrumb"},"inLanguage":"lt-LT","potentialAction":[{"@type":"ReadAction","target":["https:\/\/thecodest.co\/blog\/ruby-on-rails-modularization-with-packwerk-episode-ii\/"]}]},{"@type":"ImageObject","inLanguage":"lt-LT","@id":"https:\/\/thecodest.co\/blog\/ruby-on-rails-modularization-with-packwerk-episode-ii\/#primaryimage","url":"https:\/\/thecodest.co\/app\/uploads\/2024\/05\/ruby_on_rails_modularization_with_packwerk_-__-_episode_2.png","contentUrl":"https:\/\/thecodest.co\/app\/uploads\/2024\/05\/ruby_on_rails_modularization_with_packwerk_-__-_episode_2.png","width":960,"height":540},{"@type":"BreadcrumbList","@id":"https:\/\/thecodest.co\/blog\/ruby-on-rails-modularization-with-packwerk-episode-ii\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/thecodest.co\/"},{"@type":"ListItem","position":2,"name":"Ruby on Rails modularization with Packwerk Episode II"}]},{"@type":"WebSite","@id":"https:\/\/thecodest.co\/#website","url":"https:\/\/thecodest.co\/","name":"The Codest","description":"","publisher":{"@id":"https:\/\/thecodest.co\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/thecodest.co\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"lt-LT"},{"@type":"Organization","@id":"https:\/\/thecodest.co\/#organization","name":"The Codest","url":"https:\/\/thecodest.co\/","logo":{"@type":"ImageObject","inLanguage":"lt-LT","@id":"https:\/\/thecodest.co\/#\/schema\/logo\/image\/","url":"https:\/\/thecodest.co\/app\/uploads\/2024\/03\/thecodest-logo.svg","contentUrl":"https:\/\/thecodest.co\/app\/uploads\/2024\/03\/thecodest-logo.svg","width":144,"height":36,"caption":"The Codest"},"image":{"@id":"https:\/\/thecodest.co\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/pl.linkedin.com\/company\/codest","https:\/\/clutch.co\/profile\/codest"]},{"@type":"Person","@id":"https:\/\/thecodest.co\/#\/schema\/person\/7e3fe41dfa4f4e41a7baad4c6e0d4f76","name":"thecodest","image":{"@type":"ImageObject","inLanguage":"lt-LT","@id":"https:\/\/secure.gravatar.com\/avatar\/5dbfe6a1e8c86e432e8812759e34e6fe82ebac75119ae3237a6c1311fa19caf4?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/5dbfe6a1e8c86e432e8812759e34e6fe82ebac75119ae3237a6c1311fa19caf4?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/5dbfe6a1e8c86e432e8812759e34e6fe82ebac75119ae3237a6c1311fa19caf4?s=96&d=mm&r=g","caption":"thecodest"},"url":"https:\/\/thecodest.co\/lt\/author\/thecodest\/"}]}},"_links":{"self":[{"href":"https:\/\/thecodest.co\/lt\/wp-json\/wp\/v2\/posts\/3566","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/thecodest.co\/lt\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/thecodest.co\/lt\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/thecodest.co\/lt\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/thecodest.co\/lt\/wp-json\/wp\/v2\/comments?post=3566"}],"version-history":[{"count":10,"href":"https:\/\/thecodest.co\/lt\/wp-json\/wp\/v2\/posts\/3566\/revisions"}],"predecessor-version":[{"id":7983,"href":"https:\/\/thecodest.co\/lt\/wp-json\/wp\/v2\/posts\/3566\/revisions\/7983"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/thecodest.co\/lt\/wp-json\/wp\/v2\/media\/3567"}],"wp:attachment":[{"href":"https:\/\/thecodest.co\/lt\/wp-json\/wp\/v2\/media?parent=3566"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/thecodest.co\/lt\/wp-json\/wp\/v2\/categories?post=3566"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/thecodest.co\/lt\/wp-json\/wp\/v2\/tags?post=3566"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}