<?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: cristiano</title>
    <description>The latest articles on DEV Community by cristiano (@cristiano).</description>
    <link>https://dev.to/cristiano</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%2F11730%2F6bd2849d-49f5-45c3-a7e2-5b9d3cf1bdd5.jpg</url>
      <title>DEV Community: cristiano</title>
      <link>https://dev.to/cristiano</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/cristiano"/>
    <language>en</language>
    <item>
      <title>How to install SDL2 on macOS</title>
      <dc:creator>cristiano</dc:creator>
      <pubDate>Wed, 26 Jun 2024 14:20:50 +0000</pubDate>
      <link>https://dev.to/cristiano/how-to-install-sdl2-on-macos-3pn4</link>
      <guid>https://dev.to/cristiano/how-to-install-sdl2-on-macos-3pn4</guid>
      <description>&lt;p&gt;Running SDL2 libraries on macOS is slightly different than running them on Linux and Windows systems.&lt;/p&gt;

&lt;p&gt;You might want to run these libraries to work on a native application or a video game that requires graphics and access to other system controls.&lt;/p&gt;

&lt;p&gt;Since there are a few pitfalls to avoid I have put this resource together that covers installing &lt;code&gt;SDL2&lt;/code&gt; and &lt;code&gt;SDL2_image&lt;/code&gt; into the system.&lt;/p&gt;

&lt;p&gt;Finally, I'll include a test program to open a window and a command to compile it.&lt;/p&gt;

&lt;p&gt;It is written in C but SDL can be used with C++, Rust and a few other languages as well.&lt;/p&gt;

&lt;h2&gt;
  
  
  Installation
&lt;/h2&gt;

&lt;p&gt;The first step is to get all files required into your system.&lt;/p&gt;

&lt;p&gt;Download SDL2 by picking the &lt;code&gt;.dmg&lt;/code&gt; one from the release list:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://github.com/libsdl-org/SDL/releases" rel="noopener noreferrer"&gt;https://github.com/libsdl-org/SDL/releases&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Additionally, download the SDL2_image library (also a &lt;code&gt;.dmg&lt;/code&gt; from its release list:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://github.com/libsdl-org/SDL_image/releases" rel="noopener noreferrer"&gt;https://github.com/libsdl-org/SDL_image/releases&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Execute the SDL2 file (will be named something similar to &lt;code&gt;SDL2-2.30.4.dmg&lt;/code&gt;) and a window will open with a few files and an &lt;code&gt;SDL2.framework&lt;/code&gt; folder.&lt;/p&gt;

&lt;p&gt;Open Finder, click &lt;code&gt;Go&lt;/code&gt; then &lt;code&gt;Go to folder...&lt;/code&gt; and type &lt;code&gt;/Library/Frameworks&lt;/code&gt; which will open the contents of that folder.&lt;/p&gt;

&lt;p&gt;Drag &lt;code&gt;SDL2.framework&lt;/code&gt; to &lt;code&gt;/Library/Frameworks&lt;/code&gt; and repeat the steps for the SDL2_image file.&lt;/p&gt;

&lt;p&gt;There should be two additional folders in &lt;code&gt;/Library/Frameworks&lt;/code&gt;, &lt;code&gt;SDL2.framework&lt;/code&gt; and &lt;code&gt;SDL2_image.framework&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Compile a program
&lt;/h2&gt;

&lt;p&gt;One way to test the installation is to write a program, this one opens a window in the system.&lt;/p&gt;

&lt;p&gt;Create a &lt;code&gt;main.c&lt;/code&gt; file and add the contents below to it:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;

&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdbool.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;SDL.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;SDL_timer.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Attempt to initialize graphics and timer system.&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SDL_Init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SDL_INIT_VIDEO&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;SDL_INIT_TIMER&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"error initializing SDL: %s&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;SDL_GetError&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;SDL_Window&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;window&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;SDL_CreateWindow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello, SDL2 on macOS 🍎"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                       &lt;span class="n"&gt;SDL_WINDOWPOS_CENTERED&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                       &lt;span class="n"&gt;SDL_WINDOWPOS_CENTERED&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                       &lt;span class="mi"&gt;640&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;480&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;window&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"error creating window: %s&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;SDL_GetError&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
        &lt;span class="n"&gt;SDL_Quit&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// Keep the window open, in this case SDL_Delay(5000); statement won't work.&lt;/span&gt;
    &lt;span class="n"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;running&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;running&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;SDL_Event&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SDL_PollEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;type&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;SDL_QUIT&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;running&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
     &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// clean up resources before exiting.&lt;/span&gt;
    &lt;span class="n"&gt;SDL_DestroyWindow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;window&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;SDL_Quit&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;On a terminal window, navigate to the same directory of the &lt;code&gt;main.c&lt;/code&gt; file and attempt to compile it:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

