<?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>Forem: Duncan Sample</title>
    <description>The latest articles on Forem by Duncan Sample (@dsample).</description>
    <link>https://forem.com/dsample</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%2F179919%2F34e7a8d2-d781-4160-a7b8-0396228477e6.png</url>
      <title>Forem: Duncan Sample</title>
      <link>https://forem.com/dsample</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/dsample"/>
    <language>en</language>
    <item>
      <title>What I use in my craft</title>
      <dc:creator>Duncan Sample</dc:creator>
      <pubDate>Thu, 13 Jun 2019 11:38:50 +0000</pubDate>
      <link>https://forem.com/dsample/what-i-use-in-my-craft-ed1</link>
      <guid>https://forem.com/dsample/what-i-use-in-my-craft-ed1</guid>
      <description>&lt;p&gt;This article aims to be a list of many of the tools I use for various areas of my software development workflow, in the hope that they help others. I'll try and keep it updated when I find new stuff worth sharing.&lt;/p&gt;

&lt;h1&gt;
  
  
  Hardware
&lt;/h1&gt;

&lt;p&gt;I’m a bit of a stationary and HID geek. I’ve used a variety of pens, notebooks and keyboards over the years, and have currently settled on these for my everyday needs.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;a href="https://amzn.to/2Ibz3rM"&gt;&lt;strong&gt;Uni-ball PIN 0.3mm, 0.5mm and 0.8mm fine liners&lt;/strong&gt;&lt;/a&gt;. These use pigment ink, which means they are long-lasting ‘archival’ inks (they don’t fade), and are also resistant to bleeding when using water-based pens to colour over top. The variety of line widths allows for creating a more detailed sketchnote or diagram without having to go over lines multiple times to make them stand out.&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://amzn.to/2Kr38FN"&gt;&lt;strong&gt;Tombow dual brush pens&lt;/strong&gt;&lt;/a&gt; &lt;strong&gt;(pastel colours)&lt;/strong&gt;. These are great, coupled with pigment fine liners to highlight parts of a diagram or sketchnote.&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://amzn.to/2uUK4F8"&gt;&lt;strong&gt;Rhodia A5 Wirebound Dot Notepad&lt;/strong&gt;&lt;/a&gt;. I came across Rhodia notepads after listening to &lt;a href="https://www.relay.fm/penaddict"&gt;The Pen Addict&lt;/a&gt; podcast. The paper is smooth, works well with fountain pens, fine liners and felt tip pens, and the added dot-grid allows for writing straight as if on lined paper, as well as allowing diagrams to be drawn with straight lines as if on squared paper. The wire binding gives an easy tearaway option for disposing of temporary sketches, so it works well with my visual way of discussing architectures.&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://ergodox-ez.com"&gt;&lt;strong&gt;ErgoDox EZ keyboard&lt;/strong&gt;&lt;/a&gt;. Any mechanical keyboard which is compatible with the &lt;a href="https://qmk.fm/"&gt;QMK firmware&lt;/a&gt; will give you the opportunity to add layers, macros, and shortcut keys to your keyboard, which can make you more productive and remove the need to constantly switch from keyboard to mouse. I’ve used a Microsoft Ergonomic Keyboard for decades, so didn’t want a non-split keyboard, and when I saw the ErgoDox, I was hooked. I can’t say the quirkiness didn’t add to the the appeal of it, but the comfort it gives is great. I now own two (one DIY, one prebuilt).&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Software
&lt;/h1&gt;

