{"id":1782,"date":"2014-04-13T19:58:38","date_gmt":"2014-04-13T22:58:38","guid":{"rendered":"https:\/\/devkico.itexto.com.br\/?p=1782"},"modified":"2014-04-13T20:02:06","modified_gmt":"2014-04-13T23:02:06","slug":"modularizando-javascript-spring-mvc-jawr","status":"publish","type":"post","link":"https:\/\/devkico.itexto.com.br\/?p=1782","title":{"rendered":"Modularizando JavaScript com Spring MVC e Jawr"},"content":{"rendered":"<p><img loading=\"lazy\" decoding=\"async\" class=\"alignright  wp-image-1783\" alt=\"javascript-logo\" src=\"https:\/\/devkico.itexto.com.br\/wp-content\/uploads\/2014\/04\/javascript-logo.png\" width=\"210\" height=\"210\" srcset=\"https:\/\/devkico.itexto.com.br\/wp-content\/uploads\/2014\/04\/javascript-logo.png 300w, https:\/\/devkico.itexto.com.br\/wp-content\/uploads\/2014\/04\/javascript-logo-150x150.png 150w\" sizes=\"(max-width: 210px) 100vw, 210px\" \/>Este post inicia uma s\u00e9rie na qual vou expor t\u00e9cnicas que visam aumentar a manutenibilidade de c\u00f3digo Javascript. Convenhamos: \u00e9 uma linguagem de programa\u00e7\u00e3o legal, por\u00e9m muitas vezes o hype que a envolve nos impede de ver seus aspectos negativos. Neste post tratarei de uma das cicatrizes da linguagem que \u00e9 a dificuldade que enfrentamos na modulariza\u00e7\u00e3o do c\u00f3digo.<\/p>\n<h2>O problema: modularizar JavaScript usando Spring MVC<\/h2>\n<p>Se voc\u00ea tem a sorte de trabalhar com Grails tem \u00e0 sua disposi\u00e7\u00e3o uma solu\u00e7\u00e3o maravilhosa que \u00e9 o plugin <a href=\"http:\/\/grails-plugins.github.io\/grails-resources\/\">resources<\/a>\u00a0que nos permite definir &#8220;m\u00f3dulos Javascript&#8221;. Infelizmente do lado Spring da cerca n\u00e3o temos algo t\u00e3o popular. O que \u00e9 um m\u00f3dulo Javascript?<\/p>\n<blockquote><p>Uma unidade de c\u00f3digo que funciona em conjunto.<\/p><\/blockquote>\n<p>Muitas vezes esta unidade n\u00e3o \u00e9 apenas um arquivo, mas v\u00e1rios, e \u00e9 neste ponto que o problema come\u00e7a a se manifestar. Imagine um m\u00f3dulo composto por dois arquivos:\u00a0<em>biblioteca.js<\/em> e\u00a0<em>biblioteca2.js<\/em>. Sua equipe pode ter achado interessante dividi-lo em dois arquivos para paralelizar o esfor\u00e7o e com isto evitar todos aqueles inc\u00f4modos relacionados ao merge de arquivos. Nesta situa\u00e7\u00e3o, toda vez que voc\u00ea precisa usar este m\u00f3dulo, ir\u00e1 inserir em suas p\u00e1ginas c\u00f3digo similar ao exposto a seguir:<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n\r\n&lt;script type=&quot;text\/javascript&quot; src=&quot;\/resources\/js\/biblioteca.js&quot;&gt;&lt;\/script&gt;\r\n&lt;script type=&quot;text\/javascript&quot; src=&quot;\/resources\/js\/biblioteca2.js&quot;&gt;&lt;\/script&gt;\r\n\r\n<\/pre>\n<p>Ou ent\u00e3o voc\u00ea poderia ter algum script que unisse os dois arquivos. O problema \u00e9 que seria necess\u00e1rio modificar o seu processo de build e tamb\u00e9m fornecer garantias de que o arquivo gerado fosse sempre o mais atualizado poss\u00edvel (n\u00e3o \u00e9 uma solu\u00e7\u00e3o t\u00e3\u00e3o bacana assim).<\/p>\n<p>Agora, voltemos ao nosso exemplo. Imagine que este nosso m\u00f3dulo dependa do jQuery. Neste caso ter\u00edamos sempre de escrever o seguinte c\u00f3digo em nossas p\u00e1ginas:<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n\r\n&lt;!-- jQuery sempre ir\u00e1 ser carregado primeiro --&gt;\r\n&lt;script type=&quot;text\/javascript&quot; src=&quot;\/resources\/js\/jQuery.js&quot;&gt;&lt;\/script&gt;\r\n&lt;script type=&quot;text\/javascript&quot; src=&quot;\/resources\/js\/biblioteca.js&quot;&gt;&lt;\/script&gt;\r\n&lt;\/span&gt;&lt;script type=&quot;text\/javascript&quot; src=&quot;\/resources\/js\/biblioteca2.js&quot;&gt;&lt;\/script&gt;\r\n\r\n<\/pre>\n<p>Ainda pior: imagine que a ordem de carregamento dos arquivos\u00a0<em>biblioteca.js<\/em> e\u00a0<em>biblioteca2.js<\/em> seja importante. Agora sua equipe precisa ser informada a respeito. Se for uma aplica\u00e7\u00e3o de uma \u00fanica p\u00e1gina, n\u00e3o ser\u00e1 l\u00e1 um grande problema, mas imagine uma aplica\u00e7\u00e3o maior, com mais de um template, etc. A coisa come\u00e7a a se complicar.<\/p>\n<p>A imagem a seguir exp\u00f5e bem a situa\u00e7\u00e3o do nosso projeto. Temos uma biblioteca composta por dois arquivos que depende de uma terceira:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/devkico.itexto.com.br\/wp-content\/uploads\/2014\/04\/jawr_dependencias-263x300.png\" alt=\"jawr_dependencias\" width=\"263\" height=\"300\" class=\"aligncenter size-medium wp-image-1786\" srcset=\"https:\/\/devkico.itexto.com.br\/wp-content\/uploads\/2014\/04\/jawr_dependencias-263x300.png 263w, https:\/\/devkico.itexto.com.br\/wp-content\/uploads\/2014\/04\/jawr_dependencias.png 322w\" sizes=\"(max-width: 263px) 100vw, 263px\" \/><\/p>\n<p>N\u00e3o seria bacana se houvesse uma ferramenta que nos permitisse resolver os problemas a seguir de uma forma simples?<\/p>\n<ul>\n<li>Documentar as depend\u00eancias entre os nossos arquivos Javascript de tal forma que seja f\u00e1cil para a equipe entender a organiza\u00e7\u00e3o interna do projeto.<\/li>\n<li>Garantir que os arquivos sejam sempre carregados na ordem correta.<\/li>\n<li>De alguma maneira otimizar o modo como estes arquivos s\u00e3o enviados ao browser: compress\u00e3o via gzip, talvez at\u00e9 mesmo um merge dos arquivos.<\/li>\n<\/ul>\n<h2>Jawr entra em cena<\/h2>\n<p><a href=\"http:\/\/jawr.java.net\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/devkico.itexto.com.br\/wp-content\/uploads\/2014\/04\/logoJawr-300x52.png\" alt=\"logoJawr\" width=\"300\" height=\"52\" class=\"aligncenter size-medium wp-image-1788\" srcset=\"https:\/\/devkico.itexto.com.br\/wp-content\/uploads\/2014\/04\/logoJawr-300x52.png 300w, https:\/\/devkico.itexto.com.br\/wp-content\/uploads\/2014\/04\/logoJawr.png 465w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<p><a href=\"http:\/\/jawr.java.net\">Jawr<\/a> \u00e9 uma ferramenta que tem como objetivo resolver os tr\u00eas problemas que expus acima e mais alguns. Neste post irei tratar de uma parte bem pequena deste projeto: aquela que lida com Javascript. A grosso modo Jawr \u00e9 um servlet que iremos inserir em nosso projeto fict\u00edcio. Este servlet organizar\u00e1 nossos m\u00f3dulos Javascript em <strong>bundles<\/strong>.<\/p>\n<p>O que \u00e9 um <strong>bundle<\/strong>? \u00c9 um m\u00f3dulo, tal como expus acima. Mais do que isto, um bundle alguns atributos fundamentais do nosso m\u00f3dulo:<\/p>\n<ul>\n<li>Que arquivos comp\u00f5em o nosso m\u00f3dulo<\/li>\n<li>Em que ordem estes arquivos devem ser carregados<\/li>\n<li>Quais as depend\u00eancias do nosso bundle, isto \u00e9, que c\u00f3digo este precisa para funcionar?<\/li>\n<\/ul>\n<p>Voltando ao nosso projeto percebe-se que h\u00e1 dois bundles: biblioteca e jQuery, que podemos representar gr\u00e1ficamente tal como na imagem a seguir:<\/p>\n<figure id=\"attachment_1791\" aria-describedby=\"caption-attachment-1791\" style=\"width: 300px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/devkico.itexto.com.br\/wp-content\/uploads\/2014\/04\/bundles_projeto-300x114.png\" alt=\"Nossos bundles\" width=\"300\" height=\"114\" class=\"size-medium wp-image-1791\" srcset=\"https:\/\/devkico.itexto.com.br\/wp-content\/uploads\/2014\/04\/bundles_projeto-300x114.png 300w, https:\/\/devkico.itexto.com.br\/wp-content\/uploads\/2014\/04\/bundles_projeto.png 345w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><figcaption id=\"caption-attachment-1791\" class=\"wp-caption-text\">Nossos bundles<\/figcaption><\/figure>\n<p>Poder\u00edamos pensar em um bundle \u00fanico composto pelos nossos arquivos da biblioteca e o do jQuery. O problema \u00e9 que sabemos que jQuery ser\u00e1 usado por diversos outros pontos da nossa aplica\u00e7\u00e3o: sendo assim \u00e9 interessante que modularizemos esta parte a fim de que seja reaproveitada em outras partes do projeto.<\/p>\n<h3>Incluindo Jawr em nosso projeto<\/h3>\n<p>Nosso projeto \u00e9 baseado em Maven. Sendo assim, para incluirmos o Jawr basta adicionar a depend\u00eancia no arquivo <strong>pom.xml<\/strong> tal como no exemplo a seguir:<\/p>\n<pre class=\"brush: xml; title: ; notranslate\" title=\"\">\r\n&lt;dependency&gt;\r\n    &lt;groupId&gt;net.jawr&lt;\/groupId&gt;\r\n    &lt;artifactId&gt;jawr&lt;\/artifactId&gt;\r\n    &lt;version&gt;3.3.3&lt;\/version&gt;\r\n&lt;\/dependency&gt;\r\n<\/pre>\n<p>Como disse logo acima, Jawr \u00e9 essencialmente um servlet. Sendo assim temos tamb\u00e9m de alterar o arquivo <strong>web.xml<\/strong> para que fique similar ao exposto a seguir:<\/p>\n<pre class=\"brush: xml; title: ; notranslate\" title=\"\">\r\n&lt;!-- Servlet para lidar com Javascript --&gt;\r\n&lt;servlet&gt;\r\n   &lt;servlet-name&gt;JavascriptServlet&lt;\/servlet-name&gt;\r\n   &lt;servlet-class&gt;net.jawr.web.servlet.JawrServlet&lt;\/servlet-class&gt;\r\n\r\n\t\t&lt;!-- Aonde se encontra o arquivo de configuracao --&gt;\r\n   &lt;init-param&gt;\r\n       &lt;param-name&gt;configLocation&lt;\/param-name&gt;\r\n       &lt;param-value&gt;\/jawrJavascript.properties&lt;\/param-value&gt;\r\n   &lt;\/init-param&gt;\r\n   &lt;init-param&gt;\r\n       &lt;param-name&gt;mapping&lt;\/param-name&gt;\r\n       &lt;param-value&gt;\/bundle\/js\/&lt;\/param-value&gt;\r\n   &lt;\/init-param&gt;\r\n   &lt;load-on-startup&gt;1&lt;\/load-on-startup&gt;\r\n&lt;\/servlet&gt;\r\n&lt;!-- O mapeamento de URL --&gt;\t\r\n&lt;servlet-mapping&gt;\r\n   &lt;servlet-name&gt;JavascriptServlet&lt;\/servlet-name&gt;\r\n   &lt;url-pattern&gt;\/bundle\/js\/*&lt;\/url-pattern&gt;\r\n&lt;\/servlet-mapping&gt;\r\n<\/pre>\n<p><strong>Preste muita aten\u00e7\u00e3o no mapeamento de URL.<\/strong> Na documenta\u00e7\u00e3o oficial do Jawr este \u00e9 configurado para que lide com todos os recursos que terminem com a extens\u00e3o .js. O problema com esta abordagem \u00e9 que muitas vezes n\u00e3o queremos que todos os nossos arquivos Javascript sejam carregados como bundles. Talvez voc\u00ea queira ir adotando aos poucos a ferramenta em seu projeto (esta \u00e9 a principal raz\u00e3o que vejo). Em nosso caso, Jawr s\u00f3 ir\u00e1 lidar com aqueles recursos Javascript que se encontrem na url \/bundle\/js\/*. Nota importante: repare no parametro de inicializa\u00e7\u00e3o <strong>mapping<\/strong>. Se for usar uma configura\u00e7\u00e3o como esta, este obrigat\u00f3riamente deve estar definido.<\/p>\n<h3>Configurando os bundles<\/h3>\n<p>No mapeamento do servlet foi inclu\u00eddo um par\u00e2metro chamado <strong>configLocation<\/strong>. Em nosso projeto baseado em Maven este arquivo se encontra em \/src\/main\/resources\/jawrJavascript.properties. \u00c9 neste arquivo que iremos definir todos os nossos bundles. Abaixo est\u00e1 um exemplo deste arquivo:<\/p>\n<p># Altere aqui caso esteja no seu ambiente de desenvolvimento<br \/>\njawr.debug.on=false<\/p>\n<p># Devemos enviar os bundles compactados?<br \/>\njawr.gzip.on=true<\/p>\n<p># De quantos em quantos segundos o servlet deve verificar se as configuracoes foram<br \/>\n# alteradas. Extreammente util em tempo de desenvolvimento!<br \/>\njawr.config.reload.interval=30<\/p>\n<p># Primeiro bundle de exemplo: jQuery<br \/>\n# O identificador do bundle sempre \u00e9 o que aparece antes do &#8216;.id&#8217;<br \/>\n# neste caso, \u00e9 jquery<br \/>\njawr.js.bundle.jquery.id=\/bundle\/js\/jQuery.js<br \/>\njawr.js.bundle.jquery.mappings=\/resources\/js\/jquery-2.1.0.min.js<\/p>\n<p># Incluindo uma dependencia<br \/>\njawr.js.bundle.biblioteca.id=\/bundle\/js\/biblioteca.js<br \/>\njawr.js.bundle.biblioteca.mappings=\/resources\/js\/biblioteca.js, \/resources\/js\/biblioteca2.js<br \/>\njawr.js.bundle.biblioteca.dependencies=jquery<\/p>\n<p>Um bundle Javascript \u00e9 definido no arquivo com o prefixo jawr.js.bundle.[identificador do bundle]. A primeira linha, que termina com <strong>.id<\/strong> define como ser\u00e1 a URL que define o nosso bundle. O bundle jQuery, por exemplo, sempre ser\u00e1 carregado quando a URL \/bundle\/js\/jQuery.js for acionada, enquanto o bundle biblioteca, pela URL \/bundle\/js\/biblioteca.js.<\/p>\n<p>Voltemos nossa aten\u00e7\u00e3o para o bundle <strong>biblioteca<\/strong>. A segunda linha da sua defini\u00e7\u00e3o (mappings), define quais os arquivos que o comp\u00f5e e a ordem na qual devem ser carregados. A terceira linha define quais as suas depend\u00eancias. Neste caso, apenas uma: o bundle jquery.<\/p>\n<p>Tendo feito isto temos todos os bundles em nosso projeto prontos para serem usados. O pr\u00f3ximo passo \u00e9 trabalhar no arquivo JSP.<\/p>\n<h3>Alterando o arquivo JSP<\/h3>\n<p>O projeto Jawr vem com uma biblioteca de tags bastante \u00fatil. Abaixo podemos ver um exemplo de sua aplica\u00e7\u00e3o:<\/p>\n<p>&lt;%&#8211; A declara\u00e7\u00e3o da biblioteca de tags &#8211;%&gt;<br \/>\n&lt;%@ taglib uri=&quot;http:\/\/jawr.net\/tags&quot; prefix=&quot;jwr&quot; %&gt;<\/p>\n<p>&lt;%&#8211; Carregando o bundle biblioteca &#8211;%&gt;<br \/>\n&lt;jwr:script src=&quot;\/bundle\/js\/biblioteca.js&quot;\/&gt;<\/p>\n<p>E o que ocorre quando carrego a p\u00e1gina? Obtenho o resultado a seguir:<\/p>\n<pre class=\"brush: xml; title: ; notranslate\" title=\"\">\r\n&lt;script type=&quot;text\/javascript&quot; src=&quot;\/itexto\/bundle\/js\/gzip_N1063700552\/bundle\/js\/jQuery.js&quot; &gt;&lt;\/script&gt;\r\n&lt;script type=&quot;text\/javascript&quot; src=&quot;\/itexto\/bundle\/js\/gzip_N745101183\/bundle\/js\/biblioteca.js&quot; &gt;&lt;\/script&gt;\r\n<\/pre>\n<p>Primeiro ser\u00e1 inserida a depend\u00eancia do bundle biblioteca e, em seguida, o c\u00f3digo fonte do bundle biblioteca. Repare nas URLs: o Jawr ir\u00e1 autom\u00e1ticamente cachear os recursos Javascript. E sabem o que \u00e9 mais legal? Ele tamb\u00e9m envia o Javascript comprimido (se o modo de depura\u00e7\u00e3o estiver desativado (veja as notas no arquivo que expus acima)). E n\u00e3o \u00e9 s\u00f3 o conte\u00fado Javascript comprimido. Os dois arquivos que comp\u00f5em o m\u00f3dulo biblioteca tamb\u00e9m s\u00e3o mesclados em um s\u00f3, diminuindo assim o n\u00famero de requisi\u00e7\u00f5es necess\u00e1rias. Simples assim. :)<\/p>\n<h2>Concluindo<\/h2>\n<p>Nese post apresentei uma pequena parte do projeto Jawr. H\u00e1 mais neste servlet, que tamb\u00e9m pode ser usado para gerenciar recursos CSS e imagens. \u00c9 importante salienar que a documenta\u00e7\u00e3o do projeto \u00e9 <strong>excelente<\/strong>: bem escrita e f\u00e1cil de ser consultada. <\/p>\n<p>Claro que a quest\u00e3o da modulariza\u00e7\u00e3o n\u00e3o termina aqui. Esta \u00e9 apenas uma das solu\u00e7\u00f5es poss\u00edveis. Recentemente topei com um ebook online (e gratuito) chamado <a href=\"http:\/\/addyosmani.com\/writing-modular-js\/\">Writing Modular JavaScript with AMD, CommonJS &#038; ES Harmony<\/a> que trata da quest\u00e3o de uma forma muito mais profunda. Entra a\u00ed tamb\u00e9m o modo como escrevemos JavaScript (que n\u00e3o tratei neste post) e alguns outros pontos sobre os quais pretendo escrever mais a respeito em um futuro pr\u00f3ximo.<\/p>\n<p>O c\u00f3digo fonte deste post pode ser acessado no meu GitHub:<a href=\"https:\/\/github.com\/loboweissmann\/jawr-testes\"> https:\/\/github.com\/loboweissmann\/jawr-testes<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Como modularizar JavaScript em um projeto Spring MVC usando o excelente projeto Jawr.<\/p>\n","protected":false},"author":1,"featured_media":1788,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_coblocks_attr":"","_coblocks_dimensions":"","_coblocks_responsive_height":"","_coblocks_accordion_ie_support":"","site-sidebar-layout":"default","site-content-layout":"","ast-site-content-layout":"","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"default","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-gradient":""}},"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[36,61,62,59],"tags":[],"class_list":["post-1782","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-desenvolvimento-de-software","category-javascript","category-spring","category-spring-framework"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v22.8 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Modularizando JavaScript com Spring MVC e Jawr - \/dev\/Kico<\/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:\/\/devkico.itexto.com.br\/?p=1782\" \/>\n<meta property=\"og:locale\" content=\"pt_BR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Modularizando JavaScript com Spring MVC e Jawr - \/dev\/Kico\" \/>\n<meta property=\"og:description\" content=\"Como modularizar JavaScript em um projeto Spring MVC usando o excelente projeto Jawr.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/devkico.itexto.com.br\/?p=1782\" \/>\n<meta property=\"og:site_name\" content=\"\/dev\/Kico\" \/>\n<meta property=\"article:published_time\" content=\"2014-04-13T22:58:38+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2014-04-13T23:02:06+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/devkico.itexto.com.br\/wp-content\/uploads\/2014\/04\/logoJawr.png\" \/>\n\t<meta property=\"og:image:width\" content=\"465\" \/>\n\t<meta property=\"og:image:height\" content=\"82\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Kico (Henrique Lobo Weissmann)\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@loboweissmann\" \/>\n<meta name=\"twitter:label1\" content=\"Escrito por\" \/>\n\t<meta name=\"twitter:data1\" content=\"Kico (Henrique Lobo Weissmann)\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. tempo de leitura\" \/>\n\t<meta name=\"twitter:data2\" content=\"9 minutos\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/devkico.itexto.com.br\/?p=1782\",\"url\":\"https:\/\/devkico.itexto.com.br\/?p=1782\",\"name\":\"Modularizando JavaScript com Spring MVC e Jawr - \/dev\/Kico\",\"isPartOf\":{\"@id\":\"https:\/\/devkico.itexto.com.br\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/devkico.itexto.com.br\/?p=1782#primaryimage\"},\"image\":{\"@id\":\"https:\/\/devkico.itexto.com.br\/?p=1782#primaryimage\"},\"thumbnailUrl\":\"https:\/\/devkico.itexto.com.br\/wp-content\/uploads\/2014\/04\/logoJawr.png\",\"datePublished\":\"2014-04-13T22:58:38+00:00\",\"dateModified\":\"2014-04-13T23:02:06+00:00\",\"author\":{\"@id\":\"https:\/\/devkico.itexto.com.br\/#\/schema\/person\/502ab8892631bb005d6da2269fe5a3a7\"},\"breadcrumb\":{\"@id\":\"https:\/\/devkico.itexto.com.br\/?p=1782#breadcrumb\"},\"inLanguage\":\"pt-BR\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/devkico.itexto.com.br\/?p=1782\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"pt-BR\",\"@id\":\"https:\/\/devkico.itexto.com.br\/?p=1782#primaryimage\",\"url\":\"https:\/\/devkico.itexto.com.br\/wp-content\/uploads\/2014\/04\/logoJawr.png\",\"contentUrl\":\"https:\/\/devkico.itexto.com.br\/wp-content\/uploads\/2014\/04\/logoJawr.png\",\"width\":465,\"height\":82},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/devkico.itexto.com.br\/?p=1782#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/devkico.itexto.com.br\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Modularizando JavaScript com Spring MVC e Jawr\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/devkico.itexto.com.br\/#website\",\"url\":\"https:\/\/devkico.itexto.com.br\/\",\"name\":\"\/dev\/Kico\",\"description\":\"Desenvolvendo software\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/devkico.itexto.com.br\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"pt-BR\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/devkico.itexto.com.br\/#\/schema\/person\/502ab8892631bb005d6da2269fe5a3a7\",\"name\":\"Kico (Henrique Lobo Weissmann)\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"pt-BR\",\"@id\":\"https:\/\/devkico.itexto.com.br\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/dd6973d86a689bc63122b2e603f25be3?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/dd6973d86a689bc63122b2e603f25be3?s=96&d=mm&r=g\",\"caption\":\"Kico (Henrique Lobo Weissmann)\"},\"sameAs\":[\"https:\/\/x.com\/loboweissmann\"],\"url\":\"https:\/\/devkico.itexto.com.br\/?author=1\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Modularizando JavaScript com Spring MVC e Jawr - \/dev\/Kico","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:\/\/devkico.itexto.com.br\/?p=1782","og_locale":"pt_BR","og_type":"article","og_title":"Modularizando JavaScript com Spring MVC e Jawr - \/dev\/Kico","og_description":"Como modularizar JavaScript em um projeto Spring MVC usando o excelente projeto Jawr.","og_url":"https:\/\/devkico.itexto.com.br\/?p=1782","og_site_name":"\/dev\/Kico","article_published_time":"2014-04-13T22:58:38+00:00","article_modified_time":"2014-04-13T23:02:06+00:00","og_image":[{"width":465,"height":82,"url":"https:\/\/devkico.itexto.com.br\/wp-content\/uploads\/2014\/04\/logoJawr.png","type":"image\/png"}],"author":"Kico (Henrique Lobo Weissmann)","twitter_card":"summary_large_image","twitter_creator":"@loboweissmann","twitter_misc":{"Escrito por":"Kico (Henrique Lobo Weissmann)","Est. tempo de leitura":"9 minutos"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/devkico.itexto.com.br\/?p=1782","url":"https:\/\/devkico.itexto.com.br\/?p=1782","name":"Modularizando JavaScript com Spring MVC e Jawr - \/dev\/Kico","isPartOf":{"@id":"https:\/\/devkico.itexto.com.br\/#website"},"primaryImageOfPage":{"@id":"https:\/\/devkico.itexto.com.br\/?p=1782#primaryimage"},"image":{"@id":"https:\/\/devkico.itexto.com.br\/?p=1782#primaryimage"},"thumbnailUrl":"https:\/\/devkico.itexto.com.br\/wp-content\/uploads\/2014\/04\/logoJawr.png","datePublished":"2014-04-13T22:58:38+00:00","dateModified":"2014-04-13T23:02:06+00:00","author":{"@id":"https:\/\/devkico.itexto.com.br\/#\/schema\/person\/502ab8892631bb005d6da2269fe5a3a7"},"breadcrumb":{"@id":"https:\/\/devkico.itexto.com.br\/?p=1782#breadcrumb"},"inLanguage":"pt-BR","potentialAction":[{"@type":"ReadAction","target":["https:\/\/devkico.itexto.com.br\/?p=1782"]}]},{"@type":"ImageObject","inLanguage":"pt-BR","@id":"https:\/\/devkico.itexto.com.br\/?p=1782#primaryimage","url":"https:\/\/devkico.itexto.com.br\/wp-content\/uploads\/2014\/04\/logoJawr.png","contentUrl":"https:\/\/devkico.itexto.com.br\/wp-content\/uploads\/2014\/04\/logoJawr.png","width":465,"height":82},{"@type":"BreadcrumbList","@id":"https:\/\/devkico.itexto.com.br\/?p=1782#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/devkico.itexto.com.br\/"},{"@type":"ListItem","position":2,"name":"Modularizando JavaScript com Spring MVC e Jawr"}]},{"@type":"WebSite","@id":"https:\/\/devkico.itexto.com.br\/#website","url":"https:\/\/devkico.itexto.com.br\/","name":"\/dev\/Kico","description":"Desenvolvendo software","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/devkico.itexto.com.br\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"pt-BR"},{"@type":"Person","@id":"https:\/\/devkico.itexto.com.br\/#\/schema\/person\/502ab8892631bb005d6da2269fe5a3a7","name":"Kico (Henrique Lobo Weissmann)","image":{"@type":"ImageObject","inLanguage":"pt-BR","@id":"https:\/\/devkico.itexto.com.br\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/dd6973d86a689bc63122b2e603f25be3?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/dd6973d86a689bc63122b2e603f25be3?s=96&d=mm&r=g","caption":"Kico (Henrique Lobo Weissmann)"},"sameAs":["https:\/\/x.com\/loboweissmann"],"url":"https:\/\/devkico.itexto.com.br\/?author=1"}]}},"jetpack_featured_media_url":"https:\/\/devkico.itexto.com.br\/wp-content\/uploads\/2014\/04\/logoJawr.png","jetpack-related-posts":[],"jetpack_sharing_enabled":true,"jetpack_likes_enabled":true,"_links":{"self":[{"href":"https:\/\/devkico.itexto.com.br\/index.php?rest_route=\/wp\/v2\/posts\/1782"}],"collection":[{"href":"https:\/\/devkico.itexto.com.br\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devkico.itexto.com.br\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devkico.itexto.com.br\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/devkico.itexto.com.br\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1782"}],"version-history":[{"count":10,"href":"https:\/\/devkico.itexto.com.br\/index.php?rest_route=\/wp\/v2\/posts\/1782\/revisions"}],"predecessor-version":[{"id":1797,"href":"https:\/\/devkico.itexto.com.br\/index.php?rest_route=\/wp\/v2\/posts\/1782\/revisions\/1797"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devkico.itexto.com.br\/index.php?rest_route=\/wp\/v2\/media\/1788"}],"wp:attachment":[{"href":"https:\/\/devkico.itexto.com.br\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1782"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devkico.itexto.com.br\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1782"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devkico.itexto.com.br\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1782"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}