<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Fernando Alvarez</title>
    <description>The latest articles on DEV Community by Fernando Alvarez (@fernalvarez590).</description>
    <link>https://dev.to/fernalvarez590</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2082%2F0f49c625-d79b-4f47-ad8c-fec0f97120cc.jpg</url>
      <title>DEV Community: Fernando Alvarez</title>
      <link>https://dev.to/fernalvarez590</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/fernalvarez590"/>
    <language>en</language>
    <item>
      <title>Hype Driven Development — How teams can avoid this</title>
      <dc:creator>Fernando Alvarez</dc:creator>
      <pubDate>Tue, 27 Aug 2019 12:26:44 +0000</pubDate>
      <link>https://dev.to/fernalvarez590/hype-driven-development-how-teams-can-avoid-this-2o90</link>
      <guid>https://dev.to/fernalvarez590/hype-driven-development-how-teams-can-avoid-this-2o90</guid>
      <description>&lt;h3&gt;
  
  
  Hype Driven Development — How teams can avoid this
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F720%2F0%2AjYYCqnl6a-NZqSfZ.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F720%2F0%2AjYYCqnl6a-NZqSfZ.jpg" alt="Image that writes HYPE"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Introduction
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Let’s imagine for a bit&lt;/strong&gt; that you are in a development team doing software products or services, you have a very rock-solid planned platform, the team is doing well with the tools provided for your product specs, everything seems to be fine with the world.&lt;/p&gt;

&lt;p&gt;One day, surfing the net, you notice that a &lt;strong&gt;new tool&lt;/strong&gt; is released and is well received by the open source / framework community and, dare I say, is praised by everyone. Amazed by this, you read the documentation to learn how to use it, you tested it and, by the end of the day, you fall in love with this. Since your love for this new shiny tool is quite strong, you search a way or another to implement it in your project. You talk with your managers and leads about this and you convince them to use it. At the end of the month, the tool is implemented in your product and for now everything seems to be working.&lt;/p&gt;

&lt;p&gt;Some time later, the team started to add more features on top of the tool that you suggested but you noticed a struggle in your team to have the features implemented, more bugs than before, taking more time to develop a feature, lots of “hacks” to get things done with the tool and etc. After some chitchat with your team and the leads, you come to the conclusion that adding this tool was not the best decision since it started to hurt the development cycle and, somehow, started to hurt the business. You and the team remove this tool and you have a lesson learned.&lt;/p&gt;

&lt;p&gt;After reading this story… does it feel quite familiar to you? This topic is something what I like to call &lt;strong&gt;Hype Driven Development.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  What is Hype Driven Development (HDD)?
&lt;/h3&gt;

&lt;p&gt;I like to call it like this when you try to push a new tool / framework and then make decisions in your development team of including it without thinking of tradeoffs, technical debt, development and business implications.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why is it harmful in development teams?
&lt;/h3&gt;

&lt;p&gt;If you read the introduction, you may noticed a couple of problems that &lt;strong&gt;HDD&lt;/strong&gt; can introduce to your teams but I want to be more explicit on this.&lt;/p&gt;

&lt;p&gt;One of the problems that &lt;strong&gt;HDD&lt;/strong&gt; causes in your team is a decrease in the speed of your development teams. The reason behind this is that your team needs time to understand the new introduced tool and how to use it in the project and that learning curve can cause some delays when delivering a new feature (sometimes this may no apply) but on top of that, when the tool it’s fully implemented in the product, it may take time for all the devs how to build a feature on top of this and if it was a bad decision, your team will struggle more on that.&lt;/p&gt;

&lt;p&gt;A bad decision cause by &lt;strong&gt;HDD&lt;/strong&gt; can cause you more problems that solutions. Instead of going &lt;em&gt;smoothly&lt;/em&gt; you may have more bugs introduced in your system and more delicate parts that will require your attention.&lt;/p&gt;

&lt;p&gt;A bad decision caused by &lt;strong&gt;HDD&lt;/strong&gt; can cause a waste of time. Sounds harsh but it’s the truth. If a decision wasn’t made in a smart way, you will waste time implementing it, maintaining it but also removing it.&lt;/p&gt;

&lt;h3&gt;
  
  
  How can I avoid this in my team?
&lt;/h3&gt;

&lt;p&gt;In the company I work, I’m leading a team where we are building an internal product / platform and we faced this kind of behaviour in the team. I’ll tell you a couple of techniques that helped me to understand better the &lt;em&gt;hype&lt;/em&gt; from the devs and &lt;em&gt;probably&lt;/em&gt; avoid it (&lt;em&gt;or fell for it&lt;/em&gt;).&lt;/p&gt;

&lt;h4&gt;
  
  
  Ask for info and if it’s not enough ask again
&lt;/h4&gt;

&lt;p&gt;This one is the most useful to me. Always try to ask for why, how and what… &lt;em&gt;Why is it important for the business? why would it be useful for the team? why do you think it provides value? how much is gonna impact the team to implement this? what are the implications of use this?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Try to always look for the answer that will make more sense for the team and the business that actually provide a useful benefit. Don’t fall in answers like “&lt;em&gt;F*ck it, let’s do it”, “this might be useful in the future”, “let’s implement it and see what happens”.&lt;/em&gt; Try to prove that the hype is worth it by doing a small PoC and see how it works, &lt;strong&gt;never ever&lt;/strong&gt; try to use a new tool without knowing possible results.&lt;/p&gt;

&lt;h4&gt;
  
  
  Gather Feedback
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;Don’t listen to one person only&lt;/strong&gt;. Try to be informed and try to understand, as much as possible, the hype of this. Maybe from other colleagues, the internet, Reddit, stack overflow, GitHub… You won’t know if the proposed tool will really add value to your business if you don’t listen to other people.&lt;/p&gt;

&lt;h4&gt;
  
  
  Software Design Decisions made by the team must not be taken lightly
&lt;/h4&gt;

&lt;p&gt;One of the main focuses of your software design / architecture should be the ability to adapt to the change. However, when it comes on changes, I believe it &lt;strong&gt;must&lt;/strong&gt; be an informed one and should taken with care. You and the team &lt;strong&gt;must&lt;/strong&gt; be extremely cautious when you decide when to use a tool / framework in your platform since, again, will potentially impact the way everyone works, the and (possibly) how the business works; and how I mention mentioned before, a PoC will help you to understand all the possible implications of using a new tool. The usage of a tool / framework in conditions where is not the right one is &lt;strong&gt;absolutely worse&lt;/strong&gt; than not having it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusions
&lt;/h3&gt;

&lt;p&gt;At the end, i’m not trying to encourage you to be afraid of changes. &lt;strong&gt;Every&lt;/strong&gt; software engineer &lt;strong&gt;must&lt;/strong&gt; embrace changes. I’m encouraging you to be more informed and cautious when it comes to this.&lt;/p&gt;

&lt;p&gt;Every time that you will use a new tool / framework, always think if it’s going to provide value to the team, the client, the product, the business, productivity, etc. Try to make smarter decisions and don’t fall in the hype, you may regret it later.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/NNfY091jDRs"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;If you really liked this post, consider doing a small donation to buy me a coffee. I love coffee! 🙂 ☕ &lt;a href="https://www.buymeacoffee.com/fern" rel="noopener noreferrer"&gt;https://www.buymeacoffee.com/fern&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F170%2F0%2AbKAIjSnoXGRrMkR5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F170%2F0%2AbKAIjSnoXGRrMkR5.png" alt="Buy me a coffee button"&gt;&lt;/a&gt;&lt;strong&gt;🙌 Thanks for Reading 🙌&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>software</category>
      <category>softwaredevelopment</category>
      <category>agile</category>
    </item>
    <item>
      <title>Dependency Injection Made Easy for VueJS and Vuex with TypeScript</title>
      <dc:creator>Fernando Alvarez</dc:creator>
      <pubDate>Sun, 26 May 2019 16:52:37 +0000</pubDate>
      <link>https://dev.to/fernalvarez590/dependency-injection-made-easy-for-vuejs-and-vuex-with-typescript-556m</link>
      <guid>https://dev.to/fernalvarez590/dependency-injection-made-easy-for-vuejs-and-vuex-with-typescript-556m</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6yI6XR43--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/0%2A38yIPuEG7RKUFi-v" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6yI6XR43--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/0%2A38yIPuEG7RKUFi-v" alt=""&gt;&lt;/a&gt;Image by @mriverodorta&lt;/p&gt;

&lt;p&gt;I have to admit it &lt;em&gt;(and this is my personal point of view)&lt;/em&gt;. Dependency Injection is not popular in the VueJS Ecosystem and, dare I say, in the JS ecosystem. People want to get stuff done quickly and nicely and that is absolutely fine but I feel that most of the SOLID and OOP principles are lost in the JS ecosystem but let’s talk about that in another post 😛&lt;/p&gt;




&lt;p&gt;To understand Dependency Injection and its benefits, I &lt;strong&gt;absolutely&lt;/strong&gt; recommend you to read this post first:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://medium.freecodecamp.org/a-quick-intro-to-dependency-injection-what-it-is-and-when-to-use-it-7578c84fa88f"&gt;A quick intro to Dependency Injection: what it is, and when to use it&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;Dependency Injection &lt;strong&gt;was&lt;/strong&gt; kind of hard to implement in a VueJS application since it required to do a couple of tweaks to the codebase. One of the DI (Dependency Injection) solutions for JS and TS out there is &lt;a href="http://inversify.io/"&gt;InversifyJS&lt;/a&gt; which is my favorite DI container but still hard to use with VueJS. Fortunately, that is no more and one person give us, which is to me, &lt;strong&gt;the solution&lt;/strong&gt; to implementing DI in our VueJS Apps.&lt;/p&gt;

&lt;p&gt;In this guide/practice, I want you to learn about how to implement Dependency Injection easily into your VueJS project with TypeScript using the library &lt;a href="https://github.com/CKGrafico/inversify-props"&gt;Inversify Props&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/CKGrafico/inversify-props"&gt;CKGrafico/inversify-props&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--HflZDX5S--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/498/0%2A92p2JN9TLqFNWpzw" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HflZDX5S--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/498/0%2A92p2JN9TLqFNWpzw" alt=""&gt;&lt;/a&gt;Game Of Thrones (HBO)&lt;/p&gt;

&lt;h3&gt;
  
  
  Complete Example
&lt;/h3&gt;

&lt;p&gt;If you want to take a look into the complete example, you can go directly to this link!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/jefer590/vuejsdepencyinjectionexample/tree/03/use-dependency-injection-inside-vuex-module"&gt;jefer590/vuejsdepencyinjectionexample&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  What do I need?
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Install the latest version of &lt;a href="https://yarnpkg.com/"&gt;&lt;strong&gt;yarn&lt;/strong&gt;&lt;/a&gt; and&lt;a href="https://cli.vuejs.org/"&gt;&lt;strong&gt;Vue CLI&lt;/strong&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;An editor compatible with TypeScript (I love &lt;a href="https://www.jetbrains.com/webstorm/"&gt;WebStorm&lt;/a&gt; for this)&lt;/li&gt;
&lt;li&gt;Clone the base repo for the exercise.&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  What are we building?
&lt;/h4&gt;

&lt;p&gt;A super simple app that:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;First, will use a service that connects to &lt;a href="https://api.kanye.rest/"&gt;https://api.kanye.rest&lt;/a&gt; through a component&lt;/li&gt;
&lt;li&gt;Then, the same behaviour but through a Vuex Module&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Getting Ready
&lt;/h3&gt;

&lt;p&gt;Clone the next repo in your machine:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/jefer590/vuejsdepencyinjectionexample/tree/master"&gt;jefer590/vuejsdepencyinjectionexample&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;and then instal the dependencies using&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ yarn install
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Creating the Service
&lt;/h3&gt;

&lt;p&gt;In the /src folder, create a new folder folder called services and inside the new folder, create a folder called impl&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The /services root will be used to expose easily the Service Interfaces&lt;/li&gt;
&lt;li&gt;/services/impl will be used to add the concrete implementations of our interfaces/services&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In the /services folder create the file IKanyeWestService.ts with this shape:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;We return a promise since we will retrieve the quote from an external service.&lt;/p&gt;

&lt;p&gt;It’s time to do the concrete implementation! Create a file called KanyeWestService.ts in the /services/impl folder. It should have this shape:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;In this class service, what basically does is a &lt;em&gt;wrapper&lt;/em&gt; of our axios HTTP call which will return the object data that corresponds to the quote. You might ask:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Why didn’t you do the http request inside the required component?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The answer is easy! It’s easier to maintain. By creating a decoupled service from our codebase and injecting it in the whole codebase, let us have our code in only and only one place. If for some reason the library changes in the future (maybe they change from HTTP to Protobufs) we need to only do the change in one place and will take effect basically in every part where the dependency is injected. We will be using the abstraction over the concrete implementation.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Dependency Container
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Create the Container
&lt;/h4&gt;