&lt;p&gt;Most of my development is done on a MacBook Pro (2015 edition), so I’ll focus OS X. Many of the tools I use, however, are cross-platform, so will work on Linux, and possibly Windows.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;a href="https://www.iterm2.com/"&gt;&lt;strong&gt;iTerm 2&lt;/strong&gt;&lt;/a&gt;. A powerful replacement for the OS X Terminal which supports split-panes and tabs.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;ZSH with&lt;/strong&gt; &lt;a href="https://ohmyz.sh/"&gt;&lt;strong&gt;Oh My ZSH&lt;/strong&gt;&lt;/a&gt;. If you use the terminal a lot, Oh My ZSH will likely improve your productivity. You can customise the appearance of the prompt, as well as enable plugins which auto-complete options within apps such as Git, Docker, Helm, and Node. I use the theme &lt;code&gt;kafeitu&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://code.visualstudio.com/"&gt;&lt;strong&gt;Visual Studio Code&lt;/strong&gt;&lt;/a&gt;. Over the years I’ve gone from using TextMate, to Sublime Text, to Atom, and now VSCode. It’s a fork of Atom, but although I install a ridiculous number of extensions on both Atom and VSCode, Atom slowed down significantly for me, so I lean towards VSCode now. The added abilities of VSCode for debugging JavaScript code make it great for my work. I’ll cover list some of the extension below.&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://www.vim.org/"&gt;&lt;strong&gt;Vim&lt;/strong&gt;&lt;/a&gt;, a terminal-based editor. I don’t do the majority of my coding in it anymore, but I do still use it for a significant part of my workflow, for quick scripts, remove administration, debugging, etc.&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://mizage.com/divvy/"&gt;&lt;strong&gt;Divvy&lt;/strong&gt;&lt;/a&gt;. A screen divider. There is an Open Source alternative called &lt;a href="https://www.spectacleapp.com/"&gt;Spectacle&lt;/a&gt;, but it doesn’t have quite the same UX for setting up new shortcuts.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Visual Studio Code extensions
&lt;/h2&gt;

