{"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-modularizacija-ar-packwerk-ii-epizode","status":"publish","type":"post","link":"https:\/\/thecodest.co\/lv\/blog\/ruby-on-rails-modularization-with-packwerk-episode-ii\/","title":{"rendered":"Ruby on Rails modul\u0101cija ar Packwerk Episode II"},"content":{"rendered":"<h2 class=\"wp-block-heading\">Pieteikums k\u0101 pakete<\/h2>\n\n\n\n<p>M\u016bsu lietojumprogrammas modul\u0113\u0161anas pieeja ir p\u0101rv\u0113rst visu lietojumprogrammu paket\u0113.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Izveidot strukt\u016bru<\/h3>\n\n\n\n<p>Vispirms mums ir j\u0101izveido <code>app\/packages<\/code> mapi, kur\u0101 m\u0113s izvietosim visas m\u016bsu paketes. Lai izol\u0113tu m\u016bsu paketes, mums ir j\u0101atdala katra <strong>MVC koncepcija<\/strong> vien\u0101 map\u0113. \u0145emot <strong>CodeTriage <a href=\"https:\/\/thecodest.co\/lv\/dictionary\/why-do-projects-fail\/\">projekts<\/a><\/strong> k\u0101 piem\u0113ru m\u0113s redz\u0113sim kaut ko l\u012bdz\u012bgu \u0161\u0101dam att\u0113lam.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"\/app\/uploads\/2024\/05\/2.png\" alt=\"paketes strukt\u016bra \" title=\"paketes strukt\u016bras piem\u0113rs\"\/><\/figure>\n\n\n\n<p>Ja m\u0113\u0123in\u0101sim palaist serveri, tas nesp\u0113s atrast konstantes. T\u0101p\u0113c mums ir j\u0101pievieno konfigur\u0101cijas rinda m\u016bsu <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>Tagad lietojumprogramma darbojas, bet t\u0101 nevar atrast skatus, t\u0101p\u0113c mums ir nepiecie\u0161ams pievienot v\u0113l vienu konfigur\u0101cijas rindu m\u016bsu <code>application_controller.rb<\/code><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"ruby\" class=\"language-ruby\">pievienot_skat\u012bjuma_ce\u013cu(Dir.glob(<a href=\"https:\/\/thecodest.co\/lv\/blog\/ways-to-increase-your-rails-performance\/\">Sliedes<\/a>.root.join('app\/packages\/*\/views'))))<\/code><\/pre>\n\n\n\n<p><\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Izveidot paketes<\/h3>\n\n\n\n<p>Strukt\u016bra ir gatava, t\u0101p\u0113c tagad varam s\u0101kt pakot\u0146u izveidi. Lai to izdar\u012btu, mums tikai j\u0101pievieno<code>package.yml<\/code> katr\u0101 map\u0113 ar \u0161\u0101du konfigur\u0101ciju:<\/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 piem\u0113rs\"\/><\/figure>\n\n\n\n<p><code>enforce_privacy<\/code>sniedz <a href=\"https:\/\/thecodest.co\/lv\/blog\/why-us-companies-are-opting-for-polish-developers\/\">mums<\/a> iesp\u0113ja izol\u0113t visas paketes konstantes un str\u0101d\u0101t ar publisku <a href=\"https:\/\/thecodest.co\/lv\/blog\/compare-staff-augmentation-firms-that-excel-in-api-team-staffing-for-financial-technology-projects\/\">API<\/a>. Lai atkl\u0101tu publisk\u0101s konstantes, mums ir j\u0101pievieno konstantes, piem\u0113ram.&nbsp;<code>packages\/users\/app\/public.<\/code>Pagaid\u0101m m\u0113s \u0161o konfigur\u0101ciju iestat\u012bsim uz <em> viltus<\/em>.<\/p>\n\n\n\n<p><code>enforce_dependencies<\/code> nodro\u0161in\u0101s paketes atkar\u012bbu un p\u0101rbaud\u012bs visas konstantas atsauces. Ja atkar\u012bba nav skaidri defin\u0113ta, tas b\u016bs robe\u017eas p\u0101rk\u0101pums.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Iepakojumu sist\u0113mas apstiprin\u0101\u0161ana<\/h3>\n\n\n\n<p><strong>Packwerk<\/strong> noteica krit\u0113riju, kas mums j\u0101iev\u0113ro, lai izveidotu der\u012bgu pake\u0161u sist\u0113mu. M\u0113s varam s\u0101kt palaist <code>packwerk apstiprin\u0101t<\/code> m\u016bsu konsol\u0113.<\/p>\n\n\n\n<p>&nbsp;T\u0101d\u0113j\u0101di tiks p\u0101rbaud\u012bta m\u016bsu mapju strukt\u016bra, <strong>paketes konfigur\u0101cija<\/strong>, un autom\u0101tisk\u0101 ce\u013c\u0101 iel\u0101d\u0113t ke\u0161atmi\u0146u.<\/p>\n\n\n\n<p>\u0160obr\u012bd m\u016bsu lietojumprogramma nav der\u012bga, un mums ir j\u0101labo slodzes ce\u013ci programm\u0101.<strong><code>packwerk.yml<\/code>.<\/strong> Lai to izdar\u012btu, mums tikai j\u0101pievieno tr\u016bksto\u0161ie ce\u013ci.<\/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# Lietot\u0101ji\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>\u0160obr\u012bd esam gatavi p\u0101rbaud\u012bt robe\u017eu p\u0101rk\u0101pumus m\u016bsu lietojumprogramm\u0101. Lai p\u0101rbaud\u012btu p\u0101rk\u0101pumus, m\u0113s varam palaist<code>packwerk update-deprecations<\/code> , \u0161\u012b komanda \u0123ener\u0113s <code>deprecated_references.yml<\/code> failu katrai paketei. Katr\u0101 fail\u0101 m\u0113s atrad\u012bsim paketes nosaukumu, p\u0101rk\u0101puma veidu un faila ce\u013cu. Izmantojot \u0161o inform\u0101ciju, m\u0113s zin\u0101m, kur notiek p\u0101rk\u0101pums, un varam pie\u0146emt l\u0113mumu par t\u0101 nov\u0113r\u0161anu.<\/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 piem\u0113rs\"\/><\/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:\": p\u0101rk\u0101pumi:\n    - atkar\u012bba\n    faili:\n    - app\/packages\/users\/models\/user.rb<\/code><\/pre>\n\n\n\n<p>Izmantojot piem\u0113ru, m\u0113s aprakst\u012bsim katru \u0123ener\u0113t\u0101s inform\u0101cijas da\u013cu.<br>l\u012bdz <strong>Packwerk<\/strong>.<\/p>\n\n\n\n<p>- <code>app\/packages\/repos<\/code> &nbsp;- pakete, kur\u0101 konstants p\u0101rk\u0101pums ir<br>atrasts.<\/p>\n\n\n\n<p>- <code>::Repo<\/code> &nbsp;- ce\u013c\u0161 l\u012bdz datnei, kur\u0101 atrodas p\u0101rk\u0101pt\u0101 konstante.<\/p>\n\n\n\n<p>- <code>atkar\u012bba<\/code> &nbsp;- p\u0101rk\u0101puma veids - vai nu atkar\u012bba, vai priv\u0101tums.<\/p>\n\n\n\n<p>- <code>app\/packages\/users\/models\/user.rb<\/code> &nbsp;- ce\u013c\u0161 l\u012bdz datnei, kur\u0101 atrodas p\u0101rk\u0101pt\u0101 konstante.<\/p>\n\n\n\n<p>K\u0101 p\u0113d\u0113jo soli \u0161aj\u0101 sada\u013c\u0101 neaizmirstiet pievienot jaunrad\u012btos failu ce\u013cus pie <code>packwerk.ym<\/code>l un v\u0113lreiz palaidiet valid\u0101ciju.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Atkar\u012bbu vizualiz\u0101cija<\/h3>\n\n\n\n<p>Izmantojot visu inform\u0101ciju package.yml un <code>deprecated_references.yml<\/code>tad m\u0113s varam<br>vizualiz\u0113t atkar\u012bbu grafiku. Lai to izdar\u012btu, mums ir nepiecie\u0161ams pievienot v\u0113l vienu gem, \u0161aj\u0101 gad\u012bjum\u0101 m\u0113s izmantosim <a href=\"https:\/\/github.com\/mquan\/pocky\" rel=\"nofollow\">Pocky<\/a>.<\/p>\n\n\n\n<p>Slie\u017eu gr\u0101beklis <code>pocky:\u0123ener\u0113t<\/code> m\u0113s izveidosim failu ar nosaukumu <code>packwerk.png<\/code> kur m\u0113s varam vizualiz\u0113t m\u016bsu pirmo atkar\u012bbu grafiku.<\/p>\n\n\n\n<p>Kad visas paketes ir defin\u0113tas, m\u016bsu grafiks izskat\u0101s \u0161\u0101di.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"\/app\/uploads\/2024\/05\/5.png\" alt=\"grafiks bez akcept\u0113t\u0101m atkar\u012bb\u0101m\" title=\"grafiks bez akcept\u0113t\u0101m atkar\u012bb\u0101m piem\u0113rs\"\/><\/figure>\n\n\n\n<p>atkar\u012bbas jau past\u0101v, bet tas nenoz\u012bm\u0113, ka t\u0101s ir akcept\u0113tas ar <strong>Packwerk<\/strong>. Uz<br>pie\u0146emt atkar\u012bbu, mums ir nepiecie\u0161ams pievienot atkar\u012bbu konfigur\u0101ciju, lai <code>package.yml<\/code><br>katr\u0101 iepakojum\u0101. M\u0113s koncentr\u0113simies uz <code>mail_builders<\/code> jo t\u0101 ir pakete bez ap\u013cveida atkar\u012bbas. Ir v\u0113rts piemin\u0113t, ka <strong>Packwerk<\/strong> ne\u013cauj mums pie\u0146emt ap\u013cveida atkar\u012bbas.<\/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>P\u0113c \u0161\u012bs konfigur\u0101cijas pievieno\u0161anas, <strong>Pocky<\/strong> akcept\u0113t\u0101s atkar\u012bbas tiks iekr\u0101sotas za\u013c\u0101 kr\u0101s\u0101.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"\/app\/uploads\/2024\/05\/6.png\" alt=\"grafiks ar pie\u0146emtaj\u0101m atkar\u012bb\u0101m \" title=\"grafiks bez akcept\u0113t\u0101m atkar\u012bb\u0101m piem\u0113rs\"\/><\/figure>\n\n\n\n<p>M\u0113s varam dz\u0113st <code>deprecated_references.yml<\/code> no <code>app\/packages\/mail_builders<\/code> un palaist<br><code>packwerk update-deprecations<\/code> atkal. Faili netiks \u0123ener\u0113ts v\u0113lreiz, jo visi<br>\u0161aj\u0101 paket\u0113 tika nov\u0113rsti p\u0101rk\u0101pumi. Ir svar\u012bgi piemin\u0113t, ka, pat ja m\u0113s ne Grafiks ar pie\u0146emtaj\u0101m atkar\u012bb\u0101m<\/p>\n\n\n\n<p><strong><a href=\"https:\/\/thecodest.co\/lv\/blog\/hire-ror-developer\/\">Rub\u012bns<\/a> on Rails modul\u0113\u0161ana ar Packwerk<\/strong> pie\u0146emt atkar\u012bbas, m\u016bsu lietojumprogramma joproj\u0101m darbosies k\u0101 iepriek\u0161, bet tagad mums ir vair\u0101k<br>inform\u0101ciju, lai pie\u0146emtu l\u0113mumus un veiktu izmai\u0146as.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Dz\u0113st ap\u013cveida atkar\u012bbas<\/h3>\n\n\n\n<p>M\u016bsu iepriek\u0161\u0113j\u0101 grafik\u0101 bija daudz ap\u013cveida atkar\u012bbu, kuras vajadz\u0113ja kaut k\u0101 atrisin\u0101t. Mums ir da\u017e\u0101das strat\u0113\u0123ijas, k\u0101 to izdar\u012bt:<\/p>\n\n\n\n<p>- Nedariet neko,<\/p>\n\n\n\n<p>- Pie\u0146emt atkar\u012bbas, Apvienot paketes,<\/p>\n\n\n\n<p>- P\u0101rvietot <a href=\"https:\/\/thecodest.co\/lv\/dictionary\/what-is-code-refactoring\/\">kods<\/a> starp iepakojumiem,<\/p>\n\n\n\n<p>- Funkcijas dubl\u0113\u0161ana,&nbsp;<\/p>\n\n\n\n<p>- Veiciet atkar\u012bbu iesmidzin\u0101\u0161anu vai atkar\u012bbu iesmidzin\u0101\u0161anu ar rakst\u012b\u0161anu.<\/p>\n\n\n\n<p>Viena no probl\u0113m\u0101m ir t\u0101, ka, lai veiktu pareizu refaktoriz\u0101ciju, mums ir j\u0101p\u0101rzina kodb\u0101ze. Es neesmu tik labi iepazinies ar \u0161\u012b projekta kodu b\u0101zi, jo to izmantoju k\u0101 piem\u0113ru, t\u0101p\u0113c praktisku apsv\u0113rumu d\u0113\u013c m\u0113s izv\u0113l\u0113simies pirmo strat\u0113\u0123iju - nedar\u012bt neko. Pat ja m\u0113s izvair\u012bsimies no liel\u0101k\u0101s da\u013cas refaktoriz\u0101cijas, m\u0113s v\u0113lamies str\u0101d\u0101t ar atkar\u012bb\u0101m, kas atrodas <em>saknes<\/em> iepakojums.<\/p>\n\n\n\n<p>Saknes pakete satur visu l\u012bme no <strong>Rails ietvars<\/strong>, visas klases, no kur\u0101m mantojam, un pan\u0101kt, lai t\u0101s darbojas kop\u0101. T\u0101tad, lai atrisin\u0101tu cirkul\u0101ro atkar\u012bbu probl\u0113mu, m\u0113s izveidosim jaunu pakotni ar nosaukumu rails (sliedes), veicot \u0161\u0101dus so\u013cus:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>P\u0101rvietot visus lietojumprogrammas_ failus un mapes no lietotnes uz <code>app\/packages\/rails<\/code>.<\/li>\n\n\n\n<li>Izveidot<code>package.yml<\/code> paketei ar t\u0101du pa\u0161u konfigur\u0101ciju k\u0101 iepriek\u0161\u0113j\u0101m pakotn\u0113m.<\/li>\n\n\n\n<li>Pievienojiet visus jaunos failu ce\u013cus <code>packwerk.yml<\/code>.<\/li>\n\n\n\n<li>Pievienot <code>app\/packages\/rails<\/code> k\u0101 atkar\u012bba no p\u0101r\u0113j\u0101m pakotn\u0113m.<\/li>\n<\/ol>\n\n\n\n<p>Kad izveidosim pakotni, s\u0101ksim paman\u012bt daudz failu, kurus var p\u0101rstruktur\u0113t. P\u0113c tam, kad viss ir p\u0101rvietots uz atbilsto\u0161o pakotni un pie\u0146emts<br>atkar\u012bbas mums b\u016bs jauna strukt\u016bra un t\u012br\u0101ks grafiks.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"\/app\/uploads\/2024\/05\/graph.png\" alt=\"Iepakojuma strukt\u016bra ar slied\u0113m pakete \" title=\"Paketes strukt\u016bra ar rails paketes piem\u0113ru\"\/><\/figure>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"\/app\/uploads\/2024\/05\/8.png\" alt=\"Grafiks bez sak\u0146u ap\u013cveida atkar\u012bb\u0101m\" title=\"Grafiks bez sak\u0146u ap\u013cveida atkar\u012bb\u0101m piem\u0113rs\"\/><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Atkar\u012bbu no\u0146em\u0161ana no saknes pakotnes<\/h3>\n\n\n\n<p>Tagad m\u016bsu grafiks izskat\u0101s daudz lab\u0101k, b\u016btu lieliski, ja m\u0113s var\u0113tu no\u0146emt visas atkar\u012bbas no saknes paketes. Ja m\u0113s p\u0101rbaud\u012bsim deprecated_references.yml saknes paket\u0113, m\u0113s paman\u012bsim, ka liel\u0101k\u0101 da\u013ca no t\u0101m ir no <code>tests<\/code> , <code>lib\/tasks<\/code> , <code>db<\/code> un <code>konfigurators<\/code><br>mape. Lai atrisin\u0101tu \u0161\u012bs atkar\u012bbas, m\u0113s katr\u0101 paket\u0113 izveidosim testa mapi. Izmantojot kaut ko l\u012bdz\u012bgu <code>app\/packages\/users\/test<\/code>. T\u0101l\u0101k m\u0113s izsl\u0113gsim <code>lib\/tasks<\/code> , <code>db<\/code> un <code>konfigurators<\/code>starp cit\u0101m map\u0113m no <strong>Packwerk<\/strong> anal\u012bzei, jo \u0161\u012bs atkar\u012bbas m\u016bsu anal\u012bz\u0113 nav \u012bpa\u0161i svar\u012bgas un mums nav vienk\u0101r\u0161a veida, k\u0101 t\u0101s atrisin\u0101t. M\u0113s pievienosim m\u016bsu <em>packwerk.yml<\/em>.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"ruby\" class=\"language-ruby\">izsl\u0113gt:\n- \"{bin,node_modules,script,tmp,vendor,lib,db,config,perf_scripts}\/**\/*\"\n- \"lib\/tasks\/**\/*.rake\"<\/code><\/pre>\n\n\n\n<p>P\u0113c visu testu p\u0101rvieto\u0161anas no saknes paketes un mapju izsl\u0113g\u0161anas no anal\u012bzes mums b\u016bs jauns grafiks bez saknes atkar\u012bb\u0101m.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"\/app\/uploads\/2024\/05\/9.png\" alt=\"Grafiks bez saknes atkar\u012bb\u0101m\" title=\"Grafiks bez saknes atkar\u012bb\u0101m\"\/><\/figure>\n\n\n\n<p>K\u0101 redzams, mums joproj\u0101m ir ap\u013cveida atkar\u012bbas, jo<code>lietot\u0101ji<\/code> , <code>repozitoriji<\/code> , un <code>dokumenti<\/code> . Lai gan m\u0113s tos neatrisin\u0101j\u0101m, mums tagad ir svar\u012bga inform\u0101cija, ko nodot t\u0101l\u0101k. M\u0113s zin\u0101m, ka katrs <a href=\"https:\/\/thecodest.co\/lv\/blog\/how-to-hire-the-best-outsourced-development-team-for-a-scaleup\/\">komanda<\/a> kas veic izmai\u0146as vien\u0101 no \u0161\u012bm pakotn\u0113m, iesp\u0113jams, b\u016bs j\u0101veic izmai\u0146as pakotn\u0113s ar cirkul\u0101ro atkar\u012bbu. No otras puses, m\u0113s zin\u0101m, ka team var str\u0101d\u0101t ar <code>github_fetchers<\/code> tikai, zinot, k\u0101das paketes ir<br>ar katru mirkli tiek ietekm\u0113tas p\u0101rmai\u0146as.<\/p>\n\n\n\n<p>Projekta galarezult\u0101tu varat atrast <a href=\"https:\/\/github.com\/niconisoria\/codetriage-packwerk\" rel=\"nofollow\">\u0161eit<\/a>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">N\u0101kamais solis<\/h3>\n\n\n\n<p>N\u0101kamais solis var\u0113tu b\u016bt past\u0101v\u012bga priv\u0101tuma nodro\u0161in\u0101\u0161ana katr\u0101 pakotn\u0113 un publiskot tikai publisko API, kas b\u016bs pieejams no cit\u0101m pakotn\u0113m. Varat viegli konfigur\u0113t, kur j\u016bsu API tiks ievietots <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\">Secin\u0101jumi<\/h2>\n\n\n\n<p><strong>Packwerk<\/strong> sniedz mums daudz inform\u0101cijas par m\u016bsu lietojumprogrammu, un, izmantojot \u0161o inform\u0101ciju, m\u0113s varam pie\u0146emt l\u0113mumus, lai uzlabotu m\u016bsu team darbpl\u016bsmu. Lai gan process \u0161\u0137ita gar\u0161 un ar daudz\u0101m konfigur\u0101cij\u0101m, tam nav j\u0101b\u016bt t\u0101dam vienm\u0113r. M\u0113s varam s\u0101kt veidot paketes tikai jaunajam kodam, kas pievienots m\u016bsu lietojumprogrammai, un p\u0113c tam pak\u0101peniski modul\u0113t. Tagad m\u0113s varam s\u0101kt run\u0101t par pak\u0101penisku modul\u0101ro modul\u0113\u0161anu, un \u0161o koncepciju ieviesa Stefans Hagemans (Stephan Hagemann). <em>\u201cM\u0113s pirmo reizi varam pie\u0146emt l\u0113mumu s\u0101kt modulariz\u0113t da\u013cu koda, lai to padar\u012btu m\u0113r\u0137tiec\u012bgu... Tas \u013cauj mums pak\u0101peniski izveidot atbalsta sist\u0113mu, kas pak\u0101peniski papla\u0161in\u0101s, lai izveidotu lab\u0101ku lietojumprogrammas strukt\u016bru.\u201d.<\/em><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Avoti<\/h2>\n\n\n\n<ol class=\"wp-block-list\">\n<li><a href=\"https:\/\/leanpub.com\/package-based-rails-applications\" rel=\"nofollow\">Pak\u0101peniska modul\u0101cija Ruby on Rails - Stephan Hagemann<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/shopify.engineering\/enforcing-modularity-rails-apps-packwerk\">Modularit\u0101tes nodro\u0161in\u0101\u0161ana Rails lietotn\u0113s ar 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\">Raksta avota kods<\/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=\"Konsult\u0101cijas par digit\u0101lo produktu izstr\u0101di\"\/><\/a><\/figure>\n\n\n\n<p><strong>Las\u012bt vair\u0101k<\/strong><\/p>\n\n\n\n<p><a href=\"https:\/\/thecodest.co\/blog\/graphql-ruby-what-about-performance\">GraphQL Ruby. K\u0101 ir ar veiktsp\u0113ju?<\/a><\/p>\n\n\n\n<p><a href=\"https:\/\/thecodest.co\/blog\/rails-and-other-means-of-transport\">Sliedes un citi transporta l\u012bdzek\u013ci<\/a><\/p>\n\n\n\n<p><a href=\"https:\/\/thecodest.co\/blog\/rails-development-with-tmux-vim-fzf-ripgrep\">Rails att\u012bst\u012bba ar TMUX, Vim, Fzf + Ripgrep<\/a><\/p>","protected":false},"excerpt":{"rendered":"<p>Otraj\u0101 m\u016bsu Ruby on Rails modul\u0113\u0161anas ar Packwerk epizod\u0113 m\u0113s apl\u016bkosim lietojumprogrammas k\u0101 paketes koncepciju.<\/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\/lv\/emuars\/ruby-on-rails-modularizacija-ar-packwerk-ii-epizode\/\" \/>\n<meta property=\"og:locale\" content=\"lv_LV\" \/>\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\/lv\/emuars\/ruby-on-rails-modularizacija-ar-packwerk-ii-epizode\/\" \/>\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 min\u016btes\" \/>\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\":\"lv-LV\",\"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\":\"lv-LV\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/thecodest.co\\\/blog\\\/ruby-on-rails-modularization-with-packwerk-episode-ii\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"lv-LV\",\"@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\":\"lv-LV\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/thecodest.co\\\/#organization\",\"name\":\"The Codest\",\"url\":\"https:\\\/\\\/thecodest.co\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"lv-LV\",\"@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\":\"lv-LV\",\"@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\\\/lv\\\/author\\\/thecodest\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Ruby on Rails modul\u0101cija ar Packwerk Episode II - 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\/lv\/emuars\/ruby-on-rails-modularizacija-ar-packwerk-ii-epizode\/","og_locale":"lv_LV","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\/lv\/emuars\/ruby-on-rails-modularizacija-ar-packwerk-ii-epizode\/","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 min\u016btes"},"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":"lv-LV","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 modul\u0101cija ar 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":"lv-LV","potentialAction":[{"@type":"ReadAction","target":["https:\/\/thecodest.co\/blog\/ruby-on-rails-modularization-with-packwerk-episode-ii\/"]}]},{"@type":"ImageObject","inLanguage":"lv-LV","@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":"lv-LV"},{"@type":"Organization","@id":"https:\/\/thecodest.co\/#organization","name":"The Codest","url":"https:\/\/thecodest.co\/","logo":{"@type":"ImageObject","inLanguage":"lv-LV","@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":"lv-LV","@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\/lv\/author\/thecodest\/"}]}},"_links":{"self":[{"href":"https:\/\/thecodest.co\/lv\/wp-json\/wp\/v2\/posts\/3566","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/thecodest.co\/lv\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/thecodest.co\/lv\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/thecodest.co\/lv\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/thecodest.co\/lv\/wp-json\/wp\/v2\/comments?post=3566"}],"version-history":[{"count":10,"href":"https:\/\/thecodest.co\/lv\/wp-json\/wp\/v2\/posts\/3566\/revisions"}],"predecessor-version":[{"id":7983,"href":"https:\/\/thecodest.co\/lv\/wp-json\/wp\/v2\/posts\/3566\/revisions\/7983"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/thecodest.co\/lv\/wp-json\/wp\/v2\/media\/3567"}],"wp:attachment":[{"href":"https:\/\/thecodest.co\/lv\/wp-json\/wp\/v2\/media?parent=3566"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/thecodest.co\/lv\/wp-json\/wp\/v2\/categories?post=3566"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/thecodest.co\/lv\/wp-json\/wp\/v2\/tags?post=3566"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}