gcc &lt;span class="nt"&gt;-o&lt;/span&gt; open_window main.o &lt;span class="sb"&gt;`&lt;/span&gt;sdl2-config &lt;span class="nt"&gt;--libs&lt;/span&gt; &lt;span class="nt"&gt;--cflags&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt; &lt;span class="nt"&gt;-ggdb3&lt;/span&gt; &lt;span class="nt"&gt;-O0&lt;/span&gt; &lt;span class="nt"&gt;--std&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;c99 &lt;span class="nt"&gt;-Wall&lt;/span&gt; &lt;span class="nt"&gt;-F&lt;/span&gt;/Library/Frameworks &lt;span class="nt"&gt;-framework&lt;/span&gt; SDL2 &lt;span class="nt"&gt;-framework&lt;/span&gt; SDL2_image &lt;span class="nt"&gt;-lm&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This could work first try but in my case I've hit quite a few issues a few are solved by the way the header files are included and the structure of the compile command which have already been addressed but there's a few more I found while trying to compile an SDL2 based program.&lt;/p&gt;

&lt;p&gt;One of the issues might look like this: &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

dyld[94016]: Library not loaded: @rpath/SDL2.framework/Versions/A/SDL2
  Referenced from: &amp;lt;BAD3873A-39CC-4033-8C2A-85A0FC365404&amp;gt; /Users/user/Projects/open_window/open_window
  Reason: no LC_RPATH's found
[1]    94016 abort      ./open_window


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The way I solved it was by running the following in the terminal before compiling the program:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;DYLD_FRAMEWORK_PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/Library/Frameworks


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;macOS displays a notice saying &lt;em&gt;“SDL2.framework” cannot be opened because the developer cannot be verified&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The issue can be addressed by running the executable, e.g. &lt;code&gt;./open_window&lt;/code&gt; then opening the Privacy &amp;amp; Security settings and scroll to &lt;em&gt;Security&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;You will see a button to allow the &lt;code&gt;SDL2.framework&lt;/code&gt;, click "Allow Anyway".&lt;br&gt;
Do the same for &lt;code&gt;SDL2_image.framework&lt;/code&gt; if it shows up.&lt;/p&gt;

&lt;p&gt;The notice should now show an "Open" option, there's more context in this Github issue:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://github.com/libsdl-org/SDL/issues/4689#issuecomment-2189963510" rel="noopener noreferrer"&gt;https://github.com/libsdl-org/SDL/issues/4689#issuecomment-2189963510&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Opening a window
&lt;/h2&gt;

&lt;p&gt;Assuming the program compiled correctly we can now open a window by executing the program.&lt;/p&gt;

&lt;p&gt;On a terminal run &lt;code&gt;./open_window&lt;/code&gt; and an empty should should now show!&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4x2ir7jjatpjcnpc19v6.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4x2ir7jjatpjcnpc19v6.png" alt="A window with a black background with a title"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Additional Notes
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;A lot of programs will use &lt;code&gt;#include &amp;lt;SDL2/SDL.h&amp;gt;&lt;/code&gt; but in this case &lt;code&gt;#include &amp;lt;SDL.h&amp;gt;&lt;/code&gt; needs to be used instead when including SDL related header files.&lt;/li&gt;
&lt;li&gt;SDL2 can also be installed with Homebrew, if you prefer it there's &lt;a href="https://dev.to/hacker_thronx/sdl2-on-macos-sonoma-installation-with-vscode-29pe"&gt;a tutorial on dev.to that goes over the setup&lt;/a&gt; as well.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>c</category>
      <category>sdl2</category>
      <category>setup</category>
    </item>
    <item>
      <title>Managing JS and CSS Assets in Rails 7</title>
      <dc:creator>cristiano</dc:creator>
      <pubDate>Sat, 08 Jan 2022 21:04:32 +0000</pubDate>
      <link>https://dev.to/cristiano/managing-js-and-css-assets-in-rails-7-1n0e</link>
      <guid>https://dev.to/cristiano/managing-js-and-css-assets-in-rails-7-1n0e</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Image by &lt;a href="https://unsplash.com/@pawel_czerwinski"&gt;Pawel Czerwinski&lt;br&gt;
&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;On Ruby on Rails 7 the asset management processes have changed from using Webpacker to use the asset pipeline with Import Maps by default as a way to streamline uses of JavaScript based tools and package managers such as Webpack (or other bundlers) Yarn or npm.&lt;/p&gt;

&lt;p&gt;This article aims to explore Import Maps and custom bundling setups on a high level including a quick look over Webpacker so that it can be compared with other approaches, a short example of using Import Maps and a more convoluted example of custom bundling using esbuild with TypeScript and PostCSS.&lt;/p&gt;

&lt;p&gt;Hopefully this article can be used as a starting point for someone who uses JavaScript tools to bundle assets but has little knowledge of how this currently works in the context of a Rails app.&lt;/p&gt;

&lt;h2&gt;
  
  
  Webpacker
&lt;/h2&gt;

&lt;p&gt;This asset management approach was introduced in Rails 6 and is essentially an implementation of Webpack specifically configured to be used with Rails. This is a quick overview of Webpacker so that we can draw a comparison with more recent approaches to asset bundling.&lt;/p&gt;

&lt;p&gt;With Webpacker a &lt;code&gt;config/webpacker.yml&lt;/code&gt; is used as an interface to define the app’s Webpack configuration and a &lt;code&gt;config/webpack&lt;/code&gt; folder was used store files to specify handling of assets in different environments (development, production) or to adapt it to use certain JavaScript libraries which might require additional configuration.&lt;/p&gt;

&lt;p&gt;It would also include a &lt;code&gt;package.json&lt;/code&gt; which has become common to use in any application that makes use of Node modules.&lt;/p&gt;

&lt;p&gt;To install dependencies, &lt;code&gt;yarn install&lt;/code&gt; needs to be run but when &lt;code&gt;rails server&lt;/code&gt; is ran it would spin up the Rails application and run the Webpack watch task so that the assets are bundled correctly.&lt;/p&gt;

&lt;p&gt;One disadvantage could be that the bundling tool is locked to Webpack behind an abstraction configuration layer as it was the default asset management approach picked for version 6.0.0 of Rails. &lt;/p&gt;

&lt;p&gt;What I mean by abstraction layer here is that there wouldn’t be a need to configure Webpack and it would just work out of the box but configuration aspects are hidden behind the scenes and changing them required to change a &lt;code&gt;webpacker.yml&lt;/code&gt; and not the Webpack config directly. Rails had logic in place to glue all of this together behind the scenes. &lt;/p&gt;

&lt;p&gt;Stripping it out or ignoring it in favour of a custom implementation is possible but it’s an extra step and can be more time consuming.&lt;/p&gt;

&lt;h2&gt;
  
  
  Import Maps
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://wicg.github.io/import-maps/"&gt;Import Maps&lt;/a&gt; is the pattern being shipped with a default Rails 7 application. It makes use of a feature where JavaScript modules that would typically be installed with a package manager, such as Yarn or npm, and in most cases transpiled and bundled into a &lt;code&gt;.js&lt;/code&gt; file can be imported directly into the browser and used in your application without an extra build step.&lt;/p&gt;

&lt;h3&gt;
  
  
  Key aspects on the Import Maps approach
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;It’s more tightly coupled with Rails as it is the way the creator encourages developers to go for and ships with a default Rails app.&lt;/li&gt;
&lt;li&gt;Can simplify your toolchain since no &lt;code&gt;npm&lt;/code&gt; or bundlers are required to make use of JavaScript libraries.&lt;/li&gt;
&lt;li&gt;Requires less configuration, running a new &lt;code&gt;rails new myapp&lt;/code&gt; is enough to get you started.&lt;/li&gt;
&lt;li&gt;It does not include an option if you prefer an approach of bundling your own styles. For example using SASS or Postcss, although nothing stops you from making use of a hybrid approach and add a build step yourself.&lt;/li&gt;
&lt;li&gt;Less control of your asset bundling so if you require more complex JavaScript and CSS handling such as using Postcss partials or using a custom way of transpiling JavaScript it might not be the best choice.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Using Import Maps in a website (including a Rails app) will result in the source code look something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"importmap"&lt;/span&gt; &lt;span class="na"&gt;data-turbo-track=&lt;/span&gt;&lt;span class="s"&gt;"reload"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;imports&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;application&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/assets/application.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// A local JS file.&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;another-js-library&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/assets/another-js-library.js, // Another local JS file.
        &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="nx"&gt;local&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;time&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;: &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="nx"&gt;https&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="c1"&gt;//ga.jspm.io/npm:local-time@2.1.0/app/assets/javascripts/local-time.js" // A library being imported via a CDN.&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The example above shows a description of which modules the page is using as importable files. Others could be added such as React, JQuery or pretty much any other JavaScript library.&lt;/p&gt;

&lt;p&gt;Then the modules are imported after the &lt;code&gt;importmap&lt;/code&gt; script tag by rendering a few additional &lt;code&gt;module&lt;/code&gt; tags (can be one per module at times). In this case the libraries in the &lt;code&gt;importmaps&lt;/code&gt; script tag are being used in &lt;code&gt;application.js&lt;/code&gt; so only a single &lt;code&gt;module&lt;/code&gt; tag is required and this should work for most cases:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;script&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"module"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;import "application"&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;script&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Rails will generate these tags for you when the &lt;code&gt;&amp;lt;%= javascript_importmap_tags %&amp;gt;&lt;/code&gt; is added to a layout, typically &lt;code&gt;application.html.erb&lt;/code&gt; and will work out which modules need to be included. &lt;/p&gt;

&lt;p&gt;For browsers that do not fully support this feature, the Rails team has created a shim to make it work for now.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is a shim?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Essentially it’s a program that intercepts the default behaviour of another program or implementation and adds new logic to it, with the aim to make it work better with the application is being used in. &lt;/p&gt;

&lt;p&gt;In this case it intercepts the Import Maps feature and adds logic to make sure it works correctly in all the modern browsers as well as making it compatible with the Rails pattern.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Using Import Maps in Rails&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To import a package that is typically available in &lt;code&gt;npm&lt;/code&gt; run the following command in the terminal. In this case it will install &lt;code&gt;local-time&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;./bin/importmap pin local-time
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will add a new line to &lt;code&gt;config/importmap.rb&lt;/code&gt; to put the package to use. This file is essentially used for Rails to generate the Import Maps script tag that is placed in the final HTML output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;pin&lt;/span&gt; &lt;span class="s2"&gt;"local-time"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;to: &lt;/span&gt;&lt;span class="s2"&gt;"https://ga.jspm.io/npm:local-time@2.1.0/app/assets/javascripts/local-time.js"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you would like to download the package to store it in your application, using the &lt;code&gt;--download&lt;/code&gt; flag will pull the module file into &lt;code&gt;vendor/javascript/local-time.js&lt;/code&gt; and it would also change the &lt;code&gt;pin&lt;/code&gt; statement to reflect the change:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;pin&lt;/span&gt; &lt;span class="s2"&gt;"local-time"&lt;/span&gt; &lt;span class="c1"&gt;# @2.1.0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The module can then be used in &lt;code&gt;app/javascript/application.js&lt;/code&gt; like a regular import would be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;LocalTime&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;local-time&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In some cases you might want to use a module you’ve been working on and is not hosted with &lt;code&gt;npm&lt;/code&gt;. To do this, add the file to &lt;code&gt;assets/javascript&lt;/code&gt; in this case I’ve named it &lt;code&gt;home.js&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Hello Home!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then it can be imported to &lt;code&gt;application.js&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Configure your import map in config/importmap.rb. Read more: https://github.com/rails/importmap-rails&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@hotwired/turbo-rails&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;controllers&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;trix&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@rails/actiontext&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="c1"&gt;// Importing the home.js script here!&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./home&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;LocalTime&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;local-time&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="nx"&gt;LocalTime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;start&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That should be it, the code inside &lt;code&gt;home.js&lt;/code&gt; should run without the need to be pinned in &lt;code&gt;importmap.rb&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;importmap.rb&lt;/code&gt; file is used to workout which modules will be in the following tag:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"importmap"&lt;/span&gt; &lt;span class="na"&gt;data-turbo-track=&lt;/span&gt;&lt;span class="s"&gt;"reload"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;imports&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;application&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/assets/application.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// A local JS file.&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;another-js-library&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/assets/another-js-library.js, // Another local JS file.
        &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="nx"&gt;local&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;time&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;: &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="nx"&gt;https&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="c1"&gt;//ga.jspm.io/npm:local-time@2.1.0/app/assets/javascripts/local-time.js" // A library being imported via a CDN.&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It will also render any other necessary tags in order for Import Maps to work. Each tag points to a module used by this app in particular so your output might be different than this snippet:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"modulepreload"&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"/assets/application-97114f95015a6fb5e0cb87c109b1397e96ba9a9d1e7422725a491c2034ce6580.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"modulepreload"&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"/assets/turbo.min-305f0d205866ac9fc3667580728220ae0c3b499e5f15df7c4daaeee4d03b5ac1.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"modulepreload"&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"/assets/stimulus.min-900648768bd96f3faeba359cf33c1bd01ca424ca4d2d05f36a5d8345112ae93c.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"modulepreload"&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"/assets/stimulus-loading-685d40a0b68f785d3cdbab1c0f3575320497462e335c4a63b8de40a355d883c0.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"/assets/es-module-shims.min-6982885c6ce151b17d1d2841985042ce58e1b94af5dc14ab8268b3d02e7de3d6.js"&lt;/span&gt; &lt;span class="na"&gt;async=&lt;/span&gt;&lt;span class="s"&gt;"async"&lt;/span&gt; &lt;span class="na"&gt;data-turbo-track=&lt;/span&gt;&lt;span class="s"&gt;"reload"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is currently the encouraged way to manage JavaScript in a Rails application but the Rails team has worked towards giving developers some freedom to implement their custom bundling as well.&lt;/p&gt;

&lt;h2&gt;
  
  
  Custom Bundling
&lt;/h2&gt;

&lt;p&gt;Using your own bundling system such as Webpack, Rollup, esbuild or other is also possible in cases where you require a more robust setup. Perhaps you would like to use TypeScript or implement your own configuration of React, Svelte or Vue. You could want a setup with Sass or Postcss. You might simply want to have more control on how dependencies are installed and where they end up. If you require a more convoluted setup this could be the right approach to take.&lt;/p&gt;

&lt;h3&gt;
  
  
  Key aspects on the custom bundling approach
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;The bundler choice and configuration is left completely up to you. This can either be a positive change, because you get more control or could mean that it requires an extra step when setting up the pipeline and a number of additional configuration files.&lt;/li&gt;
&lt;li&gt;The Rails team has made available the &lt;strong&gt;&lt;a href="https://github.com/rails/jsbundling-rails"&gt;&lt;code&gt;jsbundling-rails&lt;/code&gt;&lt;/a&gt;&lt;/strong&gt; gem that streamlines configuring your application with esbuild, Webpack or Rollup along with &lt;code&gt;[cssbundling-rails](https://github.com/rails/cssbundling-rails)&lt;/code&gt; which is the equivalent to manage CSS bundling. Yarn is used in this case.&lt;/li&gt;
&lt;li&gt;This approach requires  &lt;code&gt;yarn build --watch&lt;/code&gt; to be run alongside the Rails server process but using &lt;code&gt;./bin/dev&lt;/code&gt; will run both processes in one go.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In new Rails 7 apps, a bundler and CSS pre processor can be specified using the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;rails new myapp &lt;span class="nt"&gt;-j&lt;/span&gt; esbuild &lt;span class="nt"&gt;-c&lt;/span&gt; postcss
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The options for bundlers and CSS pre processors are limited to the options &lt;code&gt;jsbundling-rails&lt;/code&gt; and &lt;code&gt;cssbundling-rails&lt;/code&gt; offer. See each of the repositories README files for details since they might provide a starting point and save you some time when creating a setup with your preferred tools.&lt;/p&gt;

&lt;p&gt;After using this command, a &lt;code&gt;scripts&lt;/code&gt; object with &lt;code&gt;build&lt;/code&gt; and &lt;code&gt;build:css&lt;/code&gt; tasks still need to be defined and configured in &lt;code&gt;package.json.&lt;/code&gt; An example of how these tasks may look like using the previously selected bundler and pre-processor:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;previous&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;file&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;contents...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"build"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"esbuild ./app/javascript/*.* --outfile=./app/assets/builds/application.js --bundle"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"build:css"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"postcss ./app/assets/stylesheets/application.postcss.css -o ./app/assets/builds/application.css"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;file&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;continues...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using this approach still couples it with Rails configuration which expects a few things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The JS and CSS final output needs to be copied to &lt;code&gt;app/assets/builds&lt;/code&gt;. This means your final transpiled &lt;code&gt;.js&lt;/code&gt; and processed &lt;code&gt;.css&lt;/code&gt; files are expected to be served from here.&lt;/li&gt;
&lt;li&gt;Rails makes use of &lt;code&gt;&amp;lt;%= stylesheet_link_tag "application", "data-turbo-track": "reload" %&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;%= javascript_include_tag "application", "data-turbo-track": "reload", defer: true %&amp;gt;&lt;/code&gt; to look for a bundled &lt;code&gt;application.js&lt;/code&gt; and a &lt;code&gt;application.css&lt;/code&gt; in the builds directory and expect these to exist.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Other than that, it seems JavaScript files and CSS files can be put together in a flexible way. However, using the &lt;code&gt;stylesheet_link_tag&lt;/code&gt; method to add &lt;code&gt;link&lt;/code&gt; tags to the head of the document seems to still require bundled files to be in the &lt;code&gt;builds&lt;/code&gt; folder:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;&amp;lt;%=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;stylesheet_link_tag&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"application"&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"data-turbo-track"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"reload"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;%&amp;gt;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;&amp;lt;%=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;stylesheet_link_tag&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"style"&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"data-turbo-track"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"reload"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;%&amp;gt;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;&amp;lt;%=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;javascript_include_tag&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"application"&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"data-turbo-track"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"reload"&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;defer:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;%&amp;gt;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the example above a link tag pointing at &lt;code&gt;app/assets/builds/style.css&lt;/code&gt; will also be included in the rendered HTML. &lt;/p&gt;

&lt;p&gt;How does Rails determines that the &lt;code&gt;builds&lt;/code&gt; folder should be where compiled assets are meant to be stored? This &lt;a href="https://github.com/rails/jsbundling-rails/blob/b6ec0980ff573203ac1031074e57bc59be5acbf5/lib/install/install.rb#L6"&gt;is decided by the &lt;code&gt;jsbundling-rails&lt;/code&gt; and &lt;code&gt;cssbundling-rails&lt;/code&gt; codebases&lt;/a&gt;, in their default internal configuration.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How about creating a JavaScript module?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The same way a bundled CSS file is expected to be in &lt;code&gt;/builds&lt;/code&gt; when using &lt;code&gt;stylesheet_link_tag&lt;/code&gt;, the same is expected for a bundle JS file when using &lt;code&gt;javascript_include_tag&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;By default, using this custom bundling approach, Rails uses &lt;code&gt;app/javascript/application.js&lt;/code&gt; as an entry point to compile files and you could split your scripts within this folder and import them in, as well as any modules installed via Yarn, this is what the file looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Entry point for the build script in your package.json&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@hotwired/turbo-rails&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./controllers&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Creating a new module in &lt;code&gt;app/javascript/external.mjs&lt;/code&gt; shows how Rails picks up the change when the file is imported into &lt;code&gt;application.js&lt;/code&gt; and that the &lt;code&gt;.mjs&lt;/code&gt; extension can be used with no issues:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;external_message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;External module loaded&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;What about TypeScript?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Typescript can be added in a few steps, &lt;a href="https://noelrappin.com/blog/2021/12/typescript-and-jsbundling-and-rails-7/"&gt;check out Noel Rappin’s post on how to get TypeScript up and running&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Here’s a breakdown of an example setup that builds on the previous steps, start by installing the &lt;code&gt;typescript&lt;/code&gt;, &lt;code&gt;tsc-watch&lt;/code&gt; and a configuration package. I’ve used &lt;code&gt;@tsconfig/recommended&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn add &lt;span class="nt"&gt;--dev&lt;/span&gt; typescript tsc-watch @tsconfig/recommended
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then we want to run the TypeScript checker before esbuild transpiles the code so a &lt;code&gt;watch:ts&lt;/code&gt; command was added along side of a &lt;code&gt;failure:ts&lt;/code&gt; command to run on failure to the &lt;code&gt;package.json&lt;/code&gt; scripts object:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"build"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"esbuild ./app/javascript/application.ts --outfile=./app/assets/builds/application.js --bundle"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"build:css"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"postcss ./app/assets/stylesheets/application.postcss.css -o ./app/assets/builds/application.css"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"failure:ts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"rm ./app/assets/builds/application.js &amp;amp;&amp;amp; rm ./app/assets/builds/application.js.map"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"watch:ts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"tsc-watch --noClear -p ./tsconfig.json --onSuccess &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;yarn build&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt; --onFailure &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;yarn failure:ts&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This requires a &lt;code&gt;tsconfig.json&lt;/code&gt;, this might be tricky to configure if you don’t do it often so here’s the configuration I’ve used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"extends"&lt;/span&gt;: &lt;span class="s2"&gt;"@tsconfig/recommended/tsconfig.json"&lt;/span&gt;,
  &lt;span class="s2"&gt;"compilerOptions"&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"target"&lt;/span&gt;: &lt;span class="s2"&gt;"ES2015"&lt;/span&gt;,
    &lt;span class="s2"&gt;"lib"&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;
      &lt;span class="s2"&gt;"dom"&lt;/span&gt;,
      &lt;span class="s2"&gt;"dom.iterable"&lt;/span&gt;,
      &lt;span class="s2"&gt;"esnext"&lt;/span&gt;
    &lt;span class="o"&gt;]&lt;/span&gt;,
    &lt;span class="s2"&gt;"allowJs"&lt;/span&gt;: &lt;span class="nb"&gt;true&lt;/span&gt;,
    &lt;span class="s2"&gt;"skipLibCheck"&lt;/span&gt;: &lt;span class="nb"&gt;true&lt;/span&gt;,
    &lt;span class="s2"&gt;"strict"&lt;/span&gt;: &lt;span class="nb"&gt;true&lt;/span&gt;,
    &lt;span class="s2"&gt;"forceConsistentCasingInFileNames"&lt;/span&gt;: &lt;span class="nb"&gt;true&lt;/span&gt;,
    &lt;span class="s2"&gt;"noEmit"&lt;/span&gt;: &lt;span class="nb"&gt;true&lt;/span&gt;,
    &lt;span class="s2"&gt;"esModuleInterop"&lt;/span&gt;: &lt;span class="nb"&gt;true&lt;/span&gt;,
    &lt;span class="s2"&gt;"module"&lt;/span&gt;: &lt;span class="s2"&gt;"esnext"&lt;/span&gt;,
    &lt;span class="s2"&gt;"moduleResolution"&lt;/span&gt;: &lt;span class="s2"&gt;"node"&lt;/span&gt;,
    &lt;span class="s2"&gt;"resolveJsonModule"&lt;/span&gt;: &lt;span class="nb"&gt;true&lt;/span&gt;,
    &lt;span class="s2"&gt;"isolatedModules"&lt;/span&gt;: &lt;span class="nb"&gt;true&lt;/span&gt;,
    &lt;span class="s2"&gt;"jsx"&lt;/span&gt;: &lt;span class="s2"&gt;"preserve"&lt;/span&gt;,
    &lt;span class="s2"&gt;"downlevelIteration"&lt;/span&gt;: &lt;span class="nb"&gt;true&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;,
  &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$schema&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;: &lt;span class="s2"&gt;"https://json.schemastore.org/tsconfig"&lt;/span&gt;,
  &lt;span class="s2"&gt;"display"&lt;/span&gt;: &lt;span class="s2"&gt;"Recommended"&lt;/span&gt;,
  &lt;span class="s2"&gt;"include"&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;
    &lt;span class="s2"&gt;"./app/javascript/**/*.ts"&lt;/span&gt;
  &lt;span class="o"&gt;]&lt;/span&gt;,
  &lt;span class="s2"&gt;"exclude"&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;
    &lt;span class="s2"&gt;"./node_modules"&lt;/span&gt;
  &lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, it’s required to rename the entry file at &lt;code&gt;app/javascript/application.js&lt;/code&gt; to &lt;code&gt;application.ts&lt;/code&gt; so that the TypeScript checker picks up on it.&lt;/p&gt;

&lt;p&gt;Finally, the contents &lt;code&gt;[Procfile.dev](http://Procfile.dev)&lt;/code&gt; need to be edited in order to run the TS watch command instead of the build one. We are running the esbuild command via &lt;code&gt;ts-watch&lt;/code&gt; and that’s why it does not need to be in the Procfile:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;web&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;bin/rails server -p &lt;/span&gt;&lt;span class="m"&gt;2077&lt;/span&gt;
&lt;span class="na"&gt;js&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;yarn watch:ts&lt;/span&gt;
&lt;span class="na"&gt;css&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;yarn build:css --watch&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Running &lt;code&gt;./bin/dev&lt;/code&gt; in the terminal will start the tasks and the track changes as well as run TypeScript checks on any &lt;code&gt;.ts&lt;/code&gt; files in the &lt;code&gt;./app/javascript&lt;/code&gt; directory.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;With Rails 7, the framework now ships with an Import Maps approach by default but it does leave options for more complex setups with custom bundling which still have to be done “the Rails way” in some sense. This is noticeable, for example, when a there are assigned default entry points for scripts and pre processed styles. It does help developers that are looking to get slightly more control over their bundling and this seems to be a step in the right direction.&lt;/p&gt;

&lt;p&gt;As the &lt;a href="https://guides.rubyonrails.org/getting_started.html"&gt;Rails getting started guide&lt;/a&gt; says:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;If you learn "The Rails Way" you'll probably discover a tremendous increase in productivity. If you persist in bringing old habits from other languages to your Rails development, and trying to use patterns you learned elsewhere, you may have a less happy experience.&lt;/em&gt; &lt;/p&gt;

&lt;p&gt;This does become true when, for instance, trying to place the files in custom directories since Rails still expects entry files to exist in certain folders and to be used or when trying to decouple asset bundling completely from the framework. For those wanting more complex setups it is completely possible to get them working but it can lead to a greater effort investment on the developer side and it might mean that some Rails helper methods might have to be set aside in those cases, creating a more decoupled solution.&lt;/p&gt;

&lt;p&gt;As with everything, each approach shows advantages and disadvantages so it is very much dependant on the use case which one to go for.&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>rails</category>
      <category>javascript</category>
      <category>css</category>
    </item>
    <item>
      <title>Is going for Devise for user authentication a good choice for a first Rails app or should I write it from scratch?</title>
      <dc:creator>cristiano</dc:creator>
      <pubDate>Mon, 25 Jan 2021 21:02:51 +0000</pubDate>
      <link>https://dev.to/cristiano/is-going-for-devise-for-user-authentication-a-good-choice-for-a-first-rails-app-or-should-i-write-it-from-scratch-47hn</link>
      <guid>https://dev.to/cristiano/is-going-for-devise-for-user-authentication-a-good-choice-for-a-first-rails-app-or-should-i-write-it-from-scratch-47hn</guid>
      <description>&lt;h3&gt;
  
  
  Question
&lt;/h3&gt;

&lt;p&gt;I am writing a Ruby on Rails application and started looking into adding user accounts so I can scope access of different parts of the application.&lt;/p&gt;

&lt;p&gt;The Devise documentation &lt;a href="https://github.com/heartcombo/devise#starting-with-rails"&gt;recommends that beginners start by setting up their own authentication before using the gem&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Setting up custom authentication logic seems to be okay but what would be the trade-offs? And if I would like to move to Devise after a while would that be challenging or even worth doing?&lt;/p&gt;

&lt;p&gt;Would appreciate to hear from more experienced RoR devs. 🙏&lt;/p&gt;

&lt;p&gt;Thanks a lot! &lt;/p&gt;

&lt;h3&gt;
  
  
  What I've learned
&lt;/h3&gt;

&lt;p&gt;Either option is feasible, it seems that going with a custom implementation allows more control over the authentication and authorization aspects of the app. It can a good way of learning about how these features work in general. The cons can be that it can be a complex aspect of the app that needs to be maintained and monitored to make exploits are fixed over time if any.&lt;/p&gt;

&lt;p&gt;This is a great guide to get started creating an auth system in Rails:&lt;/p&gt;


&lt;div class="ltag__link"&gt;
  &lt;a href="/levi" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ADc7cI4l--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/practicaldev/image/fetch/s--tRrR98iY--/c_fill%2Cf_auto%2Cfl_progressive%2Ch_150%2Cq_auto%2Cw_150/https://dev-to-uploads.s3.amazonaws.com/uploads/user/profile_image/223212/00f6a6f6-5b61-4b85-b2e2-effd717f1281.jpeg" alt="levi"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="/levi/authentication-and-authorization-a-la-rails-bcrypt-1kn0" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;Authentication and Authorization à la Rails bcrypt&lt;/h2&gt;
      &lt;h3&gt;Levi ・ Dec 6 '19 ・ 10 min read&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#ruby&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#rails&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#security&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#beginners&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


&lt;p&gt;Additionally, Chris Oliver's Ruby on Rails for Beginners covers this topic: &lt;a href="https://gorails.com/episodes/rails-for-beginners-part-11-creating-the-user-model"&gt;https://gorails.com/episodes/rails-for-beginners-part-11-creating-the-user-model&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Using Devise is an out of the box solution, everything needed for auth is already available including e-mail confirmation and password recovery. Since it's used and maintained by a large number of developers improvements are constantly being made and the gem is kept up to date which can make it more secure to use. On the other hand it can be a black box and its source and features is something that is known over time by using it and reading the code (which is not a bad thing).&lt;/p&gt;

&lt;p&gt;A guide for getting started with Devise can be found here: &lt;a href="https://github.com/heartcombo/devise#getting-started"&gt;https://github.com/heartcombo/devise#getting-started&lt;/a&gt;&lt;/p&gt;

</description>
      <category>help</category>
      <category>discuss</category>
      <category>watercooler</category>
      <category>rails</category>
    </item>
    <item>
      <title>Scoping values in JavaScript</title>
      <dc:creator>cristiano</dc:creator>
      <pubDate>Sat, 05 Dec 2020 19:23:34 +0000</pubDate>
      <link>https://dev.to/cristiano/scoping-values-in-javascript-3o64</link>
      <guid>https://dev.to/cristiano/scoping-values-in-javascript-3o64</guid>
      <description>&lt;p&gt;Scoping is the concept behind how values of variables, functions and other expressions are made available in a program and where they can be accessed from. A good understanding of scope can avoid bugs or unexpected results in a script.&lt;/p&gt;

&lt;h2&gt;
  
  
  Scope Areas
&lt;/h2&gt;

&lt;p&gt;Scoping can be thought of having three areas, the &lt;strong&gt;global scope&lt;/strong&gt;, a &lt;strong&gt;function scope&lt;/strong&gt; or a &lt;strong&gt;block scope&lt;/strong&gt;. &lt;/p&gt;

&lt;h3&gt;
  
  
  Global Scope
&lt;/h3&gt;

&lt;p&gt;The global scope is where values that can be accessed anywhere in the script exist and tend to be defined at the top level of your program. For example, if you had a &lt;code&gt;script.js&lt;/code&gt; file, the variables and functions defined inside that file would belong to the global scope but anything within a function or a code block (more on this later) would not, for example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Available to global scope&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;globalScopeVar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Can be accessed from anywhere (global scope)&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Available to global scope&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;parentScope&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="c1"&gt;// Not available in the global scope.&lt;/span&gt;
  &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;childScope&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;child&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;parent&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// This variable can be used here since its in the global scope.&lt;/span&gt;
&lt;span class="nx"&gt;globalScopeVar&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// This function may be used since its in the global scope.&lt;/span&gt;
&lt;span class="nx"&gt;parentScope&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// This function does not exist in this scope and would throw an error.&lt;/span&gt;
&lt;span class="nx"&gt;childScope&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the example above it shows how JavaScript determines what is available to run on the global scope. &lt;code&gt;globalScopeVar&lt;/code&gt; and &lt;code&gt;parentScope()&lt;/code&gt; are available but childScope() is not because it is nested in a function which makes it bound to another scope.&lt;/p&gt;

&lt;p&gt;Nice! Global scoped values may also be called from almost anywhere, even within function and code blocks.&lt;/p&gt;

&lt;p&gt;Notice how &lt;code&gt;globalScopeVar&lt;/code&gt; can be accessed within &lt;code&gt;parentScope()&lt;/code&gt; and &lt;code&gt;childScope()&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Available to global scope&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;globalScopeVar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Can be accessed from anywhere (global scope)&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Available to global scope&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;parentScope&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="c1"&gt;// Not available in the global scope.&lt;/span&gt;
  &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;childScope&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;globalScopeVar&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;globalScopeVar&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// This variable can be used here since its in the global scope.&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;globalScopeVar&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// This function may be used since its in the global scope.&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;parentScope&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Additionally, can &lt;code&gt;parentScope()&lt;/code&gt; be accessed from &lt;code&gt;childScope()&lt;/code&gt; like &lt;code&gt;globalScopeVar&lt;/code&gt; is? Yes! Because &lt;code&gt;parentScope()&lt;/code&gt; if defined at the global scope level:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Available to global scope&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;globalScopeVar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Can be accessed from anywhere (global scope)&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Available to global scope&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;parentScope&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Not available in the global scope.&lt;/span&gt;
  &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;childScope&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;parentScope&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;childScope&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// This variable can be used here since its in the global scope.&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;globalScopeVar&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// This function may be used since its in the global scope.&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;parentScope&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is probably a not so useful example of how functions are applied in practice as it turns &lt;code&gt;parentScope()&lt;/code&gt; into a function that calls itself which most likely will lead to a call stack error that looks similar to the output below.&lt;/p&gt;

&lt;p&gt;However, it is valid JavaScript and &lt;code&gt;parentScope()&lt;/code&gt; can be used by &lt;code&gt;childScope()&lt;/code&gt; because it was defined in the global scope.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;script.js:8 Uncaught RangeError: Maximum call stack size exceeded
    at childScope &lt;span class="o"&gt;(&lt;/span&gt;script.js:8&lt;span class="o"&gt;)&lt;/span&gt;
    at parentScope &lt;span class="o"&gt;(&lt;/span&gt;script.js:11&lt;span class="o"&gt;)&lt;/span&gt;
    at childScope &lt;span class="o"&gt;(&lt;/span&gt;script.js:8&lt;span class="o"&gt;)&lt;/span&gt;
    at parentScope &lt;span class="o"&gt;(&lt;/span&gt;script.js:11&lt;span class="o"&gt;)&lt;/span&gt;
    at childScope &lt;span class="o"&gt;(&lt;/span&gt;script.js:8&lt;span class="o"&gt;)&lt;/span&gt;
    at parentScope &lt;span class="o"&gt;(&lt;/span&gt;script.js:11&lt;span class="o"&gt;)&lt;/span&gt;
    at childScope &lt;span class="o"&gt;(&lt;/span&gt;script.js:8&lt;span class="o"&gt;)&lt;/span&gt;
    at parentScope &lt;span class="o"&gt;(&lt;/span&gt;script.js:11&lt;span class="o"&gt;)&lt;/span&gt;
    at childScope &lt;span class="o"&gt;(&lt;/span&gt;script.js:8&lt;span class="o"&gt;)&lt;/span&gt;
    at parentScope &lt;span class="o"&gt;(&lt;/span&gt;script.js:11&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The take away is that global scope values are available almost anywhere in your program. Global variables tend to be avoided as it could lead to bug they can end up changed unintentionally and cause unexpected behavior so the unspoken rule tends to be to avoid using them or using them carefully.&lt;/p&gt;

&lt;h3&gt;
  
  
  Function Scope
&lt;/h3&gt;

&lt;p&gt;A function scope if determined by the curly brackets &lt;code&gt;{ }&lt;/code&gt; of its block. Any variables, functions or expressions defined within those blocks won’t be available outside of the block.&lt;/p&gt;

&lt;p&gt;On the following example notice how the parentScopeVar is not available outside of the function it was defined in (&lt;code&gt;parentScope()&lt;/code&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// This variable can be accessed from anywhere.&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;globalScopeVar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Can be accessed from anywhere&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;parentScope&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// This variable can only be accessed within this function and its child function and code blocks.&lt;/span&gt;
  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;parentScopeVar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;This variable can only be accessed within this function and its children&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;parentScopeVar&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Error of undefined! Not defined in this scope&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This example will throw an error. Values defined inside the scope of a function are not available outside of its block:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;types.js:14 Uncaught ReferenceError: parentScopeVar is not defined
    at types.js:14
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Like we have observed in a previous example, values from the global scope or higher scopes can be used inside the function, just not the other way around:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// This variable can be accessed from anywhere.&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;globalScopeVar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Can be accessed from anywhere&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;parentScope&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// This variable can only be accessed within this function and its child function and code blocks.&lt;/span&gt;
  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;parentScopeVar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;This variable can only be accessed within this function and its children&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;globalScopeVar&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;parentScope&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;// Returns 'Can be accessed from anywhere';&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice how the &lt;code&gt;globalScopeVar&lt;/code&gt; is available to be used inside the function block. This can be thought like the &lt;code&gt;globalScopeVar&lt;/code&gt; can cross the “gates” (as in curly brackets) and get in &lt;code&gt;parentScope()&lt;/code&gt;, becoming available. On the other hand, &lt;code&gt;parentScopeVar&lt;/code&gt; can never leave the “gates” of &lt;code&gt;parentScope()&lt;/code&gt;, hence why it won’t be able to be accessed anywhere else.&lt;/p&gt;

&lt;p&gt;But what if &lt;code&gt;parentScope()&lt;/code&gt; had another function nested inside its block? Would &lt;code&gt;parentScopeVar&lt;/code&gt; still be available in the that function? Would the function be available in the global scope like &lt;code&gt;parentScope()&lt;/code&gt; is?&lt;/p&gt;

&lt;p&gt;You might have an idea of what the answer to these questions are, but if not it’s totally okay. Let’s consider the following example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;parentScope&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// This variable can only be accessed within this function and its child function and code blocks.&lt;/span&gt;
  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;parentScopeVar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;This variable can only be accessed within this function and its children&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="c1"&gt;// This function is only available to the parentScope. &lt;/span&gt;
  &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;childScope&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;parentScopeVar&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;childScope&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// Success! childScope is available within this block.&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;parentScope&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// Success! parentScope is available in the global scope.&lt;/span&gt;
&lt;span class="nx"&gt;childScope&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// Error! childScope is only available at the parentScope.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the example above we can see how &lt;code&gt;parentScopeVar&lt;/code&gt; is available to &lt;code&gt;childScope()&lt;/code&gt; but &lt;code&gt;childScope()&lt;/code&gt; is only available within the &lt;code&gt;parentScope()&lt;/code&gt; block and it cannot be called in the global scope. &lt;/p&gt;

&lt;p&gt;The key points are that variables and functions declared within a function are not available outside of its code block. However, they are available to be used inside and other nested function blocks if needed just like all the variables are available to every other code block when defined under the global scope.&lt;/p&gt;

&lt;h3&gt;
  
  
  Block Scope
&lt;/h3&gt;

&lt;p&gt;The block scope is similar to the function scope in that global scoped values are available to it but it has a key difference. Variables, functions and other expressions defined within these blocks will be available to the scope they’re currently part of and not limited by the curly brackets.&lt;/p&gt;

&lt;p&gt;Block scope is talked about when using &lt;code&gt;if&lt;/code&gt;, &lt;code&gt;switch&lt;/code&gt;, &lt;code&gt;for&lt;/code&gt; and other types of code blocks for control flow or iteration. Take a look of an example of a couple of code blocks being used in the global scope and how values defined within the code block can be accessed outside their curly brackets (&lt;code&gt;{ }&lt;/code&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// This variable can be accessed from anywhere.&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;globalScopeVar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Can be accessed from anywhere&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Code blocks won't affect the scope of a variable.&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;secondGlobalScopeVar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Can be accessed from anywhere&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nx"&gt;globalScopeVar&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Success! It's available in the global scope and can be accessed in the block.&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Variables in a loop will still be available and in scope after the loop is done.&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Global scoped loop:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nx"&gt;globalScopeVar&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Success! It's available in the global scope and can be accessed in the block.&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;secondGlobalScopeVar&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Success! The if statement block will run and it's available in the global scope.&lt;/span&gt;
&lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Success! It's available in the global scope.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the example above, &lt;code&gt;index&lt;/code&gt; and &lt;code&gt;secondGlobalVar&lt;/code&gt; can be accessed from outside their blocks. Variables declared with var are not bound to the limits of the blocks.&lt;/p&gt;

&lt;p&gt;However, there is a way to scope &lt;code&gt;index&lt;/code&gt; and &lt;code&gt;secondGlobalScopeVar&lt;/code&gt; to their blocks and keep them from being available in outer scopes by using &lt;code&gt;let&lt;/code&gt; and &lt;code&gt;const&lt;/code&gt;. Here's the same example using those keywords but more on this topic later:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// This variable can be accessed from anywhere.&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;globalScopeVar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Can be accessed from anywhere&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Code blocks won't affect the scope of a variable.&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;secondGlobalScopeVar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Can be accessed from anywhere&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nx"&gt;globalScopeVar&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Success! It's available in the global scope and can be accessed in the block.&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Variables in a loop will still belong to the scope after the loop is done.&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Global scoped loop:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nx"&gt;globalScopeVar&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Success! It's available in the global scope and can be accessed in the block.&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;secondGlobalScopeVar&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Error! This variable is not defined in this scope.&lt;/span&gt;
&lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Error! This variable is not defined in this scope.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Defining variables with &lt;code&gt;let&lt;/code&gt; and &lt;code&gt;const&lt;/code&gt; are a way of scoping them to their code blocks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Example of scope using var
&lt;/h2&gt;

&lt;p&gt;Now that there's been an introduction to scope, let's have a look at a larger example using &lt;code&gt;var&lt;/code&gt;. Try to read it line by line and see how the rules we've described so far apply to this piece of code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="cm"&gt;/*
 * How Javascript scope works using var
 */&lt;/span&gt;

&lt;span class="c1"&gt;// This variable can be accessed from anywhere.&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;globalScopeVar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Can be accessed from anywhere&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;parentScope&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// This variable can only be accessed within this function and its child function and code blocks.&lt;/span&gt;
  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;parentScopeVar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;This variable can only be accessed within this function and its children&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="c1"&gt;// Global scope variables are available in this function scope.&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;group&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;parentScope&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;parentScope can access globalScopeVar: &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;globalScopeVar&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;parentScope can access parentScopeVar: &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;parentScopeVar&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;parentScope can access secondParentScope (function): &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;secondParentScope&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;groupEnd&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;parentScope&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="cm"&gt;/* parentScope CANNOT access:
    childScopeVar // undefined in this scope
    secondParentScopeVar // undefined in this scope
  */&lt;/span&gt;

  &lt;span class="c1"&gt;// This function is only available to the parentScope. &lt;/span&gt;
  &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;childScope&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// This variable can only be accessed within this function and its child function and code blocks.&lt;/span&gt;
    &lt;span class="c1"&gt;// Cannot be accessed by parentScope or the globalScope.&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;childScopeVar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Only available withing this function scope and its children&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;group&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;childScope&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="c1"&gt;// Global scope variables are available in this function scope.&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;childScope can access globalScopeVar: &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;globalScopeVar&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="c1"&gt;// Can access the variable defined by its parent.&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;childScope can access parentScopeVar: &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;parentScopeVar&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;childScope can access childScopeVar: &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;childScopeVar&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;groupEnd&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;childScope&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="cm"&gt;/* childScope CANNOT access:
      secondParentScopeVar // undefined in this scope
    */&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// childScope() is only available to the parentScope&lt;/span&gt;
  &lt;span class="nx"&gt;childScope&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;secondParentScope&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;secondParentScopeVar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;This variable can only be accessed within this function and its children&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;group&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;secondParentScope&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;secondParentScope can access globalScopeVar: &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;globalScopeVar&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;secondParentScope can access secondParentScopeVar: &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;secondParentScopeVar&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;groupEnd&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;secondParentScope&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="cm"&gt;/* The global scope CANNOT access within this block:
    parentScopeVar; // undefined in this scope
    childScopeVar // undefined in this scope
    childScope() // undefined in this scope
  */&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Code blocks won't affect the scope of a variable.&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;secondGlobalScopeVar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Can be accessed from anywhere&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Global scope can access globalScopeVar (in if code block):&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;globalScopeVar&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="cm"&gt;/* The global scope CANNOT access:
    parentScopeVar; // undefined in this scope
    childScopeVar // undefined in this scope
    childScope() // undefined in this scope
    secondParentScopeVar // undefined in this scope
  */&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Variables in a loop will still belong to the scope after the loop is done.&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Global scoped loop&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// globalScopeVar can be accessed in the global scope with no issues.&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Global scope can access globalScopeVar:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;globalScopeVar&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// secondGlobalScopeVar can be accessed in the global scope even though it was defined within a code block.&lt;/span&gt;
&lt;span class="c1"&gt;// If the statement didn't evaluate to true then this variable would be undefined.&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Global scope can access secondGlobalScopeVar:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;secondGlobalScopeVar&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// index can be accessed in the global scope even though &lt;/span&gt;
&lt;span class="c1"&gt;// the loop is done andit was defined within a code block.&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Global scope can access index:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Running parentScope.&lt;/span&gt;
&lt;span class="nx"&gt;parentScope&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="c1"&gt;// Running secondParentScope.&lt;/span&gt;
&lt;span class="nx"&gt;secondParentScope&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="cm"&gt;/* The global scope CANNOT access:
  parentScopeVar; // undefined in this scope
  childScopeVar // undefined in this scope
  childScope() // undefined in this scope
  secondParentScopeVar // undefined in this scope
*/&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This &lt;a href="https://gist.github.com/csalmeida/b170b7d73937df294f87c3fc13308df2#file-javascript_var_scope-js"&gt;example is also available as a Gist&lt;/a&gt; in case you would like to read it in your code editor or run it yourself.&lt;/p&gt;

&lt;h2&gt;
  
  
  How let and const affect scope
&lt;/h2&gt;

&lt;p&gt;On an earlier example we've seen how &lt;code&gt;let&lt;/code&gt; and &lt;code&gt;const&lt;/code&gt; can scope a variable to its code block (e.g &lt;code&gt;if&lt;/code&gt; and &lt;code&gt;for&lt;/code&gt;) making it unavailable anywhere else.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;&lt;code&gt;let&lt;/code&gt; and &lt;code&gt;const&lt;/code&gt; declarations are block scoped&lt;/strong&gt;. This brings the benefits of not being able to access a value that is part of a different scope which might prevent it from changing unexpectedly.&lt;/p&gt;

&lt;p&gt;The use of &lt;code&gt;let&lt;/code&gt; and &lt;code&gt;const&lt;/code&gt; tends to be preferred to var, here's a breakdown of the differences between them:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;var&lt;/code&gt; can be updated but not redeclared&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;let&lt;/code&gt; can be updated but not redeclared and is block scoped&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;const&lt;/code&gt; cannot be updated or redeclared and is block scoped&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Example of scope using let and const
&lt;/h2&gt;

&lt;p&gt;This is updated example of how this script would work using &lt;code&gt;let&lt;/code&gt; and &lt;code&gt;const&lt;/code&gt;. Take a minute to &lt;a href="https://gist.github.com/csalmeida/b170b7d73937df294f87c3fc13308df2#file-javascript_let_const_scope-js"&gt;compare the two&lt;/a&gt; and try to see the difference and stop what variables are not longer available:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="cm"&gt;/*
 * How Javascript scope works using let and const
 * It is more restrictive as to where values can be accessed within functions and blocks
 */&lt;/span&gt;

&lt;span class="c1"&gt;// This variable can be accessed from anywhere.&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;globalScopeVar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Can be accessed from anywhere (global scope)&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;parentScope&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// This variable can only be accessed within this function and its child function and code blocks.&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;parentScopeVar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;This variable can only be accessed within this function and its children&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="c1"&gt;// Global scope variables are available in this function scope.&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;group&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;parentScope&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;parentScope can access globalScopeVar: &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;globalScopeVar&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;parentScope can access parentScopeVar: &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;parentScopeVar&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;parentScope can access secondParentScope (function): &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;secondParentScope&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;groupEnd&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;parentScope&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="cm"&gt;/* parentScope CANNOT access:
    childScopeVar // undefined in this scope
    secondParentScopeVar // undefined in this scope
  */&lt;/span&gt;

  &lt;span class="c1"&gt;// This function is only available to the parentScope. &lt;/span&gt;
  &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;childScope&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// This variable can only be accessed within this function and its child function and code blocks.&lt;/span&gt;
    &lt;span class="c1"&gt;// Cannot be accessed by parentScope or the globalScope.&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;childScopeVar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Only available withing this function scope and its children&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;group&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;childScope&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="c1"&gt;// Global scope variables are available in this function scope.&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;childScope can access globalScopeVar: &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;globalScopeVar&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Can access the variable defined by its parent.&lt;/span&gt;
    &lt;span class="nx"&gt;parentScopeVar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;parentScopeVar was modified within childScope()&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;childScope can access parentScopeVar: &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;parentScopeVar&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;childScope can access childScopeVar: &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;childScopeVar&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;groupEnd&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;childScope&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="cm"&gt;/* childScope CANNOT access:
      secondParentScopeVar // undefined in this scope
    */&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// childScope() is only available to the parentScope&lt;/span&gt;
  &lt;span class="nx"&gt;childScope&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;secondParentScope&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;secondParentScopeVar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;This variable can only be accessed within this function and its children&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;group&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;secondParentScope&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;secondParentScope can access globalScopeVar: &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;globalScopeVar&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;secondParentScope can access secondParentScopeVar: &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;secondParentScopeVar&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;groupEnd&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;secondParentScope&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="cm"&gt;/* The global scope CANNOT access within this block:
    parentScopeVar; // undefined in this scope
    childScopeVar // undefined in this scope
    childScope() // undefined in this scope
    secondGlobalScopeVar // undefined in this scope
  */&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Code blocks won't affect the scope of a variable.&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;secondGlobalScopeVar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Can be accessed from this block only&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Global scope can access globalScopeVar (in if code block):&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;globalScopeVar&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Only this block can access secondGlobalScopeVar:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;secondGlobalScopeVar&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="cm"&gt;/* The global scope CANNOT access:
    parentScopeVar; // undefined in this scope
    childScopeVar // undefined in this scope
    childScope() // undefined in this scope
    secondParentScopeVar // undefined in this scope
  */&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Variables in a loop will still belong to the scope after the loop is done.&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Index may be accessed from this loop only&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// globalScopeVar can be accessed in the global scope with no issues.&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Global scope can access globalScopeVar:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;globalScopeVar&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Running parentScope.&lt;/span&gt;
&lt;span class="nx"&gt;parentScope&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="c1"&gt;// Running secondParentScope.&lt;/span&gt;
&lt;span class="nx"&gt;secondParentScope&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="cm"&gt;/* The global scope CANNOT access:
  parentScopeVar; // undefined in this scope
  childScopeVar // undefined in this scope
  childScope() // undefined in this scope
  secondParentScopeVar // undefined in this scope
  secondGlobalScopeVar // undefined in this scope
  index // undefined in this scope
*/&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This &lt;a href="https://gist.github.com/csalmeida/b170b7d73937df294f87c3fc13308df2#file-javascript_let_const_scope-js"&gt;example is also available as a Gist&lt;/a&gt; in case you would like to read it in your code editor or run it yourself.&lt;/p&gt;

&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Glossary/Scope"&gt;MDN - Scoping&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://beginnerjavascript.com"&gt;Wes Bos - Beginner JavaScript&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://gist.github.com/csalmeida/b170b7d73937df294f87c3fc13308df2"&gt;JavaScript Scope Examples GitHub Gist&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>javascript</category>
      <category>scope</category>
      <category>variables</category>
      <category>functions</category>
    </item>
    <item>
      <title>Introduction to the REST Architecture</title>
      <dc:creator>cristiano</dc:creator>
      <pubDate>Tue, 29 Sep 2020 09:44:27 +0000</pubDate>
      <link>https://dev.to/cristiano/introduction-to-the-rest-architecture-b32</link>
      <guid>https://dev.to/cristiano/introduction-to-the-rest-architecture-b32</guid>
      <description>&lt;p&gt;The Web’s most common interaction is retrieving HTML pages via requests that are identified with URLs so we can access pieces of information. When we enter a URL on our browser, a request is sent to a server which will work out what sort of response to send back, and most of the time it will be HTML that our browser can parse and display so we can read its contents.&lt;/p&gt;

&lt;p&gt;However, web applications can do a lot more today than returning HTML to the browsers, they can allow for instance, products, users and other records to be created, we can update posts on our blogs, upload images and delete our tweets.&lt;/p&gt;

&lt;p&gt;To account for this amount of complexity , these requests are not limited to retrieve HTML markup but other formats as well. Furthermore, the request can also trigger actions that make changes to the data stored in the server.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm"&gt;Representational State Transfer (REST) architecture&lt;/a&gt; is widely applied in web application development to help in accessing and changing information related to it. The architecture is defined by a set of components and processes that are outlined by a set of constraints.&lt;/p&gt;

&lt;p&gt;This article will cover the bare bones of REST, a few important terms and concepts required to understand it and a few examples of how it might be used in practice.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is REST?
&lt;/h2&gt;

&lt;p&gt;REST is an architecture style, a set of rules that can be applied when creating web services. Its purpose is to define a uniform way of accessing and modifying web resources.&lt;/p&gt;

&lt;p&gt;Information that the browser can request is organised in entities (users, carts, posts, pages), each of these returns specific information which can be accessed via URLS.&lt;/p&gt;

&lt;p&gt;Requesting information via a URL, or in other words access a resource, can return the information in multiple formats, or commonly referred to as &lt;em&gt;representations&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;With each request, the information includes all data required to make subsequent requests to the server without needing it to know about the whole picture of what is happening in the application (also referred to as state) on the browser side. It also tells us what other resources are available and which can be accessed next so we can keep using the application without having to resort to documentation.&lt;/p&gt;

&lt;p&gt;Applying the concept of entities and resources as a way to organize, access and modify information has proven to be a useful approach to when developing applications and often seen as an alternative to other methods such as the &lt;a href="https://www.service-architecture.com/articles/web-services/soap.html"&gt;Simple Object Access Protocol (SOAP)&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This summarizes what REST is at a higher level but the architecture itself is composed of several components and constraints, each with a role to help define how a service designed with REST should work. We can now go into a bit more detail on these constraints and see how they relate with the concepts introduced in this section.&lt;/p&gt;

&lt;h2&gt;
  
  
  HTTP enables the exchange of information
&lt;/h2&gt;

&lt;p&gt;The interactions with these resources occur through the use of the Internet’s Hypertext Transfer Protocol (HTTP). Since it’s an integral part of working with REST, it is important to understand a few parts of HTTP before moving on, let’s start by defining the request response cycle:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--hNr2S_Pu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/fvdei9g5ktxel4qgfll1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hNr2S_Pu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/fvdei9g5ktxel4qgfll1.png" alt="A diagram describing the HTTP request response cycle with the browser issuing a request to a URL and the server returning a response in the HTML format." width="880" height="550"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The client issues a request to a resource via an URL and the server returns a response. Further complexity is omitted in the diagram to focus on this interaction only.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The client (also known as user agent and could be a browser, a terminal or other software) initiates a request to the server using an URL.&lt;/p&gt;

&lt;p&gt;The server then works out which type of request this is by reading it carefully. One of the details we should be aware of is the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods"&gt;HTTP method&lt;/a&gt; used to make the request. Here’s the ones most commonly used in REST:&lt;/p&gt;

&lt;h3&gt;
  
  
  GET
&lt;/h3&gt;

&lt;p&gt;Retrieves a representation of a resource. These requests should only retrieve data, without changing the resource at all (no side-effects). e.g Show a list of articles.&lt;/p&gt;

&lt;h3&gt;
  
  
  POST
&lt;/h3&gt;

&lt;p&gt;This type of request submits information to the server which can cause changes to be made, effectively changing the state of the application. e.g Publish a new article or change the email of an existing user.&lt;/p&gt;

&lt;h3&gt;
  
  
  DELETE
&lt;/h3&gt;

&lt;p&gt;It’s meant to indicate that the resource should be deleted. e.g Clear a shop cart, remove a user from the system.&lt;/p&gt;

&lt;p&gt;These methods allow us and the server to understand what action is to be taken with a resource.&lt;/p&gt;

&lt;p&gt;A resource is composed of an entity defined as a noun (e.g &lt;code&gt;posts&lt;/code&gt;) and can be accessed as a collection or as an instance. Let’s say we would like to retrieve all posts, we could access a resource that could look like &lt;code&gt;csalmeida.com/posts&lt;/code&gt; to request them and get an array posts (a collection) to display on a page for example. How about a specific post (an instance)? In that case the URL could look like &lt;code&gt;csalmeida.com/posts/1&lt;/code&gt;. The difference here is that an ID is added to the URL to identify the post we would like to access, the server will make use of it to work out which post to get back to the client.&lt;/p&gt;

&lt;p&gt;For example, presuming that we are accessing the URL &lt;code&gt;csalmeida.com/users&lt;/code&gt;. The &lt;code&gt;/users&lt;/code&gt; part of the URL would be the resource we are trying to get to and when a request gets to the server it will process this request, run any code needed to put a response together and retrieve an HTML page listing a set of users.&lt;/p&gt;

&lt;p&gt;The reason we would know some information is being accessed instead of manipulated is by looking at the HTTP method used in the request which in this example is a &lt;code&gt;GET&lt;/code&gt; request. The HTTP method used can give us some clues as to what a request intends to do but in reality we don’t know what sort of response we are going to get when the browser tries to access a resource.&lt;/p&gt;

&lt;p&gt;Looking at the URL, we might assume it returns a page listing all users on the site, but the server could actually return a completely different kind of information depending on what code runs when this request is made. This means that we cannot assume that because a resource (an URL) is described a certain way that we will get what we expect.&lt;/p&gt;

&lt;p&gt;There’s also another aspect that we don’t know about which is the kind of response. Although most of the time it is HTML, it could be other formats such as JSON, XML, plain text and more.&lt;/p&gt;

&lt;p&gt;These aspects mentioned in the example are relevant because they help describing some characteristics of REST. Now let’s look at each of the major constraints of the architecture.&lt;/p&gt;

&lt;h2&gt;
  
  
  The REST Constraints
&lt;/h2&gt;

&lt;p&gt;The set of constraints that define the REST architecture is worth knowing about to understand how to apply it when creating web services based on it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Uniform Interface
&lt;/h3&gt;

&lt;p&gt;It’s the idea that implementations are separate from the services they provide to promote independent system evolution. For example, the same API could be used by a website and a mobile application at the same time, but these elements could evolve independently. &lt;a href="https://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm#sec_5_1_5"&gt;Fielding’s points out that the disadvantage of this approach&lt;/a&gt; is that information is accessible in a standardized format instead of it being designed for each context.&lt;/p&gt;

&lt;p&gt;To achieve this REST takes a resource based approach to that are identified in requests. For example to access the articles of a site a resource could be &lt;code&gt;/articles&lt;/code&gt; and to see the list of available the trains timetables another resource could be &lt;code&gt;/timetables&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;manipulation of resources through representations&lt;/code&gt; should be possible. This means that a representation (for instance an HTML document should include all the the data and URLS necessary to perform subsequent actions if available. The actions could include, reading a related document or removing an article. For example, accessing &lt;code&gt;csalmeida.com/articles&lt;/code&gt; returns an HTML representation of all the articles available on the site. There’s also a “remove article” link that points to &lt;code&gt;csalmeida/articles/32&lt;/code&gt;. This link allows us to remove a specific article with all the information the server needs to perform the action.&lt;/p&gt;

&lt;p&gt;This ties with the with the concept of having &lt;code&gt;Hypermedia as the Engine of Application State (HATEOAS)&lt;/code&gt; which essentially means that each representation includes everything that is necessary for the user to perform subsequent actions in the application either to navigate to another resource or to makes changes to one. In fact, RESTful API expert &lt;a href="https://www.youtube.com/watch?v=MiOSzpfP1Ww&amp;amp;feature=youtu.be&amp;amp;t=204"&gt;Les Hazlewood argues that REST boils down to links and state transitions&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Finally there’s the concept of self-descriptive messages which means that each request itself should include enough information for the server to understand and process it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Stateless
&lt;/h3&gt;

&lt;p&gt;This concept essentially means that the server should not hold any application state for the current user session. The client holds all the state which means that each request made has the necessary information for the server to handle it.&lt;/p&gt;

&lt;p&gt;This helps reducing complexity and resources used by the server since it doesn’t have to track the state of the application for each user, all of it is made available on the user side instead.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cacheable
&lt;/h3&gt;

&lt;p&gt;Essentially the idea of including metadata that specified whether the information returned but the request is cacheable or not and if so, for how long. If the client has already retrieved a representation of something it will cache it and used the next time its requested instead of asking the server for it again. However, this can lead to stale data or in other words, the cached representation the user is seeing might be out of date when compared with what’s available on the server.&lt;/p&gt;

&lt;h3&gt;
  
  
  Client-Server
&lt;/h3&gt;

&lt;p&gt;The REST architecture bases itself on a client-server setup. The server holds the data and provides resources to the client. The client on the on the other hand requests theses resources once processed by the server. This creates a separation of concerns where the server handles the data storage and leaves business logic unknown to the client. The client hold the application state for that session and the server is unaware of what that looks like on each request it just provides information and executes actions as the client requests, depending on what actions are available and what the client is permitted to do.&lt;/p&gt;

&lt;h3&gt;
  
  
  Layered System
&lt;/h3&gt;

&lt;p&gt;This concept defines that an applications might have multiple layers where each layer is only aware of it’s immediate layer, or in other words, the one it needs to interact with. Additionally the client should not be able to tell which one is connecting to along the way.&lt;/p&gt;

&lt;p&gt;For example the API could be deployed on server A, and the data stored on server B and requests being authenticated in server C. A request is handled by server A, authenticated by server C and the data is then retrieved by server B, the client only gets it’s requested representation back without ever being aware that this has happened.&lt;/p&gt;

&lt;h3&gt;
  
  
  Code on demand
&lt;/h3&gt;

&lt;p&gt;An optional aspect of REST, it means that in some cases servers might provide code for the client to execute instead of a representation. This could be for instance a CSS stylesheet of Javascript files.&lt;/p&gt;

&lt;p&gt;This summarizes the six constrains that define REST, in summary each constrains encourages a separation of concerns when designing a web service.&lt;/p&gt;

&lt;h2&gt;
  
  
  A practical example of using a REST API
&lt;/h2&gt;

&lt;p&gt;As most RESTful API’s return JSON we’ll make use of the &lt;a href="https://jsonplaceholder.typicode.com/"&gt;jsonplaceholder API&lt;/a&gt;. This API returns example data out of the box without requiring further steps, let’s try the following URL in the browser:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://jsonplaceholder.typicode.com/posts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The browser will show a JSON representation of the information we’ve requested, it should look similar to this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"userId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"sunt aut facere repellat provident occaecati excepturi optio reprehenderit"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"body"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"quia et suscipit&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;suscipit recusandae consequuntur expedita et cum&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;reprehenderit molestiae ut ut quas totam&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;nostrum rerum est autem sunt rem eveniet architecto"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"userId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"qui est esse"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"body"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"est rerum tempore vitae&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;sequi sint nihil reprehenderit dolor beatae ea dolores neque&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;fugiat blanditiis voluptate porro vel nihil molestiae ut reiciendis&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;qui aperiam non debitis possimus qui neque nisi nulla"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"userId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ea molestias quasi exercitationem repellat qui ipsa sit aut"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"body"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"et iusto sed quo iure&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;voluptatem occaecati omnis eligendi aut ad&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;voluptatem doloribus vel accusantium quis pariatur&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;molestiae porro eius odio et labore et velit aut"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each post includes a set of properties, an &lt;code&gt;id&lt;/code&gt;, &lt;code&gt;title&lt;/code&gt;, &lt;code&gt;body&lt;/code&gt; and the author’s ID as &lt;code&gt;userId&lt;/code&gt;. Next, let’s access the comments for a post:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://jsonplaceholder.typicode.com/posts/1/comments
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This resource retrieves all comments associated with the post with ID 1:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"postId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"id labore ex et quam laborum"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"email"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Eliseo@gardner.biz"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"body"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"laudantium enim quasi est quidem magnam voluptate ipsam eos&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;tempora quo necessitatibus&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;dolor quam autem quasi&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;reiciendis et nam sapiente accusantium"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"postId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"quo vero reiciendis velit similique earum"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"email"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Jayne_Kuhic@sydney.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"body"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"est natus enim nihil est dolore omnis voluptatem numquam&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;et omnis occaecati quod ullam at&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;voluptatem error expedita pariatur&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;nihil sint nostrum voluptatem reiciendis et"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;//...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can also observe that this API does not adhere to all the constraints, for example, when we retrieved all posts it didn’t provide further available resources to access the comments or the author’s information, which can leave the user or the developer to guess or rely on documentation to understand what other actions are available on that resource.&lt;/p&gt;

&lt;p&gt;A way to make it clearer would be to add the paths or even the full URLs to the response as a way to facilitate access of those other resources if needed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"userId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"sunt aut facere repellat provident occaecati excepturi optio reprehenderit"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"body"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"quia et suscipit&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;suscipit recusandae consequuntur expedita et cum&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;reprehenderit molestiae ut ut quas totam&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;nostrum rerum est autem sunt rem eveniet architecto"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"links"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"https://jsonplaceholder.typicode.com/posts/1/comments"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"https://jsonplaceholder.typicode.com/posts?userId=1"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When requesting each resource we are making an HTTP request which makes has a method specified. The method we’ve been using for out requests is &lt;code&gt;GET&lt;/code&gt;. However, how do we know which request is being used?&lt;/p&gt;

&lt;p&gt;For that we can inspect networks requests using the browser’s Dev Tools. Each browser is slightly different but it should have a Network tab where the request made and it’s properties can be inspected in a bit more detail:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--F1WzpOb6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/0p5cvb5x98jq78vksq4f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--F1WzpOb6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/0p5cvb5x98jq78vksq4f.png" alt="The Firefox dev tool's network tab listing a request for a resource, showing its status as 200 OK and the HTTP method used in the request." width="880" height="128"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Using the Browser’s available dev tools a request can be inspected further.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This concludes this example but there’s a lot more to explore, different HTTP methods and some API’s may only let a resource be accessed if they pass authentication, try to explore all of these on your own by interacting with the &lt;a href="https://developer.twitter.com/en/docs/twitter-api/v1/tweets/post-and-engage/overview"&gt;Twitter API&lt;/a&gt; for example.&lt;/p&gt;

&lt;h2&gt;
  
  
  Further observations and considerations
&lt;/h2&gt;

&lt;h3&gt;
  
  
  The resources can have dynamically generated responses
&lt;/h3&gt;

&lt;p&gt;This means that the contents of a response can change with each request. For example, on an initial request to &lt;code&gt;csalmeida.com/users&lt;/code&gt;, might show a page with three users, however a subsequent request can show two if one if them was removed since.&lt;/p&gt;

&lt;h3&gt;
  
  
  The format of a response can vary
&lt;/h3&gt;

&lt;p&gt;It’s worth keeping in mind that responses can return information on an array of formats. It could be HTML for the browser to parse or a JSON data object to be consumed somewhere else. The same information can be &lt;code&gt;represented&lt;/code&gt; in multiple ways.&lt;/p&gt;

&lt;p&gt;A resource is a way to access some information and is identified by an URL used for the server to understand how to respond. The response can be any format, also called a &lt;code&gt;representation&lt;/code&gt; such as HTML, JPEG image, JSON, XML and more.&lt;/p&gt;

&lt;h3&gt;
  
  
  Only the client knows what’s up
&lt;/h3&gt;

&lt;p&gt;The state of the application is stored entirely by the user agent (typically a browser) and each request to the server is sent without the server being aware of what other requests occurred before.&lt;/p&gt;

&lt;p&gt;This means that a request must include all the information it needs to perform an action in isolation, whether it’s creating, modifying or accessing a resource.&lt;/p&gt;

&lt;h3&gt;
  
  
  Understanding an already existing API
&lt;/h3&gt;

&lt;p&gt;When accessing a RESTful API the interaction should be similar to other ones you have interacted with. There are collections and it’s individual instances.&lt;/p&gt;

&lt;p&gt;This being said, one step that needs to be often taken is getting to know the database schema. What tables are there? Which columns each table includes and how do they relate to each other?&lt;/p&gt;

&lt;h3&gt;
  
  
  HTTP has its limitations
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=P0a7PwRNLVU&amp;amp;t"&gt;Martin Nally points out&lt;/a&gt; that HTTP is good for performing Create, Read, Update Delete (CRUD) operations but doesn’t take care of querying or versioning which poses a challenge in designing quality APIs. These topics are something worth exploring as well.&lt;/p&gt;

&lt;h3&gt;
  
  
  No agreement on format of JSON representations
&lt;/h3&gt;

&lt;p&gt;JavaScript Object Notation is a format that’s commonly provided by a REST API. Despite its popularity, there’s no standardized specification on how this data should be structured which could lead to representations being dramatically different between APIs.&lt;/p&gt;

&lt;p&gt;A few experts have developed their own solutions by defining specs that are in tune with their needs and respect the REST architecture, here’s a few:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://jsonapi.org/"&gt;JSON API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://ionspec.org/"&gt;JSON ION&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/mikekelly/hal_specification/blob/master/hal_specification.md"&gt;JSON HAL&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://json-ld.org/"&gt;JSON-LD&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/kevinswiber/siren"&gt;Siren&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://amundsen.com/media-types/collection/"&gt;Collection+JSON&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Not all APIs that call themselves RESTful actually apply the REST architecture as intended
&lt;/h3&gt;

&lt;p&gt;There are a lot of APIs that base themselves in the REST achitecture but violate one or more constraints. In this case, these are not considered truly restful and that’s completely fine but it’s worth mentioning since many APIs available for use that follow some of the rules of REST might not actually adhere to others.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why is it worth knowing about REST?
&lt;/h3&gt;

&lt;p&gt;The use of the REST architecture or modified versions of it (RESTful APIS) are widely used across many applications today. Frameworks such as &lt;a href="https://laravel.com/"&gt;Laravel&lt;/a&gt;, &lt;a href="https://rubyonrails.org/"&gt;Ruby on Rails&lt;/a&gt; and &lt;a href="https://sailsjs.com/"&gt;Sails&lt;/a&gt; make use of it and abstract a lot of the complexity it has so developers can make use of it to streamline the development process and increase project maintainability.&lt;/p&gt;

&lt;p&gt;One other emerging pattern that has seen increased use to design APIs is &lt;a href="https://graphql.org/"&gt;GraphQL&lt;/a&gt; which &lt;a href="https://www.youtube.com/watch?v=T571423fC68&amp;amp;feature=youtu.be"&gt;allows to get access to many resources in a single request&lt;/a&gt;. This approach tries to solve the limitations REST presents when it’s needed to quickly adapt to requirements on the client-side.&lt;/p&gt;

</description>
      <category>rest</category>
      <category>api</category>
      <category>backend</category>
    </item>
    <item>
      <title>Can someone experienced in writing tests expand on the mental models of unit tests?</title>
      <dc:creator>cristiano</dc:creator>
      <pubDate>Mon, 10 Aug 2020 11:45:31 +0000</pubDate>
      <link>https://dev.to/cristiano/can-someone-experienced-in-writing-tests-expand-on-the-mental-models-of-unit-tests-5bp</link>
      <guid>https://dev.to/cristiano/can-someone-experienced-in-writing-tests-expand-on-the-mental-models-of-unit-tests-5bp</guid>
      <description>&lt;p&gt;Hey all, recently I've been trying to introduce tests to an app I'm working on in Rails 6 which uses MiniTest.&lt;/p&gt;

&lt;p&gt;After going through a few guides I was still struggling and I think it's not because or the syntax of the methods available for testing but because I don't quite get the reasoning behind figuring out what to test and what is the best to way to do it.&lt;/p&gt;

&lt;p&gt;Could someone give me an example of their thinking when they need to write tests for a method/something else? I would be very grateful! 🙇🏻‍♂️ &lt;/p&gt;

</description>
      <category>discuss</category>
      <category>tdd</category>
      <category>test</category>
      <category>rails</category>
    </item>
    <item>
      <title>How to setup a Ruby on Rails 7 project</title>
      <dc:creator>cristiano</dc:creator>
      <pubDate>Sat, 08 Aug 2020 07:17:47 +0000</pubDate>
      <link>https://dev.to/cristiano/how-to-setup-a-ruby-on-rails-6-project-2dnb</link>
      <guid>https://dev.to/cristiano/how-to-setup-a-ruby-on-rails-6-project-2dnb</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Cover image photo by &lt;a href="https://unsplash.com/@pixeldan?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Daniel Abadia&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Ruby on Rails is a framework that includes a lot of tools to structure and develop dynamic web applications.&lt;/p&gt;

&lt;p&gt;Rails is a good choice to create an application where a database is required to store information and provides functionality to display, change, remove data and add more as needed.&lt;/p&gt;

&lt;p&gt;For example, it could be &lt;a href="https://twitter.com/"&gt;an app where users register and can write their thoughts for others to see as posts&lt;/a&gt;. Users can follow each other and like posts. This would require data to be stored and accessed as users need it, and relationships between data need to be built, Rails responds well to these requirements.&lt;/p&gt;

&lt;p&gt;Although Rails can also be used to create static HTML pages, it is probably best to make use of a static generator for that purpose instead.&lt;/p&gt;

&lt;p&gt;Hopefully this guide will give you an overview of how to setup a project with Rails 7.0 to the point of where you will be able to see this screen:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Y2Va4tA1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rvs54nxseyply0zyr5sw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Y2Va4tA1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rvs54nxseyply0zyr5sw.png" alt="Ruby on Rails Welcome Screen" width="880" height="431"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Before we begin
&lt;/h2&gt;

&lt;p&gt;A couple of things are required to go through this guide. ails requires a few tools to be installed before a project can be created. This includes the Ruby programming language, Node, Yarn and a relational database management system. The RDBMS can be either MySQL, PosgreSQL or SQLite, this guide uses PostgreSQL but it shouldn’t make much difference to use one of your choice.&lt;/p&gt;

&lt;p&gt;If you need to get these things setup, &lt;a href="https://guides.rubyonrails.org/getting_started.html"&gt;follow the official Rails guide on how to get started&lt;/a&gt;. The guide includes a lot of the things being covered here but it doesn’t include other important details that have tripped me up when setting up a project and might not be that obvious to someone new to Rails.&lt;/p&gt;

&lt;p&gt;Finally some knowledge of how to access and run commands on the terminal is required.&lt;/p&gt;

&lt;p&gt;Once everything is installed you can check if Rails is good to go by running this command in your terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;rails &lt;span class="nt"&gt;--version&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Create a new Rails project
&lt;/h2&gt;

&lt;p&gt;The first step to get started with Rails is to create a new project. This is done using a Rails command in the terminal. Navigate to a folder where you keep your projects and create a new Rails app:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; ~/Projects
rails new rails-introduction-app &lt;span class="nt"&gt;-d&lt;/span&gt; postgresql
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let’s go through what each command does one by one.&lt;/p&gt;

&lt;p&gt;The first command changes directory into a folder named Projects, this is where I would like this app to be created at.&lt;/p&gt;

&lt;p&gt;The second command creates a new Rails app inside a folder called &lt;code&gt;rails-introduction-app&lt;/code&gt;, the name can be named anything but it tends to be named lowercase separated with dashes. An optional &lt;code&gt;-d&lt;/code&gt; flag is provided followed by a database management system name, this is how we can let Rails know which database adapter we are using, being &lt;code&gt;postgresql&lt;/code&gt; in this case.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# other output above...&lt;/span&gt;
├─ y18n@4.0.0
├─ yargs-parser@13.1.2
└─ yargs@13.3.2
✨  Done &lt;span class="k"&gt;in &lt;/span&gt;9.49s.
Webpacker successfully installed 🎉 🍰
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A lot of output will print in the terminal, eventually a new Rails app will be generated in the folder along with a lot of files, let’s have a look:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;rails-introduction-app
&lt;span class="nb"&gt;ls&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first command enters the directory of the app, the second lists the files inside that folder, can you see them? There’s a lot of them, but don’t worry we are only editing one of them in this guide.&lt;/p&gt;

&lt;h2&gt;
  
  
  Configuring the database
&lt;/h2&gt;

&lt;p&gt;In this step we will connect Rails with PostgreSQL, aside from how a database is created, everything else should be the same.&lt;/p&gt;

&lt;p&gt;If you’re using a RDBMS other than PostgreSQL, the step of creating a database is still required.&lt;/p&gt;

&lt;p&gt;Rails makes use of a database to store application data. In version 7.0, one is required from the start, in this case at least the development database needs to be in place but Rails makes use of three databases; development, production, and test.&lt;/p&gt;

&lt;p&gt;Let’s setup all three of them by logging in to &lt;code&gt;postgres&lt;/code&gt;, creating the three databases, each prefixed with the name of the project separated by underscores and creating and granting a user rights to access it. Remember this user’s password since it will be needed later:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Log in to PostgreSQL, in my case the username is postgres&lt;/span&gt;
&lt;span class="c"&gt;# but might be different in your case&lt;/span&gt;
&lt;span class="nb"&gt;sudo&lt;/span&gt; &lt;span class="nt"&gt;-u&lt;/span&gt; postgres psql

&lt;span class="c"&gt;# Once signed in create three databases&lt;/span&gt;
create database rails_introduction_app_development&lt;span class="p"&gt;;&lt;/span&gt;
create database rails_introduction_app_production&lt;span class="p"&gt;;&lt;/span&gt;
create database rails_introduction_app_test&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c"&gt;# Creating a new user, this will be used for Rails to gain access to each database&lt;/span&gt;
create user yournewuser with encrypted password &lt;span class="s1"&gt;'yoursecretpassword'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c"&gt;# Grant priviledges for the newly created user to manage these databases&lt;/span&gt;
grant all privileges on database rails_introduction_app_development to yournewuser&lt;span class="p"&gt;;&lt;/span&gt;
grant all privileges on database rails_introduction_app_production to yournewuser&lt;span class="p"&gt;;&lt;/span&gt;
grant all privileges on database rails_introduction_app_test to yournewuser&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To check if the databases and the user have been created, run the following commands whilst in postgres:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Lists users&lt;/span&gt;
&lt;span class="se"&gt;\d&lt;/span&gt;u

&lt;span class="c"&gt;# Lists all databases (it is a lowercase L)&lt;/span&gt;
&lt;span class="se"&gt;\l&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Everything good so far? I hope so but &lt;a href="//mailto:hello@csalmeida.com"&gt;please feel free to get in touch&lt;/a&gt; if you get stuck! With the necessary databases created we can now let Rails know how to access them.&lt;/p&gt;

&lt;p&gt;Open the app folder (&lt;code&gt;/rails-introduction-app&lt;/code&gt;) in your favourite text editor and open &lt;code&gt;/config/database.yml&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This file includes a lot of comments but here is what we are interested in:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;default&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nl"&gt;&amp;amp;default&lt;/span&gt;
  &lt;span class="na"&gt;adapter&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgresql&lt;/span&gt;
  &lt;span class="na"&gt;encoding&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;unicode&lt;/span&gt;
  &lt;span class="na"&gt;pool&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;lt;%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %&amp;gt;&lt;/span&gt;

&lt;span class="na"&gt;development&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;*default&lt;/span&gt;
  &lt;span class="na"&gt;database&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;rails_introduction_app_development&lt;/span&gt;

&lt;span class="na"&gt;test&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;*default&lt;/span&gt;
  &lt;span class="na"&gt;database&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;rails_introduction_app_test&lt;/span&gt;

&lt;span class="na"&gt;production&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;*default&lt;/span&gt;
  &lt;span class="na"&gt;database&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;rails_introduction_app_production&lt;/span&gt;
  &lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;rails_introduction_app&lt;/span&gt;
  &lt;span class="na"&gt;password&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;lt;%= ENV['RAILS_INTRODUCTION_APP_DATABASE_PASSWORD'] %&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the first block, there are a few defaults setup, such as which database adapter Rails is going to use to interact with the databases. All other blocks inherit what is set on this block so we can add our &lt;code&gt;username&lt;/code&gt; and &lt;code&gt;password&lt;/code&gt; here for now:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;default&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nl"&gt;&amp;amp;default&lt;/span&gt;
  &lt;span class="na"&gt;adapter&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgresql&lt;/span&gt;
  &lt;span class="na"&gt;encoding&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;unicode&lt;/span&gt;
  &lt;span class="na"&gt;pool&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;lt;%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %&amp;gt;&lt;/span&gt;
  &lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;yournewuser&lt;/span&gt;
  &lt;span class="na"&gt;password&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;yoursecretpassword&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now notice how there’s three blocks, why is that? It is because Rails has three environments that it makes use of, &lt;code&gt;development&lt;/code&gt; is the one running on our machine, &lt;code&gt;production&lt;/code&gt; is the one everyone gets to use and &lt;code&gt;test&lt;/code&gt; is used to run tests that make sure our code does what is supposed to do.&lt;/p&gt;

&lt;p&gt;Also notice that the database for each environment matches the database names of the ones we created earlier and the adapter is already set to &lt;code&gt;postgres&lt;/code&gt; but the Rails default is &lt;code&gt;sqlite&lt;/code&gt;. How?&lt;/p&gt;

&lt;p&gt;When creating the app we specified a database adapter with &lt;code&gt;-d postgres&lt;/code&gt;. This was taken into account when creating the &lt;code&gt;database.yml&lt;/code&gt; file so that value was pre-populated for us.&lt;/p&gt;

&lt;p&gt;As for the database names, Rails assumes that’s how they're going to be named, first the name of the app followed by the environment, all lowercase and words separated by underscores.&lt;/p&gt;

&lt;p&gt;Saving your file concludes all initial configuration steps of the app. Rails should now have everything it needs to run.&lt;/p&gt;

&lt;h2&gt;
  
  
  Running and viewing your app
&lt;/h2&gt;

&lt;p&gt;To start the app run the following command in the terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;rails server
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will start the Puma web server, the one used by Rails during development. If ran successfully it should look something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; Booting Puma
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; Rails 7.0.0 application starting &lt;span class="k"&gt;in &lt;/span&gt;development
&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; Run &lt;span class="sb"&gt;`&lt;/span&gt;rails server &lt;span class="nt"&gt;--help&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt; &lt;span class="k"&gt;for &lt;/span&gt;more startup options
Puma starting &lt;span class="k"&gt;in &lt;/span&gt;single mode...
&lt;span class="k"&gt;*&lt;/span&gt; Version 4.3.5 &lt;span class="o"&gt;(&lt;/span&gt;ruby 2.7.1-p83&lt;span class="o"&gt;)&lt;/span&gt;, codename: Mysterious Traveller
&lt;span class="k"&gt;*&lt;/span&gt; Min threads: 5, max threads: 5
&lt;span class="k"&gt;*&lt;/span&gt; Environment: development
&lt;span class="k"&gt;*&lt;/span&gt; Listening on tcp://127.0.0.1:3000
&lt;span class="k"&gt;*&lt;/span&gt; Listening on tcp://[::1]:3000
Use Ctrl-C to stop
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To view the app initial screen open the browser and type &lt;a href="http://localhost:3000"&gt;http://localhost:3000&lt;/a&gt;, this is the address where the Rails app can be accessed during development stages.&lt;/p&gt;