&lt;p&gt;Along with the built-in capabilities of VSCode, I’ve found a bunch of extensions help me be more productive.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;a href="https://marketplace.visualstudio.com/itemdetails?itemName=PeterJausovec.vscode-docker"&gt;&lt;strong&gt;Docker&lt;/strong&gt;&lt;/a&gt; provides intelligence for Dockerfiles as well as some useful shortcuts accessible from the command Palette.&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://marketplace.visualstudio.com/itemdetails?itemName=EditorConfig.EditorConfig"&gt;&lt;strong&gt;EditorConfig&lt;/strong&gt;&lt;/a&gt;, along with the accompanying &lt;code&gt;.editorconfig&lt;/code&gt; file within a repository/directory, will ensure that basic formatting is kept consistent. (My current base file can be found &lt;a href="https://gist.github.com/dsample/8518280e8f2e28af09e4df8908122b40#file-editorconfig"&gt;here&lt;/a&gt;, along with some other useful files for setting up a repo for consistency).&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://marketplace.visualstudio.com/itemdetails?itemName=dbaeumer.vscode-eslint"&gt;&lt;strong&gt;ESLint&lt;/strong&gt;&lt;/a&gt; will highlight code lint issues, and if you set the &lt;code&gt;"eslint.autoFixOnSave": true&lt;/code&gt; setting, it will correct the trivial issues whenever you save the file, without the need for Prettier.&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://marketplace.visualstudio.com/itemdetails?itemName=letrieu.expand-region"&gt;&lt;strong&gt;Expand Region&lt;/strong&gt;&lt;/a&gt;, If you’re used to control+W in Visual Studio for selecting the current word, line, function, etc. with increasing scope each time you press it, this adds the same functionality to VSCode.&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://marketplace.visualstudio.com/itemdetails?itemName=file-icons.file-icons"&gt;&lt;strong&gt;File Icons&lt;/strong&gt;&lt;/a&gt; has some nice icons for lots of file extensions.&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://marketplace.visualstudio.com/itemdetails?itemName=GitHub.vscode-pull-request-github"&gt;&lt;strong&gt;GitHub Pull Requests&lt;/strong&gt;&lt;/a&gt; provides a way to view GitHub Pull Requests within VSCode, which is handy for Inner Sourcing/Open Sourcing.&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://marketplace.visualstudio.com/itemdetails?itemName=eamodio.gitlens"&gt;&lt;strong&gt;GitLens&lt;/strong&gt;&lt;/a&gt; gives even more access to Git metadata and shortcuts.&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://marketplace.visualstudio.com/itemdetails?itemName=oderwat.indent-rainbow"&gt;&lt;strong&gt;Indent Rainbow&lt;/strong&gt;&lt;/a&gt; shows a pleasant colour for each level of indent&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://marketplace.visualstudio.com/itemdetails?itemName=yzhang.markdown-all-in-one"&gt;&lt;strong&gt;Markdown All in One&lt;/strong&gt;&lt;/a&gt; provides a wealth of tools for editing Markdown files&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://marketplace.visualstudio.com/itemdetails?itemName=DavidAnson.vscode-markdownlint"&gt;&lt;strong&gt;Markdownlint&lt;/strong&gt;&lt;/a&gt; highlights issues you have with your Markdown files&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://marketplace.visualstudio.com/itemdetails?itemName=christian-kohler.path-intellisense"&gt;&lt;strong&gt;Path Intellisense&lt;/strong&gt;&lt;/a&gt; helps auto-complete relational paths to files&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://marketplace.visualstudio.com/itemdetails?itemName=mechatroner.rainbow-csv"&gt;&lt;strong&gt;Rainbow CSV&lt;/strong&gt;&lt;/a&gt; colour-codes columns of CSV files to help visual scanning of CSV data.&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://marketplace.visualstudio.com/itemdetails?itemName=redhat.vscode-yaml"&gt;&lt;strong&gt;YAML&lt;/strong&gt;&lt;/a&gt; provides helpful support for YAML file editing, including linting.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  JavaScript-specific extensions
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;a href="https://marketplace.visualstudio.com/itemdetails?itemName=kisstkondoros.vscode-codemetrics"&gt;&lt;strong&gt;CodeMetrics&lt;/strong&gt;&lt;/a&gt; helps by letting you know when your functions are getting a bit long-winded and are in need of refactoring.&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://marketplace.visualstudio.com/itemdetails?itemName=wix.glean"&gt;&lt;strong&gt;Glean&lt;/strong&gt;&lt;/a&gt; helps with refactoring React code&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://marketplace.visualstudio.com/itemdetails?itemName=cmstead.jsrefactor"&gt;&lt;strong&gt;JS Refactor&lt;/strong&gt;&lt;/a&gt; helps with refactoring JavaScript code&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://marketplace.visualstudio.com/itemdetails?itemName=eg2.vscode-npm-script"&gt;&lt;strong&gt;NPM&lt;/strong&gt;&lt;/a&gt; highlights issues with packages you depend on&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://marketplace.visualstudio.com/itemdetails?itemName=christian-kohler.npm-intellisense"&gt;&lt;strong&gt;NPM Intellisense&lt;/strong&gt;&lt;/a&gt; helps import libraries by auto-completing package names&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://marketplace.visualstudio.com/itemdetails?itemName=pflannery.vscode-versionlens"&gt;&lt;strong&gt;Version Lens&lt;/strong&gt;&lt;/a&gt; shows the version of your package dependencies and helps update your references to newer versions&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://marketplace.visualstudio.com/itemdetails?itemName=MaxvanderSchee.web-accessibility"&gt;&lt;strong&gt;Web Accessibility&lt;/strong&gt;&lt;/a&gt; highlights where you might have accessibility issues in your HTML/React markup&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>productivity</category>
      <category>vscode</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Environment configuration with React &amp; Nginx</title>
      <dc:creator>Duncan Sample</dc:creator>
      <pubDate>Thu, 13 Jun 2019 07:13:45 +0000</pubDate>
      <link>https://forem.com/dsample/environment-configuration-with-react-nginx-3ja5</link>
      <guid>https://forem.com/dsample/environment-configuration-with-react-nginx-3ja5</guid>
      <description>&lt;p&gt;I’ve been working with React for a couple of weeks, and something I very quickly wanted to know, was how best to achieve environment-specific configuration with a Webpacked app.&lt;/p&gt;

&lt;p&gt;For server-side apps, such as Node.js, Ruby on Rails, or even .Net, reading an environment variable and choosing the right config file, or even just reading everything from environment variables is easy, but when your application is a static, minified package of HTML, CSS, and JavaScript, it’s not quite so simple.&lt;/p&gt;