&lt;p&gt;In the /src folder, create a file called app.container.ts which will be the file where we are going to register all of the dependencies with its abstractions. the file should look like this:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h4&gt;
  
  
  Register Dependencies
&lt;/h4&gt;

&lt;p&gt;Let’s bind our dependencies!&lt;/p&gt;

&lt;p&gt;In the same file, import container from inversify-props and both files that we did for the KanyeWest service. Inside of the function we will use container to register our service in this way:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;To this to take effect in our codebase, in the main.ts you will import the function from app.container and use it inside the loadDependencyContainer&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h3&gt;
  
  
  Injecting a service into a VueJS Component
&lt;/h3&gt;

&lt;p&gt;Our dependency container ir ready! Now it’s time to use it inside a Vue Component.&lt;/p&gt;

&lt;p&gt;Go to to /App.vue and start by importing the IKanyeWestService and then a decorator from inversify-props called Inject&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;And to inject this service, just simply add this piece of code in your Component class:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;and… That’s it! It literally take a few lines of code to use a dependency by using DI with this library. The only things left are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fetch the quote when you click the button.&lt;/li&gt;
&lt;li&gt;Fetch the quote when the component is loaded.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To tackle both cases, in the method getQuote use the injected dependency and set the quote text into the data which is called quote&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;and to execute this when the component is loaded, just put it in the mounted hook method. At the end, your &lt;em&gt;script&lt;/em&gt; should look like this:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Now that we have a fully functional component with an injected dependency, we can do the same for Vuex using vuex-class and vuex-module-decorators&lt;/p&gt;

&lt;h4&gt;
  
  
  Use Vuex in App.vue
&lt;/h4&gt;

&lt;p&gt;Let’s first remove the content of the method getQuote, remove the injected dependency from the class and then remove the imports associated to the injected dependency.&lt;/p&gt;

&lt;p&gt;Now import the &lt;strong&gt;Action&lt;/strong&gt; and &lt;strong&gt;Getter&lt;/strong&gt; decorators from vuex-class and use Getter above the quote data to bind it to the quote getter in the store:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;For the Action, since we are binding functions, we will need to match the function type in the next way:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;And use it inside the getQuote method. The component &lt;strong&gt;script&lt;/strong&gt; should look like this:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h4&gt;
  
  
  DI inside a Vuex class module
&lt;/h4&gt;

&lt;p&gt;The last part of this guide is doing DI in a Vuex module using vuex-module-decorators and inversify-props which is as easy as the component approach and, dare I say, the same code.&lt;/p&gt;

&lt;p&gt;go to /store/modules/KanyeWest.ts and import the same inject and Interface service that we used in the component into this file&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;And using the same approach as the component, Inject the dependency:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;and that’s pretty much it! Let’s us it in our fetchKanyeQuote action:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;And &lt;em&gt;voila!&lt;/em&gt; Our project is finished and using DI!&lt;/p&gt;

&lt;p&gt;And that’s it for today! I hope you learned a little bit about Dependency Injection on VueJS and TypeScript. Feedback is welcomed!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.buymeacoffee.com/fern"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--49bZwE0c--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/170/1%2Abk_C8Um34KavCkO2yzMCZg.png" alt=""&gt;&lt;/a&gt;&lt;strong&gt;🙌 Thanks for Reading 🙌&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>vue</category>
      <category>typescript</category>
      <category>dependencyinjection</category>
      <category>vuex</category>
    </item>
    <item>
      <title>Nuxt.js Debugging for WebStorm</title>
      <dc:creator>Fernando Alvarez</dc:creator>
      <pubDate>Sat, 30 Mar 2019 15:56:44 +0000</pubDate>
      <link>https://dev.to/fernalvarez590/nuxt-js-debugging-for-webstorm-365a</link>
      <guid>https://dev.to/fernalvarez590/nuxt-js-debugging-for-webstorm-365a</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj7ik9t4zzujij43uad0i.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj7ik9t4zzujij43uad0i.jpg" width="500" height="320"&gt;&lt;/a&gt;The very first recorded computer bug (&lt;a href="https://thenextweb.com/shareables/2013/09/18/the-very-first-computer-bug/" rel="noopener noreferrer"&gt;The Next Web&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;Did you ever try to debug a problem using only console logs? did your head hurt before and after this? did it take a long time to find out it was a missing property in an object? Let’s face it… almost everyone had to recur to this method, including myself.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;console.log is not and will not ever be a silver bullet for debugging&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Debuggers are tools that have been between us for years but for some reason people stop to use them in the NodeJS world. Our friends from NodeJS, VSCode and Jetbrains have created a plenty of tools that help us to “stop” the application and get the current state of the application in that moment in time.&lt;/p&gt;

&lt;p&gt;NuxtJS, in the other hand, have been a &lt;strong&gt;pain in the ass&lt;/strong&gt; to try to get the debugger up and running, has been so hard to figured out that people tend to just drop the race and start to use console.log.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkt27objub3g50rksf785.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkt27objub3g50rksf785.gif" width="480" height="264"&gt;&lt;/a&gt;Everyone trying to get NuxtJS debugger running, including myself&lt;/p&gt;

&lt;p&gt;Well, fear not my friend! I actually have a quick, safe and nice solution for all your problems! Actually, NuxtJS debugging is easier than everyone think and I want you to know this since there’s almost NO documentation of the subject and want to make your life easier.&lt;/p&gt;

&lt;h3&gt;
  
  
  Project Config
&lt;/h3&gt;

&lt;p&gt;Open your nuxt.config.js and go to the build property because we are going to modify the extend method.&lt;/p&gt;

&lt;p&gt;We need only add &lt;strong&gt;one line&lt;/strong&gt; of code but is extremely meaningful to enable debugging:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;What does this line mean to us?&lt;/p&gt;