&lt;p&gt;Provided all went as planned, the Rails’ start page should render:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Y2Va4tA1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rvs54nxseyply0zyr5sw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Y2Va4tA1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rvs54nxseyply0zyr5sw.png" alt="Ruby on Rails Welcome Screen" width="880" height="431"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;This is how to setup a new project running on Ruby on Rails version 7.0. From this point next steps could be adding views and controllers to add functionality to the app, I’ll try and cover this in a next post but in the meantime &lt;a href="https://guides.rubyonrails.org/getting_started.html"&gt;the Rails getting started guide&lt;/a&gt; is a good starting point. Thank you for reading this post! 🙏&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>rails</category>
      <category>fullstack</category>
      <category>database</category>
    </item>
    <item>
      <title>.COM might be costing more from 2020</title>
      <dc:creator>cristiano</dc:creator>
      <pubDate>Tue, 11 Feb 2020 10:24:41 +0000</pubDate>
      <link>https://dev.to/cristiano/com-might-be-costing-more-from-2020-2dg1</link>
      <guid>https://dev.to/cristiano/com-might-be-costing-more-from-2020-2dg1</guid>
      <description>&lt;p&gt;Prices for acquiring and renewing .COM domains may rise from this year onwards so I thought I might put a short article together on what is happening and how you can minimise impact on your domains.&lt;/p&gt;