&lt;p&gt;There are a few options you have here, so I’ll give a brief description of each, and I’ll describe the downsides that meant I didn’t choose them. First though, I’ll list the parts of my scenario:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;React, created using create-react-app, then ‘ejected’&lt;/li&gt;
&lt;li&gt;Nginx or potentially other static host (eg. CDN)&lt;/li&gt;
&lt;li&gt;Docker&lt;/li&gt;
&lt;li&gt;Integrating with a single, remote backend API (for now)&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Using React
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Webpack on deploy
&lt;/h4&gt;

&lt;p&gt;The documented way seems to be to use &lt;code&gt;process.env.foo&lt;/code&gt; in your react app, and let the dotenv plugin for Webpack take care of building the values into the minified code. [&lt;a href="https://github.com/react-boilerplate/react-boilerplate/issues/1250"&gt;1&lt;/a&gt;]&lt;/p&gt;

&lt;p&gt;On the face of it, this looks reasonable… you configure your Docker container with the environment variables, and just run &lt;code&gt;npm run build&lt;/code&gt; in the &lt;code&gt;CMD&lt;/code&gt; argument.&lt;/p&gt;

&lt;p&gt;For me, this is wholely unacceptable though. The are far too many possibilities for variance, and therefore failure in the process to ‘recompile’ the code for each environment. I need a ‘build once, deploy anywhere' approach.&lt;/p&gt;

&lt;p&gt;Another variation on this theme is to build the app with a placeholder in the script, add then use Sed to substitute in the real value on deployment/startup. This again, has too high chance of screwup for my liking.&lt;/p&gt;

&lt;h4&gt;
  
  
  Host detection
&lt;/h4&gt;

&lt;p&gt;Since all of the environments would have different FQDNs, I could use that as a switch to pick between different set of configuration values.&lt;/p&gt;

&lt;p&gt;I discounted this one for two reasons. Firstly, this would mean building in the configuration for all of the environments, exposing the existence and addresses of internal infrastructure and giving away some amount of development process. Secondly, if the browser misinterprets the host name somehow, it could fail inconsistently.&lt;/p&gt;

&lt;p&gt;There’s also a slight annoyance with local testing conflicting with a user loading the site having saved it to their machine for looking at later, however, this isn’t a huge concern as other things would break.&lt;/p&gt;




&lt;h3&gt;
  
  
  Using Nginx configuration
&lt;/h3&gt;

&lt;p&gt;Since the React tooling didn’t appear to have a decent answer, my next thought was to use Nginx — the web server if use to host the built site — to provide the configuration.&lt;/p&gt;

&lt;p&gt;I saw a suggestion for doing the placeholder replacement approach using &lt;a href="https://www.nginx.com/resources/wiki/modules/substitutions/"&gt;Nginx’s &lt;code&gt;sub_filter&lt;/code&gt; module&lt;/a&gt;, but I disliked that for the same reason as above.&lt;/p&gt;

&lt;h4&gt;
  
  
  Separate config file
&lt;/h4&gt;

&lt;p&gt;Of course, the next step was to make the configuration a separate file and somehow (I’ll touch on at the end) bring that file into the app when it’s loaded into the browser.&lt;/p&gt;

&lt;p&gt;Something that’s done with server-side code is to store config files outside the public files directory, and then use the environment variable (eg. &lt;code&gt;NODE_ENV&lt;/code&gt;) to pick the right config file, and serve that file up as a generic &lt;code&gt;/config.js&lt;/code&gt; endpoint. So can we do that with Nginx?&lt;/p&gt;

&lt;p&gt;Short answer, no. Long answer, yes, but you’re apparently not supposed to, so they make it hard.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Out-of-the-box, Nginx doesn’t support using environment variables inside most configuration blocks.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://docs.apitools.com/blog/2014/07/02/using-environment-variables-in-nginx-conf.html"&gt;You can use the Lua or Perl modules&lt;/a&gt;, but that will require installing those modules, making your Docker image bigger, and at that point your site stops being ‘static’ if you’re having to use runtime code.&lt;/p&gt;

&lt;h4&gt;
  
  
  Generate nginx.conf
