{"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-modularisering-med-packwerk-episode-ii","status":"publish","type":"post","link":"https:\/\/thecodest.co\/da\/blog\/ruby-on-rails-modularization-with-packwerk-episode-ii\/","title":{"rendered":"Ruby on Rails-modularisering med Packwerk Episode II"},"content":{"rendered":"<h2 class=\"wp-block-heading\">Ans\u00f8gning som en pakke<\/h2>\n\n\n\n<p>Tilgangen til at modularisere vores applikation best\u00e5r i at konvertere hele applikationen til en pakke.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Skab strukturen<\/h3>\n\n\n\n<p>F\u00f8rst skal vi oprette <code>app\/pakker<\/code> mappe, hvor vi vil placere alle vores pakker. For at isolere vores pakker er vi n\u00f8dt til at adskille hver <strong>MVC-konceptet<\/strong> i \u00e9n mappe. At tage <strong>KodeTriage <a href=\"https:\/\/thecodest.co\/da\/dictionary\/why-do-projects-fail\/\">projekt<\/a><\/strong> Som eksempel f\u00e5r vi noget, der ligner det f\u00f8lgende billede.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"\/app\/uploads\/2024\/05\/2.png\" alt=\"pakkestruktur \" title=\"eksempel p\u00e5 pakkestruktur\"\/><\/figure>\n\n\n\n<p>Hvis vi pr\u00f8ver at k\u00f8re serveren, vil den ikke kunne finde konstanterne. Derfor er vi n\u00f8dt til at tilf\u00f8je en konfigurationslinje til vores <code>applikation.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>Nu fungerer programmet, men det kan ikke finde visningerne, s\u00e5 vi er n\u00f8dt til at tilf\u00f8je endnu en konfigurationslinje til vores <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\/da\/blog\/ways-to-increase-your-rails-performance\/\">Skinner<\/a>.root.join('app\/packages\/*\/views')))<\/code><\/pre>\n\n\n\n<p><\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Opret pakkerne<\/h3>\n\n\n\n<p>Vores struktur er klar, s\u00e5 nu kan vi begynde at oprette pakkerne. For at g\u00f8re det beh\u00f8ver vi kun at tilf\u00f8je en<code>pakke.yml<\/code> til hver mappe med f\u00f8lgende konfiguration:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"ruby\" class=\"language-ruby\">h\u00e5ndh\u00e6v_privatliv: 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=\"pakke.yml\" title=\"package.yml eksempel\"\/><\/figure>\n\n\n\n<p><code>h\u00e5ndh\u00e6ve_privatliv<\/code>giver <a href=\"https:\/\/thecodest.co\/da\/blog\/why-us-companies-are-opting-for-polish-developers\/\">os<\/a> muligheden for at isolere alle pakkens konstanter og arbejde med en offentlig <a href=\"https:\/\/thecodest.co\/da\/blog\/compare-staff-augmentation-firms-that-excel-in-api-team-staffing-for-financial-technology-projects\/\">API<\/a>. For at eksponere de offentlige konstanter skal vi tilf\u00f8je konstanterne i f.eks.&nbsp;<code>pakker\/brugere\/app\/public.<\/code>Indtil videre s\u00e6tter vi denne konfiguration til <em> falsk<\/em>.<\/p>\n\n\n\n<p><code>h\u00e5ndh\u00e6ve_afh\u00e6ngigheder<\/code> vil h\u00e5ndh\u00e6ve afh\u00e6ngigheden af en pakke og tjekke for alle konstante referencer. Hvis en afh\u00e6ngighed ikke er eksplicit defineret, vil det v\u00e6re en overtr\u00e6delse af gr\u00e6nsen.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Validering af pakkesystemet<\/h3>\n\n\n\n<p><strong>Packwerk<\/strong> etableret et kriterium, som vi skal f\u00f8lge for at have et gyldigt pakkesystem. Vi kan begynde at k\u00f8re <code>packwerk valideret<\/code> i vores konsol.<\/p>\n\n\n\n<p>&nbsp;Dette vil tjekke vores mappestruktur, <strong>Pakkekonfiguration<\/strong>og autoload path cache.<\/p>\n\n\n\n<p>Lige nu er vores applikation ikke gyldig, og vi er n\u00f8dt til at rette belastningsstierne i<strong><code>packwerk.yml<\/code>.<\/strong> For at g\u00f8re dette beh\u00f8ver vi kun at tilf\u00f8je de manglende stier.<\/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#-brugere\n- app\/packages\/users\/controllers\n- app\/pakker\/brugere\/modeller\n- app\/packages\/users\/package.yml\n- app\/pakker\/brugere\/visninger<\/code><\/pre>\n\n\n\n<p>Nu er vi klar til at tjekke gr\u00e6nseoverskridelser i vores applikation. For at tjekke overtr\u00e6delser kan vi k\u00f8re<code>packwerk opdaterer afskrivninger<\/code> vil denne kommando generere <code>for\u00e6ldede_referencer.yml<\/code> fil for hver pakke. I hver fil finder vi pakkenavn, type af overtr\u00e6delse og filsti. Med alle disse oplysninger ved vi, hvor overtr\u00e6delsen sker, og vi kan tr\u00e6ffe en beslutning om at l\u00f8se den.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"\/app\/uploads\/2024\/05\/4.png\" alt=\"for\u00e6ldede_referencer.yml\" title=\"eksempel p\u00e5 deprecated_references.yml\"\/><\/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    overtr\u00e6delser:\n    - afh\u00e6ngighed\n    filer:\n    - app\/packages\/users\/models\/user.rb<\/code><\/pre>\n\n\n\n<p>Med udgangspunkt i eksemplet vil vi beskrive alle dele af den genererede information<br>af <strong>Packwerk<\/strong>.<\/p>\n\n\n\n<p>- <code>app\/pakker\/repos<\/code> &nbsp;- pakke, hvor den konstante overtr\u00e6delse er<br>fundet.<\/p>\n\n\n\n<p>- <code>::Repo<\/code> &nbsp;- stien til den fil, der indeholder den kr\u00e6nkede konstant.<\/p>\n\n\n\n<p>- <code>Afh\u00e6ngighed<\/code> &nbsp;- en form for kr\u00e6nkelse, enten afh\u00e6ngighed eller privatliv.<\/p>\n\n\n\n<p>- <code>app\/packages\/users\/models\/user.rb<\/code> &nbsp;- stien til den fil, der indeholder den kr\u00e6nkede konstant.<\/p>\n\n\n\n<p>Som et sidste trin i dette afsnit skal du ikke glemme at tilf\u00f8je de nye genererede filstier til <code>packwerk.ym<\/code>l og k\u00f8r valideringer igen.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Visualisering af afh\u00e6ngighed<\/h3>\n\n\n\n<p>Med alle oplysningerne i package.yml og <code>for\u00e6ldede_referencer.yml<\/code>Vi kan s\u00e5<br>visualisere en graf over afh\u00e6ngigheder. For at g\u00f8re det skal vi tilf\u00f8je en anden perle, i dette tilf\u00e6lde vil vi bruge <a href=\"https:\/\/github.com\/mquan\/pocky\" rel=\"nofollow\">Pocky<\/a>.<\/p>\n\n\n\n<p>L\u00f8bende rive <code>pocky:generere<\/code> vil vi generere en fil, der hedder <code>packwerk.png<\/code> hvor vi kan visualisere vores f\u00f8rste graf over afh\u00e6ngigheder.<\/p>\n\n\n\n<p>N\u00e5r alle pakkerne er defineret, vil vores graf se s\u00e5dan ud.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"\/app\/uploads\/2024\/05\/5.png\" alt=\"graf uden accepterede afh\u00e6ngigheder\" title=\"graf uden accepterede afh\u00e6ngigheder eksempel\"\/><\/figure>\n\n\n\n<p>afh\u00e6ngigheder findes allerede, men det betyder ikke, at de accepteres af <strong>Packwerk<\/strong>. Til<br>acceptere en afh\u00e6ngighed, skal vi tilf\u00f8je afh\u00e6ngighedskonfigurationen til <code>pakke.yml<\/code><br>i hver eneste pakke. Vi vil fokusere p\u00e5 <code>mail_builders<\/code> da det er en pakke uden cirkul\u00e6r afh\u00e6ngighed. Det er v\u00e6rd at n\u00e6vne, at <strong>Packwerk<\/strong> vil ikke lade os acceptere cirkul\u00e6re afh\u00e6ngigheder.<\/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\nafh\u00e6ngigheder:\n- app\/packages\/docs\n- app\/packages\/issues\n- app\/pakker\/repos<\/code><\/pre>\n\n\n\n<p>N\u00e5r du har tilf\u00f8jet denne konfiguration, <strong>Pocky<\/strong> vil farve de accepterede afh\u00e6ngigheder med gr\u00f8nt.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"\/app\/uploads\/2024\/05\/6.png\" alt=\"graf med accepterede afh\u00e6ngigheder \" title=\"graf uden accepterede afh\u00e6ngigheder eksempel\"\/><\/figure>\n\n\n\n<p>Vi kan slette <code>for\u00e6ldede_referencer.yml<\/code> fra <code>app\/packages\/mail_builders<\/code> og k\u00f8re<br><code>packwerk opdaterer afskrivninger<\/code> igen. Filen vil ikke blive genereret igen, da alle<br>overtr\u00e6delser blev rettet for denne pakke. Det er vigtigt at n\u00e6vne, at selv om vi ikke bruger Graph med accepterede afh\u00e6ngigheder<\/p>\n\n\n\n<p><strong><a href=\"https:\/\/thecodest.co\/da\/blog\/hire-ror-developer\/\">Ruby<\/a> on Rails modularisering med Packwerk<\/strong> acceptere afh\u00e6ngigheder, vil vores program stadig fungere som f\u00f8r, men nu har vi flere<br>information til at tr\u00e6ffe beslutninger og refaktorere.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Fjern cirkul\u00e6re afh\u00e6ngigheder<\/h3>\n\n\n\n<p>I vores tidligere graf havde vi en masse cirkul\u00e6re afh\u00e6ngigheder, som skulle l\u00f8ses p\u00e5 en eller anden m\u00e5de. Vi har forskellige strategier til at g\u00f8re det:<\/p>\n\n\n\n<p>- G\u00f8r ingenting,<\/p>\n\n\n\n<p>- Accepter afh\u00e6ngigheder, flet pakker,<\/p>\n\n\n\n<p>- Flyt dig <a href=\"https:\/\/thecodest.co\/da\/dictionary\/what-is-code-refactoring\/\">Kode<\/a> mellem pakkerne,<\/p>\n\n\n\n<p>- Dupliker en funktionalitet,&nbsp;<\/p>\n\n\n\n<p>- Udf\u00f8r dependency injection eller dependency injection med typing.<\/p>\n\n\n\n<p>Et problem her er, at vi skal kende kodebasen for at kunne lave en ordentlig refaktorering. Jeg er ikke s\u00e5 bekendt med kodebasen i dette projekt, da jeg tog det som et eksempel, s\u00e5 af praktiske grunde vil vi v\u00e6lge den f\u00f8rste strategi, nemlig ikke at g\u00f8re noget. Selv om vi undg\u00e5r det meste af refaktoriseringen, vil vi gerne arbejde med afh\u00e6ngighederne i <em>rod<\/em> pakke.<\/p>\n\n\n\n<p>Rodpakken indeholder al limen fra <strong>Rails-rammev\u00e6rk<\/strong>alle de klasser, vi arver fra, og f\u00e5 dem til at arbejde sammen. S\u00e5 for at l\u00f8se de cirkul\u00e6re afh\u00e6ngigheder skal vi oprette en ny pakke, der hedder rails, i de f\u00f8lgende trin:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Flyt alle application_-filer og -mapper fra appen til <code>app\/pakker\/rails<\/code>.<\/li>\n\n\n\n<li>Opret en<code>pakke.yml<\/code> for pakken med samme konfiguration som de tidligere pakker.<\/li>\n\n\n\n<li>Tilf\u00f8j alle de nye filstier til <code>packwerk.yml<\/code>.<\/li>\n\n\n\n<li>Tilf\u00f8j <code>app\/pakker\/rails<\/code> som en afh\u00e6ngighed af resten af pakkerne.<\/li>\n<\/ol>\n\n\n\n<p>N\u00e5r vi har oprettet pakken, vil vi begynde at l\u00e6gge m\u00e6rke til en masse filer, der kan omstruktureres. Efter at have flyttet alt til den tilsvarende pakke og accepteret<br>afh\u00e6ngigheder f\u00e5r vi en ny struktur og en renere graf.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"\/app\/uploads\/2024\/05\/graph.png\" alt=\"Pakningsstruktur med skinnepakke \" title=\"Pakkestruktur med eksempel p\u00e5 rails-pakke\"\/><\/figure>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"\/app\/uploads\/2024\/05\/8.png\" alt=\"Graf uden cirkul\u00e6re afh\u00e6ngigheder ved roden\" title=\"Eksempel p\u00e5 graf uden cirkul\u00e6re afh\u00e6ngigheder ved roden\"\/><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Fjern afh\u00e6ngigheder fra rodpakken<\/h3>\n\n\n\n<p>Nu ser vores graf meget bedre ud, og det ville v\u00e6re dejligt, hvis vi kunne fjerne alle afh\u00e6ngighederne fra rodpakken. Hvis vi tjekker deprecated_references.yml i rodpakken, vil vi bem\u00e6rke, at de fleste af dem er fra <code>test<\/code> , <code>lib\/opgaver<\/code> , <code>db<\/code> og <code>konfiguration<\/code><br>mappe. For at l\u00f8se disse afh\u00e6ngigheder vil vi oprette en testmappe i hver pakke. At have noget som <code>app\/pakker\/brugere\/test<\/code>. Dern\u00e6st vil vi udelukke <code>lib\/opgaver<\/code> , <code>db<\/code> og <code>konfiguration<\/code>blandt andre mapper fra <strong>Packwerk<\/strong> analyse, da disse afh\u00e6ngigheder ikke er s\u00e6rlig vigtige i vores analyse, og vi ikke har en nem m\u00e5de at l\u00f8se dem p\u00e5. Vi vil tilf\u00f8je f\u00f8lgende til vores <em>packwerk.yml<\/em>.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"ruby\" class=\"language-ruby\">ekskluderer:\n- \"{bin,node_modules,script,tmp,vendor,lib,db,config,perf_scripts}\/**\/*\"\n- \"lib\/tasks\/**\/*.rake\"<\/code><\/pre>\n\n\n\n<p>N\u00e5r vi har flyttet alle testene fra rodpakken og udelukket mapperne fra analysen, f\u00e5r vi en ny graf uden rodafh\u00e6ngigheder.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"\/app\/uploads\/2024\/05\/9.png\" alt=\"Graf uden rodafh\u00e6ngigheder\" title=\"Graf uden rodafh\u00e6ngigheder\"\/><\/figure>\n\n\n\n<p>Som vi kan se, har vi stadig cirkul\u00e6re afh\u00e6ngigheder i<code>brugere<\/code> , <code>Repos<\/code> og <code>Dokumenter<\/code> . Selv om vi ikke l\u00f8ste dem, har vi vigtige oplysninger at videregive nu. Vi ved, at alle <a href=\"https:\/\/thecodest.co\/da\/blog\/how-to-hire-the-best-outsourced-development-team-for-a-scaleup\/\">hold<\/a> der foretager \u00e6ndringer i en af disse pakker, bliver sandsynligvis n\u00f8dt til at foretage \u00e6ndringer i pakkerne med den cirkul\u00e6re afh\u00e6ngighed. P\u00e5 den anden side ved vi, at et team kan arbejde p\u00e5 <code>github_fetchers<\/code> udelukkende at vide, hvilke pakker der er<br>bliver p\u00e5virket af forandringerne i hvert \u00f8jeblik.<\/p>\n\n\n\n<p>Du kan finde det endelige resultat af projektet <a href=\"https:\/\/github.com\/niconisoria\/codetriage-packwerk\" rel=\"nofollow\">her<\/a>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">N\u00e6ste skridt<\/h3>\n\n\n\n<p>Som et n\u00e6ste skridt kan du h\u00e5ndh\u00e6ve konstant privatliv i hver pakke og kun eksponere det offentlige API, som vil v\u00e6re tilg\u00e6ngeligt fra andre pakker. Du kan nemt konfigurere, hvor din API skal placeres i <em>pakke.yml<\/em>.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"ruby\" class=\"language-ruby\">h\u00e5ndh\u00e6v_privatliv: true\nenforce_dependencies: true\npublic_path: min\/custom\/path\/<\/code><\/pre>\n\n\n\n<p><code> <\/code><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Konklusioner<\/h2>\n\n\n\n<p><strong>Packwerk<\/strong> giver os en masse information om vores applikation, og med den information kan vi tr\u00e6ffe beslutninger om at forbedre arbejdsgangen for vores teams. Selvom processen s\u00e5 ud til at v\u00e6re lang og med mange konfigurationer, beh\u00f8ver det ikke altid at v\u00e6re s\u00e5dan. Vi kan begynde med kun at oprette pakker til den nye kode, der tilf\u00f8jes til vores applikation, og derefter modulere gradvist. S\u00e5 nu kan vi begynde at tale om gradvis modularisering - det er et koncept, som Stephan Hagemann har introduceret. <em>\"Vi kan for f\u00f8rste gang beslutte at begynde at modularisere en del af koden p\u00e5 en ambiti\u00f8s m\u00e5de ... Dette giver os mulighed for at skabe et gradvist voksende st\u00f8ttesystem mod en bedre applikationsstruktur\".<\/em><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Kilder<\/h2>\n\n\n\n<ol class=\"wp-block-list\">\n<li><a href=\"https:\/\/leanpub.com\/package-based-rails-applications\" rel=\"nofollow\">Gradvis modularisering til Ruby on Rails - Stephan Hagemann<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/shopify.engineering\/enforcing-modularity-rails-apps-packwerk\">H\u00e5ndh\u00e6velse af modularitet i Rails-apps med 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\">Kildekode til artiklen<\/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=\"R\u00e5dgivning om digital produktudvikling\"\/><\/a><\/figure>\n\n\n\n<p><strong>L\u00e6s mere<\/strong><\/p>\n\n\n\n<p><a href=\"https:\/\/thecodest.co\/blog\/graphql-ruby-what-about-performance\">GraphQL Ruby. Hvad med performance?<\/a><\/p>\n\n\n\n<p><a href=\"https:\/\/thecodest.co\/blog\/rails-and-other-means-of-transport\">Skinner og andre transportmidler<\/a><\/p>\n\n\n\n<p><a href=\"https:\/\/thecodest.co\/blog\/rails-development-with-tmux-vim-fzf-ripgrep\">Rails-udvikling med TMUX, Vim, Fzf + Ripgrep<\/a><\/p>","protected":false},"excerpt":{"rendered":"<p>I den anden episode af vores Ruby on Rails-modularisering med Packwerk ser vi n\u00e6rmere p\u00e5 begrebet applikation som en pakke.<\/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=\"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 name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/thecodest.co\/da\/blog\/ruby-on-rails-modularisering-med-packwerk-episode-ii\/\" \/>\n<meta property=\"og:locale\" content=\"da_DK\" \/>\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\/da\/blog\/ruby-on-rails-modularisering-med-packwerk-episode-ii\/\" \/>\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 minutter\" \/>\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\":\"da-DK\",\"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\",\"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.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/thecodest.co\\\/blog\\\/ruby-on-rails-modularization-with-packwerk-episode-ii\\\/#breadcrumb\"},\"inLanguage\":\"da-DK\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/thecodest.co\\\/blog\\\/ruby-on-rails-modularization-with-packwerk-episode-ii\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"da-DK\",\"@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\":\"da-DK\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/thecodest.co\\\/#organization\",\"name\":\"The Codest\",\"url\":\"https:\\\/\\\/thecodest.co\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"da-DK\",\"@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\":\"da-DK\",\"@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\\\/da\\\/author\\\/thecodest\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Ruby on Rails-modularisering med Packwerk Episode II - The Codest","description":"I den anden episode af vores Ruby on Rails-modularisering med Packwerk ser vi n\u00e6rmere p\u00e5 begrebet applikation som en pakke.","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\/da\/blog\/ruby-on-rails-modularisering-med-packwerk-episode-ii\/","og_locale":"da_DK","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\/da\/blog\/ruby-on-rails-modularisering-med-packwerk-episode-ii\/","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 minutter"},"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":"da-DK","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-modularisering med 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","description":"I den anden episode af vores Ruby on Rails-modularisering med Packwerk ser vi n\u00e6rmere p\u00e5 begrebet applikation som en pakke.","breadcrumb":{"@id":"https:\/\/thecodest.co\/blog\/ruby-on-rails-modularization-with-packwerk-episode-ii\/#breadcrumb"},"inLanguage":"da-DK","potentialAction":[{"@type":"ReadAction","target":["https:\/\/thecodest.co\/blog\/ruby-on-rails-modularization-with-packwerk-episode-ii\/"]}]},{"@type":"ImageObject","inLanguage":"da-DK","@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":"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":"da-DK"},{"@type":"Organization","@id":"https:\/\/thecodest.co\/#organization","name":"Codest","url":"https:\/\/thecodest.co\/","logo":{"@type":"ImageObject","inLanguage":"da-DK","@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":"da-DK","@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\/da\/author\/thecodest\/"}]}},"_links":{"self":[{"href":"https:\/\/thecodest.co\/da\/wp-json\/wp\/v2\/posts\/3566","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/thecodest.co\/da\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/thecodest.co\/da\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/thecodest.co\/da\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/thecodest.co\/da\/wp-json\/wp\/v2\/comments?post=3566"}],"version-history":[{"count":10,"href":"https:\/\/thecodest.co\/da\/wp-json\/wp\/v2\/posts\/3566\/revisions"}],"predecessor-version":[{"id":7983,"href":"https:\/\/thecodest.co\/da\/wp-json\/wp\/v2\/posts\/3566\/revisions\/7983"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/thecodest.co\/da\/wp-json\/wp\/v2\/media\/3567"}],"wp:attachment":[{"href":"https:\/\/thecodest.co\/da\/wp-json\/wp\/v2\/media?parent=3566"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/thecodest.co\/da\/wp-json\/wp\/v2\/categories?post=3566"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/thecodest.co\/da\/wp-json\/wp\/v2\/tags?post=3566"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}