&lt;p&gt;The measure is likely to be put in place after &lt;a href="https://www.icann.org/public-comments/com-amendment-3-2020-01-03-en?utm_source=Iterable&amp;amp;utm_medium=email&amp;amp;utm_campaign=Service_DomCPIv3_20200210"&gt;amendments were proposed to the .COM Registry Agreement&lt;/a&gt; and according to the document ICANN and VeriSign were the only two parties that took part of negotiations.&lt;/p&gt;

&lt;p&gt;Something similar has happened before with the &lt;a href="https://pricecaps.org/"&gt;removal of price caps for .org&lt;/a&gt; domains last year. The price cap had been in place since 1999 for .COM and .NET domains too.&lt;/p&gt;

&lt;h2&gt;
  
  
  How does it impact .com domains?
&lt;/h2&gt;

&lt;p&gt;These amendments could mean that, within 10 years, .COM domains could cost around 70% more than the current wholesale price.&lt;/p&gt;

&lt;p&gt;VeriSign will be able to increase domain prices up to 7% each year for three years with a two year freeze in between every three year period.&lt;/p&gt;

&lt;p&gt;It is unsure yet how clear these costs could impact domain owners but “it is likely that most of these increases will be paid by domain name registrants”, Namecheap states in &lt;a href="https://www.namecheap.com/blog/icann-allows-com-price-increases-gets-more-money/?utm_source=Iterable&amp;amp;utm_medium=email&amp;amp;utm_campaign=Service_DomCPIv3_20200210"&gt;an article on the subject&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What can we do to mitigate these changes?
&lt;/h2&gt;