&lt;/h4&gt;

&lt;p&gt;Several answers on StackOverflow suggest generating the nginx configuration on deployment/startup. Ranging from Sed, and &lt;code&gt;envsubst&lt;/code&gt;, to erb (Embedded Ruby) and other scripting languages.&lt;/p&gt;

&lt;p&gt;String replacement methods, like Sed were out, solely for the possible inconsistency when dealing with complex config files. The necessity to run many times for different variables also doesn’t make it easy.&lt;/p&gt;

&lt;p&gt;Scripting languages like erb were out as I’d have to install whichever one inside the Docker image in order to use it, and that’s unnecessary bloat (as well adding to the security risk). There’s also the issue with some scripting languages that usage of special characters (eg. &lt;code&gt;$&lt;/code&gt;) in the nginx.conf itself might be interpreted, rather than left as literal strings in the config.&lt;/p&gt;

&lt;h4&gt;
  
  
  Copy the app’s config file into place
&lt;/h4&gt;

&lt;p&gt;Perhaps the simplest approach, but easy to neglect, is to have a simple shell script run prior to Nginx starting. That script reads the environment variable and copies the relevant file from an environment-specific directory to a generic file in the static site directory.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cp /config/$ENVIRONMENT.json /app/config.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you’re passing the actual configuration values in, rather than picking a pre-stored file, there’s also the option to generate the config file using a simple echo command&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;echo ‘{“foo”:”$FOO”}’ &amp;gt; /app/config.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Copying a pre-made file is currently my preferred approach. There’s always room for error, but this way doesn’t touch any brittle/complex server configuration, and leaves the server as dumb as possible at runtime. You could even run your site from S3/similar, rather than Nginx, if you wanted.&lt;/p&gt;

&lt;p&gt;The whole setup ends up looking something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#Dockerfile
FROM nginx:latest
COPY nginx.conf /etc/nginx/nginx.conf
COPY build /usr/share/nginx/html/
COPY config/client-side /usr/share/nginx/config/
COPY launch.sh ./
RUN chmod +x launch.sh
CMD ./launch.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#launch.sh
cp /usr/share/nginx/config/$ENVIRONMENT.json /usr/share/nginx/html/config.json
nginx -g "daemon off;"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#nginx.conf (snippet)
...
http {
...
    server {
    ...
        location / {
            root   /usr/share/nginx/html;
            index  index.html;
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Including the config in the site
&lt;/h3&gt;

&lt;p&gt;The other side of things that was virtually unexplained, was how to get the config file to stay separate to the main application code, but still be included.&lt;/p&gt;

&lt;h4&gt;
  
  
  Code splitting
&lt;/h4&gt;

&lt;p&gt;I tried to see if I could get Webpack to leave the config file out of the bundle, and require it at runtime, but I gave up quickly when it wasn’t obvious. I’m sure there’s probably an elegant way to do it here if I could be bothered to find it.&lt;/p&gt;

&lt;h4&gt;
  
  
  Script tag
&lt;/h4&gt;

&lt;p&gt;Putting the &lt;code&gt;config.js&lt;/code&gt; file as a &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; tag in the HTML template worked, but I’d have to rely on a blocking script loading in order to make sure the config was loaded before the application code.&lt;/p&gt;

&lt;h4&gt;
  
  
  Request it
&lt;/h4&gt;

&lt;p&gt;The easiest way I could think of was to make a module in the application that would make an HTTP request for a relative path &lt;code&gt;/config.json&lt;/code&gt; and provide the response to the rest of the application.&lt;/p&gt;

&lt;p&gt;The added benefit of requesting it is that I can deal with error handling, as well as a loading spinner, if I wanted one.&lt;/p&gt;

&lt;h3&gt;
  
  
  The end result
&lt;/h3&gt;

&lt;p&gt;After playing with all of the options, the easiest, as well as more resilient option seems to be to keep separate config files per environment, and request it the first time it’s used in the front-end.&lt;/p&gt;

</description>
      <category>docker</category>
      <category>nginx</category>
      <category>react</category>
      <category>deployment</category>
    </item>
  </channel>
</rss>