&lt;p&gt;config.devtool is a property of Webpack that let us configure how the SourceMap for that JS should be generated (&lt;a href="https://webpack.js.org/configuration/devtool/" rel="noopener noreferrer"&gt;Reference&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;eval-source-map is a SourceMap that matchers exactly to the line number and this help us to debug in the client. (&lt;a href="https://webpack.js.org/configuration/devtool/#development" rel="noopener noreferrer"&gt;More Info&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;inline-source-map is very similar to the last one but with the exception that is added as &lt;strong&gt;DataUrl&lt;/strong&gt; in the bundle. It help us to debug our NuxtJS app in the server. (&lt;a href="https://webpack.js.org/configuration/devtool/#special-cases" rel="noopener noreferrer"&gt;More Info&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: Try adding a development environment validation. It’s not recommended to use this on production.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Running the NodeJS Debugger with nodemon
&lt;/h3&gt;

&lt;p&gt;We will use an excellent tool for development called &lt;a href="https://nodemon.io/" rel="noopener noreferrer"&gt;&lt;strong&gt;nodemon&lt;/strong&gt;&lt;/a&gt; which basically let us watch any change in our project and restart the server &lt;em&gt;automagically&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;To run the NodeJS debugger with &lt;em&gt;nodemon&lt;/em&gt; just add the flag --inspector and that’s it!!&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h3&gt;
  
  
  WebStorm
&lt;/h3&gt;

&lt;p&gt;Open your project with WebStorm and wait for everything to be indexed.&lt;/p&gt;

&lt;h4&gt;
  
  
  Configure Server Side Debugging
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;Click on “Add Configuration”&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgef8qv27nmyss6jo4umd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgef8qv27nmyss6jo4umd.png" width="800" height="296"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Click in the &lt;em&gt;plus&lt;/em&gt; sign and then in npm&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb7d2l0oslcx2js1vqya5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb7d2l0oslcx2js1vqya5.png" width="800" height="514"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;In &lt;em&gt;command&lt;/em&gt; use run and in &lt;em&gt;scripts&lt;/em&gt; use dev and save!&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcp2u4i9svxhfu5008xiv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcp2u4i9svxhfu5008xiv.png" width="800" height="527"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Configure Client Side Debugging
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;Go to the same &lt;em&gt;Add Configuration&lt;/em&gt; place&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgef8qv27nmyss6jo4umd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgef8qv27nmyss6jo4umd.png" width="800" height="296"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Click the &lt;em&gt;plus&lt;/em&gt; sign and click in &lt;em&gt;Javascript Debug&lt;/em&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fea77fjuw58kmft6yomfd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fea77fjuw58kmft6yomfd.png" width="800" height="506"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Put a name to this; URL should be the URL where Nuxt will run, browser can be your favorite one but i’d recommend to use Chrome and enable the option of “Ensure breakpoints are detected when loading scripts” and save!&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F52mpfq3cr59vjnox71ec.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F52mpfq3cr59vjnox71ec.png" width="800" height="517"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  How to get both running
&lt;/h4&gt;

&lt;p&gt;First run the Server Side Debugger by having the run option selected and then running the &lt;em&gt;bug&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F39sgjqxohjoixoo3u6e5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F39sgjqxohjoixoo3u6e5.png" width="800" height="556"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After the project loads correctly, select the client side run config and click the same icon. It should open a new chrome instance.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frqd3oatc34l6mvo58asd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frqd3oatc34l6mvo58asd.png" width="800" height="315"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And we are absolutely ready to debug our application! 🎉&lt;/p&gt;

&lt;h4&gt;
  
  
  Demo Video!
&lt;/h4&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/-zqknOA25-o"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Have a great hunt, Bug Hunter! May this article were of your help in your job!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvoehm0afxgpgiq7pe9m4.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvoehm0afxgpgiq7pe9m4.jpg" width="800" height="533"&gt;&lt;/a&gt;The Hunter from Bloodborne (From Software)&lt;/p&gt;

&lt;h3&gt;
  
  
  🙌 Thanks fo reading! 🙌
&lt;/h3&gt;

</description>
      <category>javascript</category>
      <category>nuxt</category>
      <category>tips</category>
      <category>debugging</category>
    </item>
    <item>
      <title>Level Up your VueJS project with Typescript (Part 3): Vuex</title>
      <dc:creator>Fernando Alvarez</dc:creator>
      <pubDate>Mon, 14 Jan 2019 13:30:25 +0000</pubDate>
      <link>https://dev.to/fernalvarez590/level-up-your-vuejs-project-with-typescript-part-3-vuex-2nba</link>
      <guid>https://dev.to/fernalvarez590/level-up-your-vuejs-project-with-typescript-part-3-vuex-2nba</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--bn_RKY7Z--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2Aq6_LObOAS5FVdt8TXGLIOQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--bn_RKY7Z--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2Aq6_LObOAS5FVdt8TXGLIOQ.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  If you missed part 2, go to this post:
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://medium.com/@fernalvarez/level-up-your-vuejs-project-with-typescript-part-2-translating-components-to-typescript-3719092c7b5f"&gt;Level Up your VueJS project with Typescript (Part 2): Translating Components to Typescript&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For the complete version of this part, use this branch of the project repo:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/jefer590/upgrade-vuejs-ts-series/tree/05/vuex-ts-usage"&gt;jefer590/upgrade-vuejs-ts-series&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In part 3, we translated most of our components to use Typescript using the vue-property-decorator with the exception of the View that use &lt;strong&gt;Vuex&lt;/strong&gt;. In this part, we will translate our Vuex Modules and the Store.vue that uses the module. Let’s get started!&lt;/p&gt;

&lt;h3&gt;
  
  
  The Foo Vuex Module
&lt;/h3&gt;

&lt;p&gt;If you noticed, the project already has a Vuex Module called Foo in the path ~/src/store/foo.ts. Go to that file because we are going to modify it.&lt;/p&gt;

&lt;p&gt;Let’s take a look what’s &lt;em&gt;“inside”&lt;/em&gt; of this simple module. The module contains a state called text which initializes a simple text string; contains a mutation to set a new text into that state; a getter to get the text string but in upper case and last the module is namespaced so, to access to this, we will need to use Foo/textUpper if we need the getter for example.&lt;/p&gt;

&lt;p&gt;Taking all of this into account, let’s remove all the content of this file because we will rewrite the whole file in Typescript but doing the same actions and preserving the same state. For that we will use the library (installed in part 1):&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/championswimmer/vuex-module-decorators"&gt;championswimmer/vuex-module-decorators&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Translating the Foo Vuex Module into Typescript
&lt;/h3&gt;

&lt;p&gt;We will start by importing the necessary decorators and classes that we will use in the *&lt;em&gt;Foo *&lt;/em&gt; Module:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { VuexModule, Module, Mutation } from 'vuex-module-decorators'
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;In the “traditional” way, we return an object literal that contains all the states, mutations, etc; to satisfy our requirements. For this approach, we need to return a class that extends of VuexModule and the name of the class needs to be the name of the module which in this case is Foo&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;The only thing left to let know to Vuex that this file/class is a Module and is namespaced is use the @Module decorator at the beginning of the class and we will pass metadata to the decorator to let know this class is, in fact, namespaced:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Our &lt;strong&gt;Foo&lt;/strong&gt; Module looks good but the state, mutation and getter are missing. Time to work!&lt;/p&gt;

&lt;p&gt;To add a state to the module we will simply add a class property that needs to be public and the name of the property needs to be text and we will initialize it with the same string text as the &lt;em&gt;“traditional”&lt;/em&gt; way:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;For the mutation, we will do a class method that uses the @Mutation decorator. The name of the mutation will be defined by the name of the class method. The parameters of the class method mutation will only be the required ones to mutate the state. There’s only one catch here and is, to access to the state of this module, you will need to use this for example: this.text&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;And last, to create a Vuex getter, you need to define a class getter like computed properties in the Vue Component class. The name of the class getter will be the name of the Vuex getter.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://medium.com/media/3ae7397c9f1eadd6dfd47ae0cd07fe56/href"&gt;&lt;/a&gt;&lt;a href="https://medium.com/media/3ae7397c9f1eadd6dfd47ae0cd07fe56/href"&gt;https://medium.com/media/3ae7397c9f1eadd6dfd47ae0cd07fe56/href&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And that’s it! if you test the project with yarn serve and see that the Store View is still working that means that the Vuex store module is using our TS implementation of it successfully 🎉&lt;/p&gt;

&lt;h3&gt;
  
  
  Translating Store View to Typescript
&lt;/h3&gt;

&lt;p&gt;We go to ~/src/views/Store.vue and take all the  part into another file because we will delete the current script content. We will define a class component following the same pattern as part 2:&amp;lt;/p&amp;gt;

&amp;lt;iframe src="" width="0" height="0" frameborder="0" scrolling="no"&amp;gt;&amp;lt;a href="https://medium.com/media/e54690ed663e61c2aa1475dc6868e83d/href"&amp;gt;https://medium.com/media/e54690ed663e61c2aa1475dc6868e83d/href&amp;lt;/a&amp;gt;&amp;lt;/iframe&amp;gt;

&amp;lt;p&amp;gt;To create the Vuex bindings, we will use a library that I really like called vuex-class this will let us to create the bindings of our Vuex store using Decorators (already installed in part 1).&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;&amp;lt;a href="https://github.com/ktsn/vuex-class"&amp;gt;ktsn/vuex-class&amp;lt;/a&amp;gt;&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;In this component, we need to bind the state text, the mutation setText and the getter textUpper into it. Let’s begin!&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;Since our Vuex state is inside a namespaced module, we need to create the binding for that namespace. First import:&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;&amp;lt;/p&amp;gt;
&amp;lt;div class="highlight"&amp;gt;&amp;lt;pre class="highlight plaintext"&amp;gt;&amp;lt;code&amp;gt;import { namespace } from 'vuex-class'
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;p&amp;gt;&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;Then, we will create a constant &amp;lt;strong&amp;gt;outside the class&amp;lt;/strong&amp;gt; that will have the Decorators of our namespace. Using namespace as a method, you need to pass, as a parameter, the name of your namespaced vuex module so we will pass the name &amp;lt;em&amp;gt;“Foo”&amp;lt;/em&amp;gt; as follows:&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;&amp;lt;/p&amp;gt;
&amp;lt;div class="highlight"&amp;gt;&amp;lt;pre class="highlight plaintext"&amp;gt;&amp;lt;code&amp;gt;const fooModule = namespace('Foo') 
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;p&amp;gt;&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;Our script of that component should look like this:&amp;lt;/p&amp;gt;

&amp;lt;iframe src="" width="0" height="0" frameborder="0" scrolling="no"&amp;gt;&amp;lt;a href="https://medium.com/media/6f691ac0645ef94906f91f4d1ca58aab/href"&amp;gt;https://medium.com/media/6f691ac0645ef94906f91f4d1ca58aab/href&amp;lt;/a&amp;gt;&amp;lt;/iframe&amp;gt;

&amp;lt;p&amp;gt;Great! time for bindings! Our first candidate is the text state. To use the namespaced state, we will use the const fooModule as decorator and the state will be a class property with the same name as the state and taking into account the proper types used in the module:&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;&amp;lt;/p&amp;gt;
&amp;lt;div class="highlight"&amp;gt;&amp;lt;pre class="highlight plaintext"&amp;gt;&amp;lt;code&amp;gt;@fooModule.State
private text!: string
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;p&amp;gt;&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;Our script should look like this:&amp;lt;/p&amp;gt;

&amp;lt;iframe src="" width="0" height="0" frameborder="0" scrolling="no"&amp;gt;&amp;lt;a href="https://medium.com/media/dad0e29ab8218c3d903c4b9cec188667/href"&amp;gt;https://medium.com/media/dad0e29ab8218c3d903c4b9cec188667/href&amp;lt;/a&amp;gt;&amp;lt;/iframe&amp;gt;

&amp;lt;p&amp;gt;Now it’s time to bind the getter. For that, we will follow the same pattern as the state:&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;&amp;lt;/p&amp;gt;
&amp;lt;div class="highlight"&amp;gt;&amp;lt;pre class="highlight plaintext"&amp;gt;&amp;lt;code&amp;gt;@fooModule.Getter
private textUpper!: string
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;p&amp;gt;&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;Our script should look like this:&amp;lt;/p&amp;gt;

&amp;lt;iframe src="" width="0" height="0" frameborder="0" scrolling="no"&amp;gt;&amp;lt;a href="https://medium.com/media/30282cd455a3d0083dc72de46fa373c7/href"&amp;gt;https://medium.com/media/30282cd455a3d0083dc72de46fa373c7/href&amp;lt;/a&amp;gt;&amp;lt;/iframe&amp;gt;

&amp;lt;p&amp;gt;Last but not least, it’s time to bind the mutation. We will follow the same pattern as the getter and the state BUT with a little catch in the type. The type &amp;lt;strong&amp;gt;must&amp;lt;/strong&amp;gt; match the method input and output types. Fortunately, Typescript let us do this to our variables:&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;&amp;lt;/p&amp;gt;
&amp;lt;div class="highlight"&amp;gt;&amp;lt;pre class="highlight plaintext"&amp;gt;&amp;lt;code&amp;gt;@fooModule.Mutation
private setText!: (_newText_: string) =&amp;amp;gt; void
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;p&amp;gt;&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;In this case, we are telling to the typescript compiler that this property is a method and will receive a string but it won’t return nothing by using void. After adding this, the scriptshould look like this:&amp;lt;/p&amp;gt;

&amp;lt;iframe src="" width="0" height="0" frameborder="0" scrolling="no"&amp;gt;&amp;lt;a href="https://medium.com/media/0620325c94725092402b7280d8762317/href"&amp;gt;https://medium.com/media/0620325c94725092402b7280d8762317/href&amp;lt;/a&amp;gt;&amp;lt;/iframe&amp;gt;

&amp;lt;p&amp;gt;We are almost done! The only missing thing here is a method used in the input’s @input event method called changeText that will pass the event param with the new value and will use the mutation to change the state of text :&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;&amp;lt;/p&amp;gt;
&amp;lt;div class="highlight"&amp;gt;&amp;lt;pre class="highlight plaintext"&amp;gt;&amp;lt;code&amp;gt;changeText (event: _any_): _void_ {
_this_.setText(event.target.value)
}
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;p&amp;gt;&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;The script now should look like this:&amp;lt;/p&amp;gt;

&amp;lt;iframe src="" width="0" height="0" frameborder="0" scrolling="no"&amp;gt;&amp;lt;a href="https://medium.com/media/7ca1d98d2114fc18b3759d32d3f0dbec/href"&amp;gt;https://medium.com/media/7ca1d98d2114fc18b3759d32d3f0dbec/href&amp;lt;/a&amp;gt;&amp;lt;/iframe&amp;gt;

&amp;lt;p&amp;gt;And that’s it! If we run our project with yarn serve and check again the Store view, everything should still working as expected!&amp;lt;/p&amp;gt;
&amp;lt;h4&amp;gt;
  &amp;lt;a name="thats-all-for-part-3-stay-tuned-for-part-four-where-we-are-going-to-create-a-new-endpoint-api-in-express-using-typescript-but-also-we-are-going-to-create-a-new-view-that-will-use-that-endpoint" href="#thats-all-for-part-3-stay-tuned-for-part-four-where-we-are-going-to-create-a-new-endpoint-api-in-express-using-typescript-but-also-we-are-going-to-create-a-new-view-that-will-use-that-endpoint" class="anchor"&amp;gt;
  &amp;lt;/a&amp;gt;
  That’s all for part 3! Stay tuned for part four where we are going to create a new endpoint API in Express using Typescript but also we are going to create a new view that will use that endpoint.
&amp;lt;/h4&amp;gt;
&amp;lt;h3&amp;gt;
  &amp;lt;a name="thanks-for-reading" href="#thanks-for-reading" class="anchor"&amp;gt;
  &amp;lt;/a&amp;gt;
  🙌 Thanks for reading! 🙌
&amp;lt;/h3&amp;gt;
&lt;/p&gt;

</description>
      <category>vue</category>
      <category>typescript</category>
      <category>frontenddev</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Level Up your VueJS project with Typescript (Part 2): Translating Components to Typescript</title>
      <dc:creator>Fernando Alvarez</dc:creator>
      <pubDate>Mon, 07 Jan 2019 13:31:00 +0000</pubDate>
      <link>https://dev.to/fernalvarez590/level-up-your-vuejs-project-with-typescript-part-2-translating-components-to-typescript-3b64</link>
      <guid>https://dev.to/fernalvarez590/level-up-your-vuejs-project-with-typescript-part-2-translating-components-to-typescript-3b64</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--hbxel0_7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2ANO1PE-ic3ILCVHqeVHn1SQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hbxel0_7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2ANO1PE-ic3ILCVHqeVHn1SQ.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  If you missed part 1, go to this post:
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://dev.to/lordferquad/level-up-your-vuejs-project-with-typescript-part-1-installing-typescript-3f7l"&gt;Level Up your VueJS project with Typescript (Part 1): Installing Typescript&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For the completed version of this part, use this branch of the project repo:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/jefer590/upgrade-vuejs-ts-series/tree/03/translate-components-to-ts"&gt;jefer590/upgrade-vuejs-ts-series&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In part 1, we prepared our project to use Typescript and was only installation + configuration. For many of you that part could be considered the “boring” part and I understand it! To compensate that, in this part we will translate almost all our VueJS Files (Home View+Components) to use Typescript! So let’s begin.&lt;/p&gt;

&lt;h3&gt;
  
  
  Translating the “Hello.vue” Component — Single File Component
&lt;/h3&gt;

&lt;p&gt;For this component, we are going to replace only the &amp;lt;script&amp;gt; part with TS, the HTML template doesn’t need any modifications (one advantage of using SFC 🙌).&lt;/p&gt;

&lt;p&gt;When we open this file we noticed that the file is very simple:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The component data is only a variable called text with a string&lt;/li&gt;
&lt;li&gt;There’s only one computed property called textUpper that uses text&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Try to remember this because we are going to delete all the script part of that component and we will rewrite it using TS starting with:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;You will noticed that we added a lang="ts". This means that we are telling to Vue Loader the script inside this SFC will be compiled/transpiled using Typescript.&lt;/p&gt;

&lt;p&gt;After that, we will use a library that I absolutely love for VueJS TS development called vue-property-decorator that is already included in the project&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/kaorun343/vue-property-decorator"&gt;kaorun343/vue-property-decorator&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And using that library, &lt;strong&gt;we will start to use this pattern for every component that we will make with TS&lt;/strong&gt;&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Now you may ask, &lt;em&gt;“what does this even mean?”&lt;/em&gt; let me explain it quickly:&lt;/p&gt;

&lt;p&gt;@Component is using a feature in &lt;a href="https://www.typescriptlang.org/docs/handbook/decorators.html"&gt;TS called Decorators&lt;/a&gt; and in this context will pass some metadata of the component to the class. The metadata is basically all the properties that are available in the VueJS Component like data , methods , components , mixins , etc…&lt;/p&gt;

&lt;p&gt;In export default class Hello Extends Vue we are doing almost the same as the traditional way that is exporting the VueJS component object but we have TWO main differences:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The class name will be also the name of the component&lt;/li&gt;
&lt;li&gt;Since this is Typescript, we need the VueJS object to be inherited to have the types available and also to tell to VueJS that this is a component object.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To declare the textdata or any kind of data in your VueJS component, create simple a class property and initialize it with the “Hello” string:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;private text: string = 'string'
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;this line is pretty much the same as:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;and to create the textUpper computed method, &lt;a href="https://www.typescriptlang.org/docs/handbook/classes.html#accessors"&gt;we need to create a “getter”&lt;/a&gt;inside our component class&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;which, in the traditional way, translates to:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;After that, our “Hello.vue” Component should look like this:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;If you run the project with these changes you will notice that everything is working as expected.&lt;/p&gt;

&lt;h3&gt;
  
  
  Translating the “World.jsx” Component — TSX Component
&lt;/h3&gt;

&lt;p&gt;For this file, the first thing we need to do is rename it to use the .tsx file extension. If you are running the project, the hot reloading will fail because the compiler is not accepting how this file is done. Let’s translate this!&lt;/p&gt;

&lt;p&gt;First, copy all the content of the file and put it somewhere else because we are going to totally rewrite the World.tsx file. After you clean the file, we will declare our Component class in the same way as the Hello.vue file:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Let’s do the same as the Hello.vue with the data and computed property!&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Since this is a TSX file, a render function will be needed. To type that function, the parameter of h needs to use the Vue.CreateElement Interface and the render function needs to return Vue.VNode which translates to the “HTML” returned in that function:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;This is a good amount of code to check if everything is working. After trying, it will appear an error like this:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;To fix this, in the Home.vue view, change the import of World.jsx to use TSX instead. After that, the project should run fine with the only problem that our text is not updating. Since this is TSX/JSX we need to attach the events manually. To fix that, we need to add a method to the on-input event of our input and create a class method that changes the value of text to use the passed text.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;After this change, the text mutation should work fine!&lt;/p&gt;

&lt;h3&gt;
  
  
  Translating the “Home.vue” View
&lt;/h3&gt;

&lt;p&gt;The only thing left to update for now is the Home.vue file. Go to the file, copy the component imports and delete the script part. We will follow next the same pattern to create a class component but adding the component imports:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;And to attach the Hello and World components, we will use the @Component decorator by passing an object with the components key as if it were a traditional VueJS object:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;After save, the project should start to work properly again.&lt;/p&gt;

&lt;h4&gt;
  
  
  That all for part 2 friends! Stay tuned for part three where we are going to translate the Vuex module to use Typescript and also how to use it inside a Typescript Class Component!
&lt;/h4&gt;

&lt;h3&gt;
  
  
  🙌 Thanks for reading! 🙌
&lt;/h3&gt;

</description>
      <category>tutorial</category>
      <category>frontenddev</category>
      <category>vue</category>
      <category>frontend</category>
    </item>
    <item>
      <title>Level Up your VueJS project with Typescript (Part 1): Installing Typescript</title>
      <dc:creator>Fernando Alvarez</dc:creator>
      <pubDate>Wed, 02 Jan 2019 13:58:01 +0000</pubDate>
      <link>https://dev.to/fernalvarez590/level-up-your-vuejs-project-with-typescript-part-1-installing-typescript-3f7l</link>
      <guid>https://dev.to/fernalvarez590/level-up-your-vuejs-project-with-typescript-part-1-installing-typescript-3f7l</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--APlG_F05--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1024/1%2ASvERD1zJKQ70hbOq8nRTGw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--APlG_F05--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1024/1%2ASvERD1zJKQ70hbOq8nRTGw.png" alt="" width="800" height="444"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Welcome to this new series/course! The goal of this series is that we’re going to take a simple VueJS project and upgrade it to use Typescript! You may wonder, “why to use typescript in my VueJS project if I’m fine with the good old fashioned way?” The answer is simple. There are sometimes that our project can get bigger than we expected and creating new features or a simple refactor could scare us. This is because, most of the time, we don’t have any idea if something else gets broken or how many files need to change to put our feature/refactor in place.&lt;/p&gt;

&lt;h3&gt;
  
  
  Requirements
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/jefer590/upgrade-vuejs-ts-series"&gt;Clone this project on Github&lt;/a&gt; and checkout the master branch.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://nodejs.org/en/"&gt;NodeJS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://yarnpkg.com"&gt;yarn&lt;/a&gt; package manager.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://cli.vuejs.org/"&gt;Vue CLI 3&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Editor/IDE like VSCode or Webstorm.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  How is the project currently working?
&lt;/h3&gt;

&lt;p&gt;The project is quite simple:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We have a view with two components that basically do the same but one is done with the Single File Component Pattern (SFC for short) and the other one is using JSX.&lt;/li&gt;
&lt;li&gt;The other view is just a component linked to a state and a getter in the foo store. It have a textbox that let us mutate the state in “real time” and see the changes right away.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We will add another view in a later part but for now this is a pretty good example.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is the goal at the end of this series?
&lt;/h3&gt;

&lt;p&gt;At the end of this series:&lt;/p&gt;

&lt;h4&gt;
  
  
  The Project:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Should have all their components migrated to Typescript.&lt;/li&gt;
&lt;li&gt;Vuex Store should be also migrated to Typescript.&lt;/li&gt;
&lt;li&gt;Typescript in Express should be in place also.&lt;/li&gt;
&lt;li&gt;Dependency Injection / IoC Container implemented.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  And you will learn:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Little bit of TS.&lt;/li&gt;
&lt;li&gt;How to implement a VueJS Component using TS.&lt;/li&gt;
&lt;li&gt;How to install TS in your current VueJS project.&lt;/li&gt;
&lt;li&gt;How to use Express with TS.&lt;/li&gt;
&lt;li&gt;How to implement Dependency Injection / IoC Containers.&lt;/li&gt;
&lt;li&gt;How to create a vuex store with TS.&lt;/li&gt;
&lt;li&gt;How to use Vuex within a component in the TS way.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you want to see the completed project, click down here👇!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/jefer590/upgrade-vuejs-ts-series/tree/08/dependency-injection"&gt;jefer590/upgrade-vuejs-ts-series&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--wJAX_VGE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://cdn-images-1.medium.com/max/490/0%2AkGf2l17k0nTrl9U9.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--wJAX_VGE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://cdn-images-1.medium.com/max/490/0%2AkGf2l17k0nTrl9U9.gif" alt="" width="490" height="291"&gt;&lt;/a&gt;Mulan by Disney&lt;/p&gt;

&lt;h3&gt;
  
  
  Installing Typescript
&lt;/h3&gt;

&lt;p&gt;The first thing that you need to do is clone the repository mentioned above in your machine using git&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ git clone [git@github.com](mailto:git@github.com):jefer590/upgrade-vuejs-ts-series.git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;After that, we just install the project packages using yarn and then we check if our project is working as intended&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ yarn install
$ yarn serve
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Now it comes the tricky part. To install Typescript into this project, we will use the “magic” of Vue CLI 3 by just typing the next command inside the project’s folder:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ vue add @vue/typescript
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;It’s going start to install some dependencies and then it will ask:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;? Use class-style component syntax? (Y/n)
? Use Babel alongside TypeScript for auto-detected polyfills? (Y/n)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;We say yes (Y)!&lt;/p&gt;

&lt;p&gt;And after everything is installed, that’s about it! You already have Typescript on the project! but you may noticed some weird stuff happened. Let me list:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Every .js file was renamed to use the .ts extension.&lt;/li&gt;
&lt;li&gt;Add the VueJS and TSX Shims to the project.&lt;/li&gt;
&lt;li&gt;The CLI Replaced the Home.vue and App.vue with the default ones (😱)&lt;/li&gt;
&lt;li&gt;The CLI Added the HelloWorld.vue component&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;and if you try to run the project is not going to work because the TS compiler is failing. Let’s fix all these problems!&lt;/p&gt;
&lt;h3&gt;
  
  
  Stabilizing the project
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;To recover the Home.vue and App.vue files, we only need one git command:
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ git checkout HEAD -- src/App.vue src/views/Home.vue
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;We can remove the HelloWorld.vue component&lt;/li&gt;
&lt;li&gt;Since our store started to use TS instead of JS, we need to type our store module. Go to src/store/foo.ts and&lt;a href="https://www.typescriptlang.org/docs/handbook/basic-types.html"&gt;type your function params&lt;/a&gt; in the next way:&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;After all of this, if we serve again our project should work fine without any compilation errors.&lt;/p&gt;

&lt;h3&gt;
  
  
  Installing Extra Packages
&lt;/h3&gt;

&lt;p&gt;For this series we will install a couple of tools that I, personally, love for my day by day TS development in VueJS. I’ll explain both packages in the future so don’t worry about it for now.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/ktsn/vuex-class"&gt;ktsn/vuex-class&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/championswimmer/vuex-module-decorators"&gt;championswimmer/vuex-module-decorators&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;we only need one command with yarn to install both packages.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ yarn add vuex-class vuex-module-decorators
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;and to support the vuex modules decorators we only need to add the next config almost at the end of the vue.config.js&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;transpileDependencies: ['vuex-module-decorators']
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;so, our vue.config.js should look like this:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;Let’s test our project! If we run…&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ yarn express
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and then…&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ yarn serve
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Express API and the VueJS Site should work! 🎉&lt;/p&gt;

&lt;h4&gt;
  
  
  That all for the first part folks! Stay tuned for part two where we are going to translate some components to Typescript.
&lt;/h4&gt;

&lt;h3&gt;
  
  
  🙌 Thanks for reading! 🙌
&lt;/h3&gt;

</description>
      <category>vue</category>
      <category>typescript</category>
      <category>tutorial</category>
      <category>frontend</category>
    </item>
    <item>
      <title>Documentation with Continuous Delivery Pipeline using VuePress, S3 and Buddy Works</title>
      <dc:creator>Fernando Alvarez</dc:creator>
      <pubDate>Mon, 30 Jul 2018 11:01:01 +0000</pubDate>
      <link>https://dev.to/fernalvarez590/documentation-with-continuous-delivery-pipeline-using-vuepress-s3-and-buddy-works-go7</link>
      <guid>https://dev.to/fernalvarez590/documentation-with-continuous-delivery-pipeline-using-vuepress-s3-and-buddy-works-go7</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F600%2F0%2AG6f3Yd5joymz5MzS.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F600%2F0%2AG6f3Yd5joymz5MzS.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The other day, I was told I can create a Continuous Delivery pipeline for the documentation for the project and I said yes and for this particular case we use &lt;a href="https://vuepress.vuejs.org/" rel="noopener noreferrer"&gt;VuePress&lt;/a&gt;, which is the new tool by Evan You, the creator of VueJS, to create documentation for your site. We create something simple for it but the curiosity of how can I improve the pipeline started to work and then, this article came up.&lt;/p&gt;

&lt;h3&gt;
  
  
  Prerequisites
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;An AWS Account&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://nodejs.org" rel="noopener noreferrer"&gt;NodeJS&lt;/a&gt; (Version must be ≥ 8)&lt;/li&gt;
&lt;li&gt;&lt;a href="https://yarnpkg.com/en/" rel="noopener noreferrer"&gt;Yarn&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;A &lt;a href="https://buddy.works/" rel="noopener noreferrer"&gt;Buddy Works CI/CD&lt;/a&gt; account&lt;/li&gt;
&lt;li&gt;A &lt;a href="https://github.com/" rel="noopener noreferrer"&gt;Github&lt;/a&gt; Account&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Code Ready Example
&lt;/h3&gt;

&lt;p&gt;If you just want to test the pipeline and skip the development part (doing your own documentation), you can fork this project ready for S3 deployment and start experimenting with it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/jefer590/vuepress-s3-cd-example" rel="noopener noreferrer"&gt;jefer590/vuepress-s3-cd-example&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Setup Project
&lt;/h3&gt;

&lt;p&gt;First we will need to init a new NodeJS project using yarn using the next command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ yarn init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, it’s time to install the only dependency for this project that is &lt;a href="https://vuepress.vuejs.org/" rel="noopener noreferrer"&gt;VuePress&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;$ yarn add -D vuepress&lt;/p&gt;

&lt;p&gt;After that, you must follow the &lt;a href="https://vuepress.vuejs.org/guide/getting-started.html#inside-an-existing-project" rel="noopener noreferrer"&gt;Getting Started Guide&lt;/a&gt; of VuePress. If you have it ready, let’s move on!&lt;/p&gt;

&lt;h3&gt;
  
  
  Setup Pipeline
&lt;/h3&gt;

&lt;p&gt;Create a new public or private project on Github, you can name it however you want.&lt;/p&gt;

&lt;p&gt;We need another config before jumping into Buddy Works and that is creating a programmatically user on &lt;a href="https://aws.amazon.com/iam/" rel="noopener noreferrer"&gt;AWS IAM&lt;/a&gt; that will allow Buddy Works, deploy the built assets into an S3 bucket and, obviously, an S3 bucket configured to support Static Web Pages.&lt;/p&gt;

&lt;p&gt;In the AIM dashboard, you have to go to &lt;em&gt;Users &amp;gt; Add User&lt;/em&gt; and then, in the next page, you will write the AIM username with programmatic access&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AH6VpflfqiVpmWfTlSsxpMg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AH6VpflfqiVpmWfTlSsxpMg.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the permissions screen, you will attach an existing policy. For demonstration purposes, we will use the &lt;strong&gt;&lt;em&gt;“AmazonS3FullAccess”&lt;/em&gt;&lt;/strong&gt; policy. You can create your own policy with only the necessary permissions for Buddy Works and you can check them &lt;a href="https://buddy.works/knowledge/deployments/list-of-aws-policies" rel="noopener noreferrer"&gt;in this link&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AB9A-jtXlG5gjpXslsnJy3Q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AB9A-jtXlG5gjpXslsnJy3Q.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the next screen, verify the info for your user and click on &lt;strong&gt;&lt;em&gt;“Create User”&lt;/em&gt;&lt;/strong&gt; and in the next screen you will get the Access Key ID and the Secret Access Key. save this info because you will use it later.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AbNMlW5UG5D2z8wsqgzI1vA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AbNMlW5UG5D2z8wsqgzI1vA.png"&gt;&lt;/a&gt;Our user is ready, thanks IAM!&lt;/p&gt;

&lt;p&gt;It’s time to create our S3 Bucket! go to the S3 dashboard and click in the button &lt;strong&gt;&lt;em&gt;“Create Bucket”&lt;/em&gt;&lt;/strong&gt; and a modal will appear to start creating the bucket. On the first step, add a bucket name that will be part of your domain name and select your preferred region.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AwAyBwO4Q5swqibhdctaZPg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AwAyBwO4Q5swqibhdctaZPg.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On the next step, you will add &lt;strong&gt;&lt;em&gt;“Versioning”&lt;/em&gt;&lt;/strong&gt; to the bucket. Static Web Site config comes later.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AJQb0-gc5EtOC-nfPO9EiJw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AJQb0-gc5EtOC-nfPO9EiJw.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next step, grant read access to all the users.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AKD6Zzu6P3PYg1QwO34-h_Q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AKD6Zzu6P3PYg1QwO34-h_Q.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The last step is review your options and that’s it! you have a brand new S3 bucket but only one thing is left, set up the web host for this bucket and for that, in the dashboard of your bucket, go to &lt;strong&gt;&lt;em&gt;Properties&lt;/em&gt;&lt;/strong&gt; and then click on &lt;strong&gt;&lt;em&gt;“Static Web Hosting”&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AJFO7YQdezC2JOy7Sx_QpNg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AJFO7YQdezC2JOy7Sx_QpNg.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A bunch of options will appear again, click on &lt;strong&gt;&lt;em&gt;“Use this bucket to host a website”&lt;/em&gt;&lt;/strong&gt;. On &lt;strong&gt;&lt;em&gt;Index document&lt;/em&gt;&lt;/strong&gt; you will put the value &lt;strong&gt;&lt;em&gt;“index.html”&lt;/em&gt;&lt;/strong&gt; and on &lt;strong&gt;&lt;em&gt;Error document&lt;/em&gt;&lt;/strong&gt; you will add the value &lt;strong&gt;&lt;em&gt;“404.html”&lt;/em&gt;&lt;/strong&gt;. Both files are generated by the VuePress building process. You save and that’s it! Everything is ready on AWS.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AY7EJJCDfbkv6daJe7o-okA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AY7EJJCDfbkv6daJe7o-okA.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now let’s go to the fun part, configure the pipeline! Go to your Buddy Works Projects dashboard and click on &lt;strong&gt;&lt;em&gt;“Create a new project”&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AuiIV89fDsimFnjaqTsf0dA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AuiIV89fDsimFnjaqTsf0dA.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then, a list with all your repos will appear. Search the one that you created for the VuePress Project&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2APqfZn-6hC7fZioUIek79dg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2APqfZn-6hC7fZioUIek79dg.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After you selected your project, the pipeline dashboard for that project will appear. Click on &lt;strong&gt;&lt;em&gt;“Add a new pipeline”&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2ATTQpEz_g2YwkfmUTxBa5jQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2ATTQpEz_g2YwkfmUTxBa5jQ.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the next screen, we will set how the pipeline will be triggered and which branch or tag you want it to be triggered. In my case, I’ll trigger this pipeline every push to master. You can add a target website to preview the deployed project. For this case, we will use the S3 static website url which the pattern is .s3-website-.amazonaws.com&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AVY3Fuwzel3Tzb-Ns5NY2yg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AVY3Fuwzel3Tzb-Ns5NY2yg.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After that, a screen to chose a new action for your pipeline. Since we need to build the VuePress project to upload it into our S3 bucket, we will use a node action.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2ARyAdJUGkXHvSLNBvXHECDQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2ARyAdJUGkXHvSLNBvXHECDQ.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Time to configure our task! We need yarn to build download the packages and download everything, so let’s install yarn in this action. Go to &lt;strong&gt;&lt;em&gt;“Environment Customization”&lt;/em&gt;&lt;/strong&gt; and add the next command $ npm install -g yarn and to try that yarn is installed, in the command screen, use the$ yarn -v command. Save the action and let’s run manually our task clicking in the &lt;em&gt;“Run Pipeline”&lt;/em&gt; button&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F251%2F1%2Augds9dR-L2kmUPeY90c5Gg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F251%2F1%2Augds9dR-L2kmUPeY90c5Gg.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If everything went fine, check the logs of your node action and you will see the latest yarn version&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AS3TQMn_SUhmhN4T1VZAj9g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AS3TQMn_SUhmhN4T1VZAj9g.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;All right! Yarn is ready in our pipeline, let’s add the build action into out Node Task! Use the command $ yarn and$ yarn build:docs to install dependencies and build the docs.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2A_sJRNV0qZIqbFjebKxDyTQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2A_sJRNV0qZIqbFjebKxDyTQ.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The last thing needed is set the Node Runtime to grab the latest 8 version of node from the Docker Public Hub&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AunfODlz05Gh10YkNQZPegw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AunfODlz05Gh10YkNQZPegw.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At last, we have our first action made on node!!!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AFH5IVuQ1RX3CNu1CmsL7VA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AFH5IVuQ1RX3CNu1CmsL7VA.png"&gt;&lt;/a&gt;Our brand new action is ready!&lt;/p&gt;

&lt;p&gt;The build should be good! Now let’s actually upload all our documentation into our S3 bucket. Create another action for the pipeline but this time search for a S3 action. It will ask for you S3 User Access Key ID and Secret Access Key. Use the one that you created with the S3 policy.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AchDTNQ1FlozZOUcEkPPIUw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AchDTNQ1FlozZOUcEkPPIUw.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If the integration went fine, a screen with the S3 upload config should appear. Make sure that you are using the &lt;strong&gt;&lt;em&gt;“Pipeline Filesystem”&lt;/em&gt;&lt;/strong&gt; to use the build archives in the past action and make sure that your source path is /docs/.vuepress/dist&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2A2gOqF-1wybzp1HtOt4dwRg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2A2gOqF-1wybzp1HtOt4dwRg.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Also, make sure that you will use the S3 account for this action and you will upload everything to the root of the bucket with public access. At last, set a name for your action.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AiX0g_80PeM1rj2JirrF83Q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AiX0g_80PeM1rj2JirrF83Q.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click on &lt;strong&gt;&lt;em&gt;“Add This Action”&lt;/em&gt;&lt;/strong&gt; to finish and have our second action in our pipeline&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2Ada1Z3i-uz0mUrrWsw8G3xA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2Ada1Z3i-uz0mUrrWsw8G3xA.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Everything is going well, we have a step to build and a step to upload but I think the only thing left is an action to notify me when this was deployed successfully. Let’s do that with an email by creating a new email action.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AosYTRlZl_4FwZZE5v1ngLQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AosYTRlZl_4FwZZE5v1ngLQ.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let’s add a successful message to the email that we are going to notify&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AMbWf3jUAIrWrt_Xr6yjlFQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AMbWf3jUAIrWrt_Xr6yjlFQ.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And at last, let’s add the name of the action.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AUq1KDPL7omyZjp0PNDqgfQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AUq1KDPL7omyZjp0PNDqgfQ.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Our pipeline should looks like this.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AI7coS2XTYBB-d5GiTBd-_Q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AI7coS2XTYBB-d5GiTBd-_Q.png"&gt;&lt;/a&gt;Beautiful!&lt;/p&gt;

&lt;p&gt;Now, it’s the time of truth. let’s test our new pipeline by clicking on &lt;strong&gt;Run Pipeline&lt;/strong&gt; button. If everything was successful you may see your pipeline as &lt;em&gt;completed&lt;/em&gt; and you may received an email.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2Ab9jN_kKkOQ8r3onhHKPWoQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2Ab9jN_kKkOQ8r3onhHKPWoQ.png"&gt;&lt;/a&gt;Everything went right on Buddy Works!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2A4jNmKE3ns8UtqhW-kxgcEQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2A4jNmKE3ns8UtqhW-kxgcEQ.png"&gt;&lt;/a&gt;I received the email!&lt;/p&gt;

&lt;p&gt;And, of course, our site must be online.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AUlRRw8FL8i8QunwOSvpC2w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AUlRRw8FL8i8QunwOSvpC2w.png"&gt;&lt;/a&gt;Our site works wonderfully!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AVIKak45G3d5w1CX0lucRxA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AVIKak45G3d5w1CX0lucRxA.png"&gt;&lt;/a&gt;The work done in the repo looks nice!&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;With buddy we can create CI/CD workflow so nice, so easy and so wonderful. VuePress is an excellent tool for Static Documentation because of the uses of Markdown + Vue Componentes + templates. If we keep uploading changes to this repo, the repo will trigger automatically. I suggest you to check it out!&lt;/p&gt;

&lt;h4&gt;
  
  
  🙌 Thanks for reading and see you on the next time 🙌
&lt;/h4&gt;

</description>
      <category>continuousdelivery</category>
      <category>vuepress</category>
      <category>vue</category>
      <category>s3</category>
    </item>
    <item>
      <title>Serverless-Side Rendering With AWS Lambda &amp; NuxtJS</title>
      <dc:creator>Fernando Alvarez</dc:creator>
      <pubDate>Sat, 21 Apr 2018 00:49:49 +0000</pubDate>
      <link>https://dev.to/fernalvarez590/serverless-side-rendering-with-aws-lambda--nuxtjs-4j4c</link>
      <guid>https://dev.to/fernalvarez590/serverless-side-rendering-with-aws-lambda--nuxtjs-4j4c</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AwCN74zqZqZR1ibLdBeyCBw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AwCN74zqZqZR1ibLdBeyCBw.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There are two things that I love right know:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Serverless Ecosystem like AWS Lambda&lt;/li&gt;
&lt;li&gt;The VueJS Ecosystem&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;One day, I was discussing with some folks in the office about Serverless and Lambdas in general, how to make a lambda, how to use the Serverless framework, create your own REST API, etc.&lt;/p&gt;

&lt;p&gt;After that discussion, and given that I am working with VueJS, a simple but crazy idea came up:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“What if we can provide server-side rendering Front End using AWS Lambdas instead of a Virtual Machine?”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I decided to take a look into it using NuxtJS because is my favorite tool for the job and also, &lt;a href="https://aws.amazon.com/blogs/compute/node-js-8-10-runtime-now-available-in-aws-lambda/" rel="noopener noreferrer"&gt;AWS just launched the NodeJS 8.10 runtime for AWS Lambda&lt;/a&gt;, making this a perfect moment to test this idea and the new runtime.&lt;/p&gt;

&lt;h3&gt;
  
  
  Where to find the example?
&lt;/h3&gt;

&lt;p&gt;If you want to directly jump to the final version of the code, the repo is available in github right here:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/jefer590/serverless-side-nuxtjs-example" rel="noopener noreferrer"&gt;jefer590/serverless-side-nuxtjs-example&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Prerequisites
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;An AWS Account&lt;/li&gt;
&lt;li&gt;&lt;a href="https://nodejs.org" rel="noopener noreferrer"&gt;NodeJS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://serverless.com" rel="noopener noreferrer"&gt;Serverless CLI&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://yarnpkg.com/en/" rel="noopener noreferrer"&gt;Yarn&lt;/a&gt; (You can use npm)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Setup
&lt;/h3&gt;

&lt;p&gt;First we will need to init a new NodeJS project using yarn (or using NPM) using the next command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ yarn init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Then, it’s time to install the dependencies what we will need for this project:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ yarn add aws-serverless-express axios express nuxt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;but, what are these dependencies? let me explain briefly:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="http://expressjs.com/" rel="noopener noreferrer"&gt;ExpressJS&lt;/a&gt; is a minimalist framework for web development for NodeJS&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/awslabs/aws-serverless-express" rel="noopener noreferrer"&gt;aws-serverless-express&lt;/a&gt; is a proxy to run express applications in AWS Lambda (The spine of this project)&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/axios/axios" rel="noopener noreferrer"&gt;axios&lt;/a&gt; is a HTTP Client for NodeJS and Web Browsers&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://nuxtjs.org/" rel="noopener noreferrer"&gt;NuxtJs&lt;/a&gt; is a Server Side Rendering Framework for VueJS&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After installing all the dependencies, we will need a serverless plugin to make this whole thing to work:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ yarn add -D serverless-apigw-binary
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This Serverless plugin automates the process of adding binary files support in API Gateway. (From the &lt;a href="https://github.com/maciejtreder/serverless-apigw-binary" rel="noopener noreferrer"&gt;Github Repo&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;Now, is time to add some scripts to our &lt;em&gt;package.json:&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;... "scripts": { "dev": "nuxt", "build": "nuxt build", "deploy": "npm run build &amp;amp;&amp;amp; sls deploy" }, ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;“dev”&lt;/em&gt; is to run nuxt locally and test if our pages and layouts work properly&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;“build”&lt;/em&gt; is for building the scripts and assets that NuxtJS require to serve static html&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;“deploy” runs&lt;/em&gt; project building and uses the Serverless CLI to deploy our function in AWS Lambda.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Configuration
&lt;/h3&gt;

&lt;p&gt;First of all, we need to some config related to NuxtJS and Serverless&lt;/p&gt;
&lt;h4&gt;
  
  
  NuxtJS Config
&lt;/h4&gt;

&lt;p&gt;In our root folder we will create a file called &lt;strong&gt;nuxt.config.js&lt;/strong&gt; a file designed to contain all the config that NuxtJS needs to be built and run properly. &lt;a href="https://nuxtjs.org/guide/configuration/" rel="noopener noreferrer"&gt;You can check the documentation of the config file in the NuxtJS Site.&lt;/a&gt;&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;I’m just going to point the important parts of this file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;srcDir: 'src/', performance: { gzip: false }, router: { base: '/dev/' }, dev: false
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;&lt;em&gt;“srcDir” is self-explanatory; is the path of where all the source files live in the project.&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;“performance&amp;gt;gzip”&lt;/em&gt; is for performance configurations, since we don’t want gzip based request (not quite well supported by AWS Lambda), we just disable it.&lt;/li&gt;
&lt;li&gt;“&lt;em&gt;router&lt;/em&gt;” is the web path where NuxtJS is going to be triggered, maybe you want the frontend to be executed in /site/ instead of root.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;“dev”&lt;/em&gt; a flag that tells to NuxtJS if the project will run in production mode&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;
  
  
  Serverless Config
&lt;/h4&gt;

&lt;p&gt;In the root file, you will create a file called &lt;strong&gt;serverless.yml&lt;/strong&gt; that contains all the config needed to deploy our Lambda function in AWS or maybe your function in another provider. &lt;a href="https://serverless.com/framework/docs/providers/aws/guide/serverless.yml/" rel="noopener noreferrer"&gt;You can check the Serverless YAML reference guide in the Serverless documentation.&lt;/a&gt;&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;In the provider config, we set that our function is going to be deployed into AWS using the NodeJS 8.10 runtime and in the region us-east-1 in the dev stage. Our function is going to be called nuxt and the handler of it will be in the handler.js file on the property nuxt, we will se more details of it in the code; and the events that will trigger this function will be HTTP events (via API Gateway) with Any method to any path to support the NuxtJS routing.&lt;/p&gt;

&lt;p&gt;The custom part of all this is related to binary files in the response. Since our lambda will provide Static assets like HTML, css and JS, we will need to support these kind of file using the type */*.&lt;/p&gt;

&lt;h4&gt;
  
  
  Project Structure
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F374%2F1%2Aea3rkzFEm8KkDA8W7MMvlw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F374%2F1%2Aea3rkzFEm8KkDA8W7MMvlw.png"&gt;&lt;/a&gt;Project Structure&lt;/p&gt;

&lt;h3&gt;
  
  
  Time to code!
&lt;/h3&gt;

&lt;p&gt;First of all, we will need to create the handler.js which serves a the entry file for our Lambda&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;This file does a couple of things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;First, we import our server.js that contains all the config related to Express Middlewares and Routing.&lt;/li&gt;
&lt;li&gt;We use a “workaround” to serve static files from our lambda.&lt;/li&gt;
&lt;li&gt;We create our Server object using the Express and MIME configs.&lt;/li&gt;
&lt;li&gt;Finally, we use the Express Serverless Proxy in our lambda handler.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Express Server file
&lt;/h4&gt;

&lt;p&gt;Since we are using an Express Proxy, we use the same config as always!&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;What does this file do?&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;We import the necessary packages to config Express.&lt;/li&gt;
&lt;li&gt;We create our Express App.&lt;/li&gt;
&lt;li&gt;We set the API Gateway Middleware.&lt;/li&gt;
&lt;li&gt;We config the path to access to the NuxtJS static assets.&lt;/li&gt;
&lt;li&gt;We add our Nuxt App as a Express Middleware.&lt;/li&gt;
&lt;li&gt;We export the Express App to use it in the proxy.&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  NuxtJS
&lt;/h4&gt;

&lt;p&gt;The time has come! It’s NuxtJS time.&lt;/p&gt;

&lt;p&gt;We need to create two folders in the src folder, layouts and pages. The NuxtJS documentation defines these folders as:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The layouts directory contains your Application Layouts.&lt;/p&gt;

&lt;p&gt;The pages directory contains your Application Views and Routes. The framework reads all the .vue files inside this directory and creates the application router.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;em&gt;You can check more info about&lt;/em&gt; &lt;a href="https://nuxtjs.org/guide/directory-structure/" rel="noopener noreferrer"&gt;&lt;em&gt;directories in the NuxtJS Documentation.&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To serve the root path of our url (Ex: &lt;a href="https://mysite.io/" rel="noopener noreferrer"&gt;https://mysite.io/&lt;/a&gt;), we will create a new index.vue file in the root of the pages dir&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;This file will render a &lt;em&gt;Hello World&lt;/em&gt; like page, but the interesting part of this is that first it will fetch the data of &lt;strong&gt;Luke Skywalker&lt;/strong&gt; from the &lt;a href="https://swapi.co" rel="noopener noreferrer"&gt;Star Wars API&lt;/a&gt; using and pass it to the template to generate the HTML using the &lt;strong&gt;asyncData Method.&lt;/strong&gt; The NuxtJS define the asyncData Method as this:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;You may want to fetch data and render it on the server-side. Nuxt.js adds an&lt;/em&gt; &lt;em&gt;asyncDatamethod to let you handle async operations before setting the component data.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;em&gt;You can check more info about the&lt;/em&gt; &lt;a href="https://nuxtjs.org/guide/async-data/" rel="noopener noreferrer"&gt;&lt;em&gt;asyncData method in the NuxtJS Documentation.&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The next file will be rendered like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F772%2F1%2AJG4-ea_HI600ffvK3MnxVg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F772%2F1%2AJG4-ea_HI600ffvK3MnxVg.png"&gt;&lt;/a&gt;Our root path is ready 🙌&lt;/p&gt;

&lt;p&gt;Next, we will create the next paths:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;/serverless To show another &lt;em&gt;Hello World&lt;/em&gt; like page but it will use a layout for it. Will be handled by the file src/page/serverless/index.vue&lt;/li&gt;
&lt;li&gt;/serverless/:name To show the param used in the path in a &lt;em&gt;Hello {person}&lt;/em&gt; like page. Will be handled by the file src/page/serverless/_name.vue&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Since we a re going to use a different layout for this, let’s create the layout folder and the layout to use, in my case I created a layout called serverless.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;This layout will only add the &lt;a href="http://materializecss.com/" rel="noopener noreferrer"&gt;Materialize CSS&lt;/a&gt; file to our page.&lt;/p&gt;

&lt;p&gt;Let’s use our brand new layout in the path /serverless&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;What this page does is prints a data called type from our Vue object and it will use the serverless layout. It should print a page like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AW5TViqiehWqq2-nsW-Ljzw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AW5TViqiehWqq2-nsW-Ljzw.png"&gt;&lt;/a&gt;/serverless path ready 🙌&lt;/p&gt;

&lt;p&gt;And to finish all of these, let’s create the param route /serverless/:name&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;What this page does, it will use a data called name that will retrieve the param use in the /serverless/:name path, it will render it in the template and then it will use it in the HTML header to generate the title and meta.description tags. The Page should be rendered like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AAn1El54qFQRWJXM-xLWrMw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AAn1El54qFQRWJXM-xLWrMw.png"&gt;&lt;/a&gt;It renders my name in the site and in the title 🙌&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AgER9ipqnOjwckvBQZcnkRw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AgER9ipqnOjwckvBQZcnkRw.png"&gt;&lt;/a&gt;Hey Look! The title and the meta are in the HTML 🙌&lt;/p&gt;

&lt;h3&gt;
  
  
  Deploying
&lt;/h3&gt;

&lt;p&gt;It’s time to deploy our lambda, just type the command yarn run deploy to build and deploy your app. It will take a couple of minutes.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2A0UM7cIAow4HuDi3NKtGvJg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2A0UM7cIAow4HuDi3NKtGvJg.png"&gt;&lt;/a&gt;Our NuxtJS Site built and deployed!&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;You can do almost everything in AWS Lambda! I couldn’t believe the first time I made to work this. If you have an Express powered application and you want to go full serverless, &lt;a href="https://github.com/awslabs/aws-serverless-express" rel="noopener noreferrer"&gt;take a look to the&lt;/a&gt;&lt;a href="https://github.com/awslabs/aws-serverless-express" rel="noopener noreferrer"&gt;aws-serverless-express&lt;/a&gt;, the migration to AWS Lambda is extremely easy and comfortable. I found a couple of use cases that you might go with this approach:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You may want to build a personal website with some degree of dynamism.&lt;/li&gt;
&lt;li&gt;You may want to save money in idle times for your personal website.&lt;/li&gt;
&lt;li&gt;You may want a Small Front End to be powered by a headless CMS like &lt;a href="https://prismic.io/" rel="noopener noreferrer"&gt;Prismic&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you found more use cases or you want to discuss the mentioned ones, feel free to leave a comment!&lt;/p&gt;

&lt;h3&gt;
  
  
  🙌 Thanks for reading 🙌
&lt;/h3&gt;

</description>
      <category>lambda</category>
      <category>nuxt</category>
      <category>aws</category>
      <category>serverless</category>
    </item>
    <item>
      <title>My Experience Unscrambling a Big Content Migration</title>
      <dc:creator>Fernando Alvarez</dc:creator>
      <pubDate>Mon, 22 Jan 2018 14:00:25 +0000</pubDate>
      <link>https://dev.to/fernalvarez590/my-experience-unscrambling-a-big-content-migration-58lo</link>
      <guid>https://dev.to/fernalvarez590/my-experience-unscrambling-a-big-content-migration-58lo</guid>
      <description>&lt;p&gt;&lt;a href="https://medium.com/@lordferquad/my-experience-unscrambling-a-big-content-migration-9d527885731c" rel="noopener noreferrer"&gt;&lt;em&gt;This article was originally published on Medium&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F600%2F1%2AAEoWvUBRaVw4bh5WWhv7Sg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F600%2F1%2AAEoWvUBRaVw4bh5WWhv7Sg.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It’s a great day at the office, the birds sing, the flowers bloom and the coffee is very pleasant. That day, the client told us about a new requirement that, at the time, we thought would be piece of cake… we were so wrong…&lt;/p&gt;

&lt;p&gt;The client told to us that they needed to migrate all the content from their current CMS to the new Content Delivery Stream we were building. &lt;strong&gt;“Move content from one node to another”&lt;/strong&gt; sounds quite easy, but there were a lot of problems to solve behind that phrase.&lt;/p&gt;

&lt;h3&gt;
  
  
  Old vs New
&lt;/h3&gt;

&lt;p&gt;The client wanted a fancy, brand-new Content Delivery Stream including a Headless CMS, Serverless backend and a frontend to display the content of it. Their current CMS has a lot of problems: from poor client-side performance and a slow delivery stream, to server down-time.&lt;/p&gt;

&lt;p&gt;The architecture we proposed looks like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1003%2F1%2AkWB0Ks5qVEAfF5d9AzLTjg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1003%2F1%2AkWB0Ks5qVEAfF5d9AzLTjg.png"&gt;&lt;/a&gt;High Level Architecture&lt;/p&gt;

&lt;p&gt;CMS users can create and manage content inside a Headless CMS based on WordPress. When users publish an Article, the CMS sends it to the Content Stream. The Content Stream uses &lt;a href="https://aws.amazon.com/lambda/?nc1=h_ls" rel="noopener noreferrer"&gt;AWS Serverless Lambdas&lt;/a&gt; to transform and confirm the content. Content gets hosted on an &lt;a href="https://aws.amazon.com/elasticsearch-service/" rel="noopener noreferrer"&gt;ElasticSearch service.&lt;/a&gt; Web clients visit the frontend and can navigate on the website. The frontend was built in &lt;a href="https://vuejs.org/" rel="noopener noreferrer"&gt;VueJS&lt;/a&gt; and &lt;a href="https://nuxtjs.org/" rel="noopener noreferrer"&gt;Nuxt.js&lt;/a&gt; (server-side rendering for VueJS). The frontend fetches the data from ElasticSearch to display the content. For third-party news feeds, content is loaded using the WordPress REST API.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;What are we going to move?&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;The requirement was clear for us:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;The team needs to move around half a million articles from their old CMS into the new Content Delivery Stream. The content must be available for the frontend and for CMS users to manage inside it. The articles must show the same content as the old CMS and should be flexible enough to edit it in WordPress.&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Designing the migration process
&lt;/h3&gt;
&lt;/blockquote&gt;

&lt;p&gt;The client provided us an ElasticSearch endpoint containing all the data to be migrated instead of querying their database directly. At first we thought of doing a Migration from their ElasticSearch to our Delivery ElasticSearch to have the content ready for external visitors of the website but there was a problem with this approach: the content will not be available in WordPress to edit it and manage it. After seeing this problem, we started doing some research on getting the content “On Demand” using a similar process as the &lt;a href="https://github.com/10up/ElasticPress" rel="noopener noreferrer"&gt;ElasticPress Plugin for WordPress&lt;/a&gt;. Because of the lack of time to do this requirement, we dropped the idea.&lt;/p&gt;

&lt;p&gt;In the next iteration of this design process: we decided to insert the migrated Content into WordPress: we already had a Plugin that transforms the content and the metadata into the required schema that ElasticSearch needs; we only needed to convert every article from the client’s ElasticSearch to WordPress post schema.&lt;/p&gt;

&lt;p&gt;For this, we thought in automating the ingest from ES client to our WordPress instance, our first choice was using the Amazon Simple Queue Service (SQS for short) to throttle the Content Ingestion. The plan was simple and this diagram was born:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F557%2F1%2Ah-HJDoWWDmfZkcoTKs8F7Q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F557%2F1%2Ah-HJDoWWDmfZkcoTKs8F7Q.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We only needed a SQS Producer (to grab from ES and ingest it to an SQS queue) and a couple of SQS Consumers (to listen to the queue and insert the messages into WordPress). Our technology choice was &lt;a href="https://nodejs.org" rel="noopener noreferrer"&gt;NodeJS&lt;/a&gt; because there are two easy-to-use SQS P&lt;a href="https://www.npmjs.com/package/sqs-producer" rel="noopener noreferrer"&gt;roducer&lt;/a&gt; and C&lt;a href="https://www.npmjs.com/package/sqs-consumer" rel="noopener noreferrer"&gt;onsumer&lt;/a&gt; modules for NodeJS available in NPM.&lt;/p&gt;

&lt;p&gt;At the time we were developing the SQS Producer we faced an important problem: ElasticSearch’s limit of 10K documents on from + size queries was causing this problem. To solve this, we decided to use the &lt;a href="https://www.elastic.co/guide/en/elasticsearch/reference/5.5/search-request-scroll.html" rel="noopener noreferrer"&gt;Scroll API&lt;/a&gt; to access to every document in chunks.&lt;/p&gt;

&lt;p&gt;Other problem that we faced when we were developing the Producer was that if the process died, the state wasn’t saved and everything needed to be ingested again.&lt;/p&gt;

&lt;p&gt;To avoid this problem we saved the state of which articles where ingested. To keep track of the last ingested document into SQS we saved the UUID of that document in a database every time the process runs again. It checks the latest UUID in the database. The Scroll API then knows from where to start, using the UUID.&lt;/p&gt;

&lt;p&gt;The consumer process was easy to make. We created a NodeJS script that would listen to the queue and it would got data in chunks of ten. After, it would try to insert them into WordPress. If the process failed fifteen times, SQS would send the broken messages into a Dead Letter queue. To keep the process alive we used PM2.&lt;/p&gt;

&lt;p&gt;After creating the SQS Producer and Consumers, we started developing the content transformers for the WordPress REST API. At first, we decided to get every dependency inside WordPress but we started to notice the requests took a lot of time. Transforming and fetching data inside the CMS was a lot of work for WordPress and MySQL. After a tough afternoon brain storming how to solve this problem, we decided to fetch all the dependencies in the SQS Producer. We transferred that work to Node instead of WordPress to avoid Requests timeout from the API.&lt;/p&gt;

&lt;p&gt;After that change in the Producer everything started to go fine. We decided to start testing the migration process and noticed that MySQL and PHP were taking too long transforming and inserting the data into the CMS.&lt;/p&gt;

&lt;p&gt;We decided to use Amazon Aurora to scale up the database power. Things started to look a little bit better after that but we noticed that the process was going to take many days to finish. With around 50 Articles per minute, the whole process would take forever so we decided to scale-up, the CMS, vertically.&lt;/p&gt;

&lt;p&gt;We created a &lt;a href="https://www.terraform.io/" rel="noopener noreferrer"&gt;Terraform&lt;/a&gt; template to create a cluster of 5 WP instances with the same big power and all of them connected to Aurora. Every request passes through an Elastic Load Balancer (AWS ELB) and using a round robin will access to each instance.&lt;/p&gt;

&lt;p&gt;At last, we had our first architecture design of the migration process:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F914%2F1%2APmSpTnwQ5z14eoJdNHXIQQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F914%2F1%2APmSpTnwQ5z14eoJdNHXIQQ.png"&gt;&lt;/a&gt;Architecture of the content migration using SQS&lt;/p&gt;

&lt;p&gt;We were so proud at that moment because everything started to flow super nicely! but we knew this could be improved to speed up the process a little bit more. We decided to go to the next level by using Amazon Kinesis.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F551%2F1%2AZQLqvm8oClz6J0AFC9f9IQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F551%2F1%2AZQLqvm8oClz6J0AFC9f9IQ.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We decided to change the SQS Producer to be a hybrid supporting SQS and Kinesis ingestion. For the Consumer, we created a lambda function that gets triggered when a new event is ingested into Kinesis Stream. At that moment, we could get around 150 per minute and guess what! The process was too much for WordPress and started timing out. The answer was vertically-scaling up the EC2 instances. At last, our migration process with Kinesis was finished.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F901%2F1%2ARrFniRBVcrvTnAcYFr7A4w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F901%2F1%2ARrFniRBVcrvTnAcYFr7A4w.png"&gt;&lt;/a&gt;Architecture of the content migration using Kinesis&lt;/p&gt;

&lt;p&gt;At this point everything started to going exceptionally well, extremely good time per requests, great number of requests per minute handled… Then everything started getting dark for us.&lt;/p&gt;

&lt;h3&gt;
  
  
  The bumps on the road
&lt;/h3&gt;

&lt;p&gt;We thought at the moment we were out of trouble but we were so wrong. The first bump was when we hit 100k articles and everything came &lt;a href="https://www.youtube.com/watch?v=oIscL-Bjsq4" rel="noopener noreferrer"&gt;tumbling down&lt;/a&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AD0jFYyZ-pG--gy_qMYlR7A.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AD0jFYyZ-pG--gy_qMYlR7A.png"&gt;&lt;/a&gt;What an odd peak…&lt;/p&gt;

&lt;p&gt;We were surprised by this: we never thought something like that peak could happen in the process until we noticed something interesting:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F962%2F1%2ADa8izfZK7X-xPlxssFcinw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F962%2F1%2ADa8izfZK7X-xPlxssFcinw.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We noticed that getting the dependencies to send it to the Delivery Stream was taking too long «but WHY!?!» We noticed that the wp_postmeta table from WordPress had around 1.5 million rows, lots of the values weren’t indexed and required lots of time for MySQL to resolve. This problem was serious because we were facing a &lt;em&gt;probable&lt;/em&gt; design problem in the way WordPress stored the Article metadata. To solve this, we installed the &lt;a href="https://github.com/10up/ElasticPress" rel="noopener noreferrer"&gt;ElasticPress Plugin&lt;/a&gt; to save all the content from WordPress into another ElasticSearch instance. Everything started to run normally again!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2A-9mozCPRQHgo4D_WHbAASA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2A-9mozCPRQHgo4D_WHbAASA.png"&gt;&lt;/a&gt;Before ElasticPress and After ElasticPress&lt;/p&gt;

&lt;p&gt;Another problem we faced is, the process in Kinesis finished abruptly.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2ADU-5_V4iPM2Rv4WZMbpnIg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2ADU-5_V4iPM2Rv4WZMbpnIg.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AXT8R95855f4OGJl1GiS2fA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AXT8R95855f4OGJl1GiS2fA.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Fortunately, this just was a configuration problem that was solved easily by changing the data retention period of the event in the AWS Console&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2Agw2L5gNuKtThnQ-wiPNwQw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2Agw2L5gNuKtThnQ-wiPNwQw.png"&gt;&lt;/a&gt;From 24 hours of retentions to a week of retention&lt;/p&gt;

&lt;p&gt;Another problem we faced in our tests, was the number of request per minute being at an incredibly slow rate when the database had around 1 million Articles:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F711%2F1%2ANB2TXnwPov_VGAlDB99meg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F711%2F1%2ANB2TXnwPov_VGAlDB99meg.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To solve this, the operation team suggested us to use the &lt;a href="https://es.wordpress.org/plugins/hyperdb/" rel="noopener noreferrer"&gt;HyperDB Plugin for WordPress&lt;/a&gt; to manage easily the read and writes replicas since we are using &lt;a href="https://aws.amazon.com/rds/aurora/" rel="noopener noreferrer"&gt;AWS RDS Aurora&lt;/a&gt; as Database Infrastructure. After the configuration of the plugin, the results were very satisfying:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F713%2F1%2AXAVsemQmbOkLGudlvsp6TQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F713%2F1%2AXAVsemQmbOkLGudlvsp6TQ.png"&gt;&lt;/a&gt;HyperDB helped us to manage Read and Write replicas and speed up the process.&lt;/p&gt;

&lt;h3&gt;
  
  
  Time to run the data migration
&lt;/h3&gt;

&lt;p&gt;After all this bumps, we were finally able to run the data migration in the client’s infrastructure. We set up everything and we started the process at the first hour in the morning and after 10k articles we started noticing slowness in the process, time outs and very high CPU usage in the AWS Aurora cluster.&lt;/p&gt;

&lt;p&gt;We made some tests again in our infrastructure and everything fine but their infrastructure wasn’t working! something fishy was going on. We were facing an interesting and unpredictable problem. So close yet so far, we started to debug the process using new relic and we noticed something interesting in their infrastructure:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F838%2F1%2Aqko4KK7u9vToaDWx8kaAFw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F838%2F1%2Aqko4KK7u9vToaDWx8kaAFw.png"&gt;&lt;/a&gt;Every request was taking almost 9 seconds!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AeFXMIDTgKGgU2z5OROeiuQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AeFXMIDTgKGgU2z5OROeiuQ.png"&gt;&lt;/a&gt;126 instances!?&lt;/p&gt;

&lt;p&gt;After some exhaustive debugging, the architecture developer found a bug in the scalability strategy, the problem was fixed and the number of instances started to look more consistent but we still noticed slowness and we found this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AxRCPQVm8iBnX929P5r9JQw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AxRCPQVm8iBnX929P5r9JQw.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AH4BupAXeBjg0Mqy6n-_x1A.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AH4BupAXeBjg0Mqy6n-_x1A.png"&gt;&lt;/a&gt;Painful long requests&lt;/p&gt;

&lt;p&gt;For some strange reason, that select was taking a lot of time and the database CPU was peaking up to 100% of usage. This problem was interesting to solve because we need to replicate the same problem in our infrastructure. We found that each post insert makes a request to that table to increase the count of terms. We clearly don’t need that for our CMS, so we made some query improvements and optimisations but the problem was still there. We decided to add a caching layer using &lt;a href="https://redis.io/" rel="noopener noreferrer"&gt;Redis&lt;/a&gt; and the plugin &lt;a href="https://es.wordpress.org/plugins/redis-cache/" rel="noopener noreferrer"&gt;Redis Object Cache&lt;/a&gt; and the result was better than we expected:&lt;/p&gt;

&lt;h4&gt;
  
  
  Before Caching
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AOZ_rzxa4PLaZK_pQQnUtzw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AOZ_rzxa4PLaZK_pQQnUtzw.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2A-kWiwssGJQ52t6dO9GYJqQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2A-kWiwssGJQ52t6dO9GYJqQ.png"&gt;&lt;/a&gt;Painfully MySQL getting peak up&lt;/p&gt;

&lt;h4&gt;
  
  
  After Caching
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AJzf8WadIp0rGpOLsbopLUQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AJzf8WadIp0rGpOLsbopLUQ.png"&gt;&lt;/a&gt;Every request started to took less than a second&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;A valuable lesson that we learned is that data migrations are not as easy as they sound. This whole experience helped us to understand data migrations better and the learn value was very high for us. Right now, the solutions provided in this article are effectively working for the content migration. I really recommend you to be part of a development process for this kind of projects.&lt;/p&gt;

&lt;h3&gt;
  
  
  Special Thanks
&lt;/h3&gt;

&lt;p&gt;Thank you so much to &lt;a href="https://medium.com/u/79dc767f9a2f" rel="noopener noreferrer"&gt;Vero Leon&lt;/a&gt;, &lt;a href="https://medium.com/u/b4df8fb7f602" rel="noopener noreferrer"&gt;Eder Diaz&lt;/a&gt;, &lt;a href="https://medium.com/u/ff471ed75d8d" rel="noopener noreferrer"&gt;Rafa Salazar&lt;/a&gt; and &lt;a href="https://medium.com/u/b0f1eeeaa8dd" rel="noopener noreferrer"&gt;Eduardo Romero&lt;/a&gt; for helping me making this article even better!&lt;/p&gt;

&lt;h3&gt;
  
  
  🙌 Thanks for Reading! 🙌
&lt;/h3&gt;

</description>
      <category>elasticsearch</category>
      <category>wordpress</category>
      <category>datamigration</category>
      <category>aws</category>
    </item>
    <item>
      <title>Telegram Bot Prototype using Serverless Framework and Webtask</title>
      <dc:creator>Fernando Alvarez</dc:creator>
      <pubDate>Mon, 02 Oct 2017 13:01:28 +0000</pubDate>
      <link>https://dev.to/fernalvarez590/telegram-bot-prototype-using-serverless-framework-and-webtask-e7g</link>
      <guid>https://dev.to/fernalvarez590/telegram-bot-prototype-using-serverless-framework-and-webtask-e7g</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2A2jp2b8aeXLxBVC0yS0RpYA.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2A2jp2b8aeXLxBVC0yS0RpYA.jpeg"&gt;&lt;/a&gt;Scientists from Cognitive Science Research Group at Queen Mary University of London programmed a robot to perform stand-up comedy.â€Š–â€Š&lt;a href="https://www.youtube.com/watch?v=fL5ZtBO4NzM" rel="noopener noreferrer"&gt;&lt;/a&gt;&lt;a href="https://www.youtube.com/watch?v=fL5ZtBO4NzM" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=fL5ZtBO4NzM&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;FaaS (Functions as a Service) is gaining momentum more and more popular this days because They are easy to scale, not idle times costs and incredibly powerful when creating microservices. I was told that Auth0 Inc. created their own FaaS called Webtask and one of the greatest features is that you can easily create your function using NodeJS, so I decided to give it a try and create a very simple prototype with a Telegram bot, Why a bot? Because bots are commonly known to use servers to provide their services, and I want to try the serverless approach of this. Why a telegram bot? Because I am curious about how to do a Telegram Bot.&lt;/p&gt;

&lt;h3&gt;
  
  
  What are we going to build?
&lt;/h3&gt;

&lt;p&gt;In this article, we are going to create a very simple telegram bot that retrieves a random dad joke using the &lt;a href="https://icanhazdadjoke.com/api" rel="noopener noreferrer"&gt;&lt;em&gt;icanhazdadjoke&lt;/em&gt; API&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  What we are going to use?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Latest version of NodeJSâ€Š–â€ŠDownload it &lt;a href="https://nodejs.org/en/download/" rel="noopener noreferrer"&gt;&lt;strong&gt;here&lt;/strong&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;A &lt;a href="https://webtask.io/" rel="noopener noreferrer"&gt;Webtask&lt;/a&gt; account&lt;/li&gt;
&lt;li&gt;An editor of your choiceâ€Š–â€ŠIn mi case, i’m using &lt;a href="https://code.visualstudio.com/" rel="noopener noreferrer"&gt;VSCode&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;A Telegram account and the Telegram Desktop Client (Recommended).&lt;/li&gt;
&lt;li&gt;The Serverless CLIâ€Š–â€ŠDownload it &lt;a href="https://serverless.com/" rel="noopener noreferrer"&gt;here&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Creating the bot in Telegram
&lt;/h3&gt;

&lt;p&gt;After you created your Telegram account and logged in the desktop client, you need to talk with the &lt;a href="https://telegram.me/botfather" rel="noopener noreferrer"&gt;&lt;em&gt;BotFather&lt;/em&gt;&lt;/a&gt; (Click to go to talk with it in the Telegram Client) to create your bot and generate your &lt;strong&gt;API Token&lt;/strong&gt; for your new bot.&lt;/p&gt;

&lt;p&gt;After you open the client with the &lt;em&gt;BotFather,&lt;/em&gt; the /start will be triggered automatically, and the bot will answer with a big list of commands that will help you to create and manage your Telegram bots&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2ARg_4nvtKJB65kR1VPAIN6w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2ARg_4nvtKJB65kR1VPAIN6w.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Use the/newbot command to start. The bot will need a human-readable name. I used “Dad Jokes Bot but you can use any name like “My very first super duper bot joke 5000.”&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2Att0OoLHTcEqClZFDded-Ig.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2Att0OoLHTcEqClZFDded-Ig.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The &lt;em&gt;BotFather&lt;/em&gt; will ask you for an username for the bot. The username &lt;strong&gt;must&lt;/strong&gt; be unique and &lt;strong&gt;end&lt;/strong&gt; with &lt;strong&gt;bot&lt;/strong&gt;. In my case, I used &lt;em&gt;“DadJokesTestBot”&lt;/em&gt; but the username can be any. After you insert the valid bot username will tell you that the bot was successfully created and it will give you the &lt;strong&gt;API Token.&lt;/strong&gt; Write it down. You will need it ðŸ”œ.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2ARLucsPL9aOH2NQkKWy8e8g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2ARLucsPL9aOH2NQkKWy8e8g.png"&gt;&lt;/a&gt;Example of the bot’s username must beÂ unique&lt;/p&gt;

&lt;h3&gt;
  
  
  Creating the Webtask function using Serverless CLI
&lt;/h3&gt;

&lt;p&gt;After creating our Telegram bot using the bot father, we need to create the function that will provide the bot’s functionality. In this case, we will use the Serverless CLI.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Serverless Framework provides a very easy-to-use CLI that generates skeletons of functions from different providers like AWS Lambdas, Google Cloud Functions, Microsoft Azure Functions and, of course, Auth0 Webtask.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;First, we need to create our webtask function using the CLI. Using the next command&lt;/p&gt;

&lt;p&gt;$ serverless create --template webtasks-nodejs --path &amp;lt;folder_name_of_your_bot_&amp;gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AKX3W742tuF_5q-6SKvFHcw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AKX3W742tuF_5q-6SKvFHcw.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Our generated folder structure will look like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F432%2F1%2ABBwAryv1SXxAmS_y02Ok_g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F432%2F1%2ABBwAryv1SXxAmS_y02Ok_g.png"&gt;&lt;/a&gt;Generated folder structure by Serverless CLI&lt;/p&gt;

&lt;p&gt;We need to do a couple of things after upload our function to Webtask. First, we need to install the webtask handler for this project that is included in the package.json file. We Only need to make this command:&lt;/p&gt;

&lt;p&gt;$ npm install&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2ACzGdeDOmDNieab5QtYxegA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2ACzGdeDOmDNieab5QtYxegA.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After that, we need to install a couple of packages to make the bot work:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;axiosâ€Š–â€ŠHTTP Client for NodeJS&lt;/li&gt;
&lt;li&gt;node-telegram-bot-apiâ€Š–â€ŠTelegram Bot API for NodeJS&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;$ npm install --save axios node-telegram-bot-api&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AbfIx6mvEAk1GtWbpFulKtw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AbfIx6mvEAk1GtWbpFulKtw.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After installing all the project dependencies, we need to configure the function name for Webstask. Open the serverless.yml file and then modify the name of the function in service&amp;gt;name. The typical generated example name is &lt;em&gt;webtasks-nodejs&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F896%2F1%2A3oF-NTHuuggMNXfts-1lIA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F896%2F1%2A3oF-NTHuuggMNXfts-1lIA.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After that, we need to login to Webstask using the command:&lt;/p&gt;

&lt;p&gt;$ serverless login&lt;/p&gt;

&lt;p&gt;After the login, the only thing left is deploy our function. Use the next command:&lt;/p&gt;

&lt;p&gt;$ serverless deploy&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AY-eYiJhFz1muGzW6eisa3Q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AY-eYiJhFz1muGzW6eisa3Q.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After this, you will receive your endpoint URL, test it in your browser to be sure that is working. If everything is alright a JSON like this needs to appear:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AFAELJVG6ZhpvxjdvlVTFZw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AFAELJVG6ZhpvxjdvlVTFZw.png"&gt;&lt;/a&gt;The Webtask endpoint is workingÂ ðŸ™Œ&lt;/p&gt;

&lt;h3&gt;
  
  
  Setting the WebHook of our Telegram Bot
&lt;/h3&gt;

&lt;p&gt;After configuring our Webtask endpoint, we need to tell to our bot where it needs to send all the requests that we could make in the chat. Telegram Bots use &lt;strong&gt;WebHooks.&lt;/strong&gt; They are very easy to set up. We are going to set the WebHook to our task’s endpoint using curl:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ curl -X POST https://api.telegram.org/bot&amp;lt;TELEGRAM_BOT_API_TOKEN&amp;gt;/setWebhook -H "Content-type: application-json" -d '{"url": "WEBTASK_ENDPOINT_URL"}'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AtVZSMsrvmL9JAWbhkUAxVQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AtVZSMsrvmL9JAWbhkUAxVQ.png"&gt;&lt;/a&gt;Example of setting a Webhook, in this case is another bot that I madeÂ before&lt;/p&gt;
&lt;h3&gt;
  
  
  Beep-Boop ðŸ¤–: “Hello World!”
&lt;/h3&gt;

&lt;p&gt;Time to code! ðŸ‘&lt;/p&gt;

&lt;p&gt;In the handler.js file, we are going to make the bot respond to messages:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;After that, we just deploy the Webtask&lt;/p&gt;

&lt;p&gt;$ serverless deploy&lt;/p&gt;

&lt;p&gt;And then we just chat a little bit to check if the bot responds&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F426%2F1%2AReeiD0XBEGTkOy_JAOx1uQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F426%2F1%2AReeiD0XBEGTkOy_JAOx1uQ.png"&gt;&lt;/a&gt;Any message to the bot will trigger the message “HelloÂ World!”&lt;/p&gt;

&lt;h3&gt;
  
  
  Making the bot to tell a random dad joke ðŸ¤¡
&lt;/h3&gt;

&lt;p&gt;Lets code again!&lt;/p&gt;

&lt;p&gt;Lets check first what this code do:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;ol&gt;
&lt;li&gt;We create a TelegramBot instance.&lt;/li&gt;
&lt;li&gt;Then we use axiospackage to call the &lt;em&gt;icanhazdadjoke&lt;/em&gt; API.&lt;/li&gt;
&lt;li&gt;Then we set the Token and we create an instance of the bot using the TelegramBot object.&lt;/li&gt;
&lt;li&gt;We get the chatId and message from the current request.&lt;/li&gt;
&lt;li&gt;If the message is the command /start, send the welcome message.&lt;/li&gt;
&lt;li&gt;If the message is the command /tellmeajoke, we retrieve a random dad joke in text/plain from the &lt;em&gt;icanhazdadjoke&lt;/em&gt; API and tell the joke to the user.&lt;/li&gt;
&lt;li&gt;If there’s something that the bot does not understand, we send the error message ðŸ˜•.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Note: We can use ES2017 in Webtasks ðŸ˜&lt;/p&gt;

&lt;h3&gt;
  
  
  Beep-Boop ðŸ¤–: “Let me tell you a joke”
&lt;/h3&gt;

&lt;p&gt;Moment of truth, lets try to chat with our bot!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1004%2F1%2AOjr1JN0eB4jLwT1ZHat9bg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1004%2F1%2AOjr1JN0eB4jLwT1ZHat9bg.png"&gt;&lt;/a&gt;It works!Â ðŸŽ‰&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;This was a simple example, but it shows how fast you can start with serverless bots. Worth to mention that Telegram Bot API is incredibly easy to use and well documented, it shows you great examples of how to create your bots and how to consume their APIs. What I liked the most of this quick project is how easy it is to get create, deploy and test functions with the help of Serverless and Webtasks. I can see a bright future for Webtasks ðŸ˜&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The source code of this project is available on Github right&lt;/em&gt; &lt;a href="https://github.com/jefer590/telegram-bot-serverless-webtasks-example" rel="noopener noreferrer"&gt;&lt;em&gt;here&lt;/em&gt;&lt;/a&gt; &lt;em&gt;if you want to check it out and run it by yourself.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  ðŸ™Œ Thanks for reading! ðŸ™Œ
&lt;/h3&gt;

&lt;h3&gt;
  
  
  Special Thanks!
&lt;/h3&gt;

&lt;p&gt;Thanks to &lt;a href="https://medium.com/u/b0f1eeeaa8dd" rel="noopener noreferrer"&gt;Eduardo Romero&lt;/a&gt; for helping me with the redaction and revision of this article.&lt;/p&gt;

</description>
      <category>node</category>
      <category>bots</category>
      <category>serverless</category>
      <category>telegrammessenger</category>
    </item>
  </channel>
</rss>