&lt;p&gt;You could extend your .COM domains to up to 10 years before prices increase as the amendments will have a six month notice period before changes can be made.&lt;/p&gt;

&lt;p&gt;Finally, you could &lt;a href="https://www.icann.org/public-comments/com-amendment-3-2020-01-03-en?utm_source=Iterable&amp;amp;utm_medium=email&amp;amp;utm_campaign=Service_DomCPIv3_20200210"&gt;leave a comment with your thoughts on the proposed changes&lt;/a&gt; on ICANN until the 14th of Feb 2020 or discuss the subject on social media (&lt;a href="https://twitter.com/ICANN"&gt;@ICANN on Twitter&lt;/a&gt;).&lt;/p&gt;

</description>
      <category>domains</category>
      <category>internet</category>
      <category>web</category>
      <category>com</category>
    </item>
    <item>
      <title>Why do recruiters ask for current salary?</title>
      <dc:creator>cristiano</dc:creator>
      <pubDate>Tue, 16 Apr 2019 17:06:32 +0000</pubDate>
      <link>https://dev.to/cristiano/why-do-recruiters-ask-for-current-salary-3l93</link>
      <guid>https://dev.to/cristiano/why-do-recruiters-ask-for-current-salary-3l93</guid>
      <description>&lt;p&gt;I've recently had an interview where the recruiter kept pressuring me to tell her what my current salary was while at the same time being hesitant in saying what they were offering (which was on their advert anyway).&lt;/p&gt;

&lt;p&gt;I thought this was irrelevant to the interview so I preferred not to share but I keep wondering what is the reason behind this question. Is it something harmless or is there a specific purpose to it? Would appreciate the thoughts of anyone who know about this. 🙇🏻‍♂️&lt;/p&gt;

</description>
      <category>discuss</category>
    </item>
  </channel>
</rss>
