<?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: i. welch canavan</title>
    <description>The latest articles on DEV Community by i. welch canavan (@xiwcx).</description>
    <link>https://dev.to/xiwcx</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%2F78346%2F653b6169-04fb-4c17-b76a-35f81c265a15.jpg</url>
      <title>DEV Community: i. welch canavan</title>
      <link>https://dev.to/xiwcx</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/xiwcx"/>
    <language>en</language>
    <item>
      <title>The Simplest Possible Docker Setup For PostgreSQL</title>
      <dc:creator>i. welch canavan</dc:creator>
      <pubDate>Mon, 30 Nov 2020 19:47:18 +0000</pubDate>
      <link>https://dev.to/xiwcx/the-simplest-possible-docker-setup-for-postgresql-1554</link>
      <guid>https://dev.to/xiwcx/the-simplest-possible-docker-setup-for-postgresql-1554</guid>
      <description>&lt;p&gt;Recently I was working through &lt;a href="https://www.xiaoru.li/"&gt;Xiaoru Li&lt;/a&gt;’s &lt;a href="https://dev.to/prisma/passwordless-authentication-with-next-js-prisma-and-next-auth-5g8g"&gt;excellent tutorial on Next-Auth&lt;/a&gt; and I needed a Postgresql database &lt;em&gt;quick&lt;/em&gt;. My search got a lot of results that were similar, but different enough for me to lose confidence in any given solution. I spent a little time searching for a simple configuration and this is what I came up with. For those of you in a rush, copy and paste away:&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;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;3.8"&lt;/span&gt;

&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;postgres&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgres:13-alpine&lt;/span&gt;
    &lt;span class="na"&gt;restart&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;always&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;5432:5432"&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;POSTGRES_USER&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;username&lt;/span&gt;
      &lt;span class="na"&gt;POSTGRES_PASSWORD&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;password&lt;/span&gt;
      &lt;span class="na"&gt;POSTGRES_DB&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgres&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;./data:/var/lib/postgresql/data\&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, for the rest of you who aren’t even sure why this is necessary or aren’t sure why there are so many suggestions when you search for this problem, let’s dig in.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Docker at all?
&lt;/h2&gt;

&lt;p&gt;In my career, it has been immeasurably beneficial to make sure that the low level technologies and languages I am relying upon are “insulated” from the computer I am developing on. By insulated, I mean it is best to use Docker or a version manager (e.g. &lt;code&gt;rbenv&lt;/code&gt;, &lt;code&gt;pyenv&lt;/code&gt;, &lt;code&gt;nvm&lt;/code&gt;, ...) rather than installing a technology directly on to your operating system.&lt;/p&gt;

&lt;p&gt;For example, when you use an already installed language (like python on MacOS) you run the risk of breaking how your OS functions. When you install a language directly (e.g. &lt;code&gt;brew install python&lt;/code&gt; on MacOS) you run the risk of packages conflicting.&lt;/p&gt;

&lt;p&gt;Using a version manager allows you to easily reset the installation of a language if anything goes wrong. Presuming your configuration and package manifests are intact you should have an easy time getting back up and running. Using a version manager also helps you run different version of a language or database for different projects so you can easily switch between them.&lt;/p&gt;

&lt;p&gt;Running your DB inside of docker can be thought as the ultimate version manager, it not only keeps different versions separate from each other, it keeps each version isolated in its own virtual machine.&lt;/p&gt;

&lt;h2&gt;
  
  
  Docker-compose vs &lt;code&gt;docker run&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;When looking for a “minimally viable” way to get Postgres running the results were fairly evenly split between suggestions using &lt;code&gt;docker run&lt;/code&gt; and suggestions using &lt;code&gt;docker-compose&lt;/code&gt;. &lt;code&gt;docker run&lt;/code&gt; is a way of running commands inside of a docker container, if the container does not exist it will create it before running the command. &lt;code&gt;docker-compose&lt;/code&gt; prompts docker to run a variety of commands (&lt;code&gt;up&lt;/code&gt;, &lt;code&gt;down&lt;/code&gt;, &lt;code&gt;stop&lt;/code&gt;) relative to a &lt;code&gt;docker-compose.yml&lt;/code&gt; configuration file. There are a lot of differences between the two methods, but syntactically you can think of the difference between them as the difference between passing all of your &lt;code&gt;eslint&lt;/code&gt; options as flags in the command line and running &lt;code&gt;eslint&lt;/code&gt; in conjunction with an &lt;code&gt;.eslintrc&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;Using a &lt;code&gt;docker-compose.yml&lt;/code&gt; file is the easier route, as it is the more legible of the two options.&lt;/p&gt;

&lt;h2&gt;
  
  
  Exploded &lt;code&gt;docker-compose.yml&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;What is the &lt;code&gt;docker-compose.yml&lt;/code&gt; file doing? Let's go line by line.&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;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;3.8"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;docker-compose.yml&lt;/code&gt; API has different versions, this is something to be keenly aware of while researching and creating your configuration. It is typically best to use the &lt;a href="https://docs.docker.com/compose/compose-file/"&gt;latest version&lt;/a&gt;. You should also check what version of Docker Engine you are running.&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;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;postgres&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A typical &lt;code&gt;docker-compose.yml&lt;/code&gt; in a professional environment will have several services configured to work together. For our purpose we only need the one. The key for your service is arbitrary, you could name it &lt;code&gt;db&lt;/code&gt; or &lt;code&gt;banana&lt;/code&gt;, but for organizational purposes it makes most sense to match the key to the Docker image you are relying upon.&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;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgres:13-alpine&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the image tag, the list of available options is available on &lt;a href="https://hub.docker.com/_/postgres"&gt;Docker Hub&lt;/a&gt;. &lt;code&gt;postgres&lt;/code&gt; refers to the Docker image you would like to use. &lt;code&gt;13-alpine&lt;/code&gt; is a tag of the image with &lt;code&gt;13&lt;/code&gt; referring to the version of Postgres you would like to use and &lt;code&gt;alpine&lt;/code&gt; denoting a flavor of linux that is stripped down to be as small as possible. You can always specify simply &lt;code&gt;postgres&lt;/code&gt; or &lt;code&gt;postgres:latest&lt;/code&gt; if size or version doesn't matter to you.&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;restart&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;always&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What it says on the label! &lt;a href="https://docs.docker.com/compose/compose-file/#restart"&gt;Always restart&lt;/a&gt; this container when docker engine starts.&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;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;5432:5432"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This forwards the &lt;a href="https://docs.docker.com/compose/compose-file/#ports"&gt;Docker containers ports&lt;/a&gt; to your machine's ports. &lt;code&gt;5432&lt;/code&gt; is PostgreSQL's &lt;a href="https://www.postgresql.org/docs/current/app-postgres.html"&gt;default port&lt;/a&gt;. You should only need to change this if you have a conflicting process using the same port.&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;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;POSTGRES_USER&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;prisma&lt;/span&gt;
  &lt;span class="na"&gt;POSTGRES_PASSWORD&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;prisma&lt;/span&gt;
  &lt;span class="na"&gt;POSTGRES_DB&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;tabata&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;While there are other &lt;a href="https://hub.docker.com/_/postgres"&gt;environment variables available&lt;/a&gt; for your PostgreSQL container, this is all you need to get the container running. If the container and database do not yet exist &lt;code&gt;docker-compose up&lt;/code&gt; will create a database with this name, user, and password.&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;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;./data:/var/lib/postgresql/data\&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://docs.docker.com/compose/compose-file/#volume-configuration-reference"&gt;Volumes&lt;/a&gt; allow your data to persist in-between bringing your container up and down. This tells docker where to store that persisted data and links it to the location within your container.&lt;/p&gt;

&lt;h2&gt;
  
  
  You know something I don't?
&lt;/h2&gt;

&lt;p&gt;If you've made it to the end and you see a way to make this configuration even leaner, please let me know!&lt;/p&gt;

</description>
      <category>docker</category>
      <category>postgres</category>
      <category>database</category>
      <category>webdev</category>
    </item>
    <item>
      <title>I published my first Ember Addon</title>
      <dc:creator>i. welch canavan</dc:creator>
      <pubDate>Wed, 19 Feb 2020 03:53:33 +0000</pubDate>
      <link>https://dev.to/xiwcx/i-published-my-first-ember-addon-138c</link>
      <guid>https://dev.to/xiwcx/i-published-my-first-ember-addon-138c</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://xiw.cx/2wqxO3b"&gt;welchcanavan.com&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt;: &lt;em&gt;a new &lt;a href="https://github.com/Mariana-Tek/ember-fullcalendar"&gt;ember-fullcalendar&lt;/a&gt; addon based on Fullcalendar v4 is released this week. Here is some of my process and experience.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Backstory
&lt;/h2&gt;

&lt;p&gt;My day job is working on a large &lt;a href="https://en.wikipedia.org/wiki/Software_as_a_service"&gt;SaaS&lt;/a&gt; application at &lt;a href="https://marianatek.com/"&gt;Mariana Tek&lt;/a&gt;. We help boutique gyms with their business operations, which means our application serves a lot of purposes: point of sale, time clock, class scheduler, and a lot more. Having to write all this functionality from scratch would be difficult if not impossible, so I'm grateful for plugins in general and Ember's painless &lt;a href="https://guides.emberjs.com/release/addons-and-dependencies/"&gt;addon&lt;/a&gt; system in particular.&lt;/p&gt;

&lt;p&gt;While our application is on an earlier version Ember 3, we're in the process of a long walk to the exciting &lt;a href="https://blog.emberjs.com/2019/12/20/octane-is-here.html"&gt;Ember Octane&lt;/a&gt;. Part of this process has been gradually updating our addons. Our application, which is over four years old, had accrued some addons that are now abandoned. Most of these were easy to address, with one big exception - &lt;a href="https://fullcalendar.io/"&gt;Fullcalendar&lt;/a&gt;. Fullcalendar is a fantastic tool that allows the user to provide a fully-featured scheduling calendar (e.g. Google Calendar) with minimal code. The Ember Fullcalendar addon hadn't been updated in over a year and I really didn't want to write a calendar from the ground up. The writing was on the wall; I was going to have to write my first Ember addon.&lt;/p&gt;

&lt;h2&gt;
  
  
  Well, not quite...
&lt;/h2&gt;

&lt;p&gt;In actuality, my first inclination was to see if I could chip in with the &lt;em&gt;current&lt;/em&gt; Ember Fullcalendar plugin, but I found that Fullcalendar had done a major upgrade moving from &lt;a href="https://fullcalendar.io/docs/upgrading-from-v3"&gt;version 3 to version 4&lt;/a&gt;;  having removed &lt;a href="https://jquery.com/"&gt;jQuery&lt;/a&gt; and &lt;a href="https://momentjs.com/"&gt;Moment&lt;/a&gt; as dependencies, and updated their API. If I wanted to fully get rid of jQuery as a dependency in our app it seemed I would have start from scratch.&lt;/p&gt;

&lt;h2&gt;
  
  
  Inspiration
&lt;/h2&gt;

&lt;p&gt;If I couldn't improve the current addon or use it as a guide for my new addon then what could I look at? For the Ember side of things I went to &lt;a href="https://emberobserver.com/"&gt;Ember Observer&lt;/a&gt;, a great resource for finding quality addons. I read through some of the popular addons that provide a similar service (bindings to a popular Javascript UI utility). This provided some hints and ideas for structure, but I still needed some ideas for the Fullcalendar side of things. I thought I'd take a peek at the &lt;a href="https://github.com/fullcalendar/fullcalendar-react"&gt;&lt;code&gt;fullcalendar-react&lt;/code&gt;&lt;/a&gt; package and was pleasantly surprised to find that it barely breaks fifty lines of code.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;fullcalendar-react&lt;/code&gt; provided the idea to avoid explicit bindings for each property or attribute and simply batch updates and pass them along to Fullcalendar. &lt;code&gt;componentDidMount()&lt;/code&gt; becomes &lt;code&gt;didInsertElement()&lt;/code&gt;, while &lt;code&gt;componentDidUpdate()&lt;/code&gt; becomes &lt;code&gt;didUpdateAttrs()&lt;/code&gt;. This makes the addon easier to maintain as I can upgrade its Fullcalendar dependency version with minimal updates to the addon's code. The Ember best practice of &lt;a href="https://dockyard.com/blog/2015/10/14/best-practices-data-down-actions-up"&gt;Data Down, Actions Up&lt;/a&gt; aligns well with React's philosophy and if you account for differences in each framework's API many patterns are easily transferable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it out
&lt;/h2&gt;

&lt;p&gt;The addon can be installed using &lt;code&gt;ember install @mariana-tek/ember-fullcalendar&lt;/code&gt;. You can find further instruction in the &lt;a href="https://github.com/Mariana-Tek/ember-fullcalendar#mariana-tekember-fullcalendar"&gt;documentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Please feel free to check out the &lt;a href="https://github.com/Mariana-Tek/ember-fullcalendar/blob/master/addon/components/full-calendar.js"&gt;source code&lt;/a&gt; or &lt;a href="https://github.com/Mariana-Tek/ember-fullcalendar/issues"&gt;report an issue&lt;/a&gt;. Enjoy!&lt;/p&gt;

&lt;h3&gt;
  
  
  Acknowledgement
&lt;/h3&gt;

&lt;p&gt;Thanks to my employer for the support in making this! If you think you'd like to work on a kind and supportive team that talks Ember, React, and—above all—Javascript, please &lt;a href="https://marianatek.com/careers"&gt;check us out&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>ember</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Why I Lint Everything</title>
      <dc:creator>i. welch canavan</dc:creator>
      <pubDate>Sun, 17 Nov 2019 23:09:51 +0000</pubDate>
      <link>https://dev.to/xiwcx/why-i-lint-everything-21h7</link>
      <guid>https://dev.to/xiwcx/why-i-lint-everything-21h7</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://xiw.cx/32WzkEX"&gt;welchcanavan.com&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I lint everything. No, really. If I'm working on a project—personal or professional—that I believe will outlast the day, installing linters is one of the very first steps I take. If you're unfamiliar with &lt;a href="https://en.wikipedia.org/wiki/Lint_(software)"&gt;linters&lt;/a&gt;, they're a tool that help web developers (or any programmers) avoid bugs, errors, and anti-patterns while enforcing consistent style.&lt;/p&gt;

&lt;p&gt;Linters have helped me become a better developer and they have helped me stay a better developer. They can help you do the same. Aside from their stated intentions they can also help you learn best practices as well as how to function on a team.&lt;/p&gt;

&lt;h2&gt;
  
  
  Linting to challenge yourself
&lt;/h2&gt;

&lt;p&gt;First off, I pick an aggressive linter. If I am writing Javscript I tend towards &lt;a href="https://www.npmjs.com/package/eslint-config-airbnb"&gt;Airbnb&lt;/a&gt;'s configuration, if I am writing CSS I use stylelint's &lt;a href="https://github.com/stylelint/stylelint-config-standard"&gt;standard&lt;/a&gt; configuration over their &lt;a href="https://github.com/stylelint/stylelint-config-recommended"&gt;recommended&lt;/a&gt; configuration. For writing JSX I throw an &lt;a href="https://github.com/evcohen/eslint-plugin-jsx-a11y"&gt;a11y accessibility configuration&lt;/a&gt; on top of the heap as well.&lt;/p&gt;

&lt;p&gt;Second, I install the linter almost immediately, usually before my first commit. This is typically an infuriating experience. If it is my first time using a language or framework &lt;em&gt;and&lt;/em&gt; a new linter I find I can scarcely write a line of code without making the linter angry and provoking lots of glaring red warnings in my text editor. For every linter message I do not understand, I visit the accompanying documentation page and read it top to bottom until I understand. If that fails, I start searching for other people who encountered the same message under similar conditions.&lt;/p&gt;

&lt;p&gt;While this makes for a slow start, I am much more productive once I am over the initial learning curve. For example, I do not waste nearly as much time as I used to banging my head against the idiosyncrasies of a new framework's API.&lt;/p&gt;

&lt;h2&gt;
  
  
  Linting to become a better collaborator
&lt;/h2&gt;

&lt;p&gt;You will never be on a team that is completely aligned on best practices. Part of being a great team member is setting your ego aside and recognizing that it is much more important to agree on &lt;em&gt;a&lt;/em&gt; standard than &lt;em&gt;your&lt;/em&gt; standard.&lt;/p&gt;

&lt;p&gt;If you are already employed it makes the most sense to grab an off the shelf solution and avoid wasting time &lt;a href="https://en.wiktionary.org/wiki/bikeshedding"&gt;bikeshedding&lt;/a&gt;. Bespoke linting configurations tend to lead to a hodgepodge of individuals' preferences that cannot be easily unraveled as team members inevitably join and leave.&lt;/p&gt;

&lt;p&gt;If you have not had the opportunity to work on a team yet linters are a great way to learn how to compromise ahead of joining a team. I do not always agree with 100% of the configuration in a linter, but reading the documentation helps me to get a sense of how &lt;em&gt;other&lt;/em&gt; people think about code, and I am often compelled to change my mind.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to get started linting
&lt;/h2&gt;

&lt;p&gt;There are a lot of ways to lint code. The linter can be run during your &lt;a href="https://en.m.wikipedia.org/wiki/Continuous_integration"&gt;CI&lt;/a&gt; step using a tool like &lt;a href="https://circleci.com/"&gt;Circle&lt;/a&gt;, &lt;a href="https://jenkins.io/"&gt;Jenkins&lt;/a&gt;, or &lt;a href="https://docs.gitlab.com/ee/ci/"&gt;Gitlab&lt;/a&gt;. The linter can be run via a &lt;a href="https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks"&gt;Git pre-commit&lt;/a&gt; hook (there are integrations for most popular languages like &lt;a href="https://github.com/observing/pre-commit"&gt;Node&lt;/a&gt; or &lt;a href="https://pre-commit.com/"&gt;Python&lt;/a&gt;). My preferred method is to lint live in my text editor or IDE. An internet search should find a plugin for your preferred text editor and a popular linter (e.g. &lt;a href="https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint"&gt;ESLint for VSCode&lt;/a&gt;). Linting in your editor will provide you with real time feedback on your code, and a good code editor will provide you with a link directly to the documentation for that rule. Additionally, there are &lt;a href="https://eslint.org/docs/user-guide/getting-started"&gt;lots&lt;/a&gt; &lt;a href="https://css-tricks.com/stylelint/"&gt;of&lt;/a&gt; &lt;a href="https://dev.to/jameesy/the-absolute-beginners-guide-to-linting-45a1"&gt;guides&lt;/a&gt; to get you started.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--IVY4d6Ce--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://d28efhqsv6dyl0.cloudfront.net/media/uploads/ad901924db/Screen_Shot_2019-11-17_at_5.36.44_PM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--IVY4d6Ce--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://d28efhqsv6dyl0.cloudfront.net/media/uploads/ad901924db/Screen_Shot_2019-11-17_at_5.36.44_PM.png" alt="screenshot of linter display in a code editor"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;It's probably clear that this approach will not work for everyone; I’m sure this level of overhead would be too much for many people and get in the way of a creative spark. All the same, I encourage you to give it a shot and see if this process works for you. I’ve gained a lot of knowledge and patience through this practice and I’m certain others could too.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>css</category>
      <category>linting</category>
    </item>
    <item>
      <title>I Made A Package Lock Inspector With React Hooks, Ramda, and Deepdash</title>
      <dc:creator>i. welch canavan</dc:creator>
      <pubDate>Mon, 11 Nov 2019 03:01:51 +0000</pubDate>
      <link>https://dev.to/xiwcx/i-made-a-package-lock-inspector-with-react-hooks-ramda-and-deepdash-29jo</link>
      <guid>https://dev.to/xiwcx/i-made-a-package-lock-inspector-with-react-hooks-ramda-and-deepdash-29jo</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://xiw.cx/2CyMk8M"&gt;welchcanavan.com&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I have been having a hard time at work getting to the bottom of a dependency issue. As a result, I have spent far more time than I would like to manually parsing &lt;code&gt;package-lock.json&lt;/code&gt;. Eventually, I thought "someone has to have made a tool for this" and &lt;a href="https://compulim.github.io/lock-walker"&gt;someone did&lt;/a&gt;! &lt;a href="https://github.com/compulim"&gt;William Wong&lt;/a&gt;'s &lt;a href="https://github.com/compulim/lock-walker"&gt;lock-walker&lt;/a&gt; was very helpful while trying to debug my problem. However, there were some improvements I thought I could make on the tool:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Ability to navigate using the browser's history&lt;/li&gt;
&lt;li&gt;Ability to have more than one tab or window open&lt;/li&gt;
&lt;li&gt;A faster filter&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I'm not going to go very deep in to how I wrote the app, as I learned a lot of disparate things on this project, but I do want to touch on some of the tools that helped me solve the problem.&lt;/p&gt;

&lt;p&gt;Goals 1 and 2 were easily accomplished using hooks. With &lt;a href="https://reacttraining.com/react-router/web/api/Hooks/usehistory"&gt;&lt;code&gt;useHistory&lt;/code&gt;&lt;/a&gt; and &lt;a href="https://reacttraining.com/react-router/web/api/Hooks/uselocation"&gt;&lt;code&gt;uselocation&lt;/code&gt;&lt;/a&gt; from &lt;a href="https://reacttraining.com/react-router/web/"&gt;React Router&lt;/a&gt; I was able to set the URL when searching and get the URL whenever it changed to trigger the filter. With &lt;a href="https://github.com/streamich/react-use/blob/master/docs/useLocalStorage.md"&gt;&lt;code&gt;useLocalStorage&lt;/code&gt;&lt;/a&gt; from &lt;a href="https://streamich.github.io/react-use"&gt;react-use&lt;/a&gt; I was able to  persist the uploaded packages.&lt;/p&gt;

&lt;p&gt;This was my first project using &lt;a href="https://reactjs.org/docs/hooks-intro.html"&gt;React Hooks&lt;/a&gt; and they are satisfying to say the least. I got a lot of mileage out of them &lt;a href="https://github.com/streamich/react-use/blob/master/docs/useDebounce.md"&gt;&lt;code&gt;useDebounce&lt;/code&gt;&lt;/a&gt; and I also used &lt;a href="https://github.com/streamich/react-use/blob/master/docs/useMeasure.md"&gt;&lt;code&gt;useMeasure&lt;/code&gt;&lt;/a&gt; to power my project's &lt;a href="https://dev.to/xiwcx/simple-element-queries-with-react-hooks-253j"&gt;element queries&lt;/a&gt;.&lt;/p&gt;


&lt;div class="ltag__link"&gt;
  &lt;a href="/xiwcx" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fSp_mNTV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/practicaldev/image/fetch/s--8CBGoitZ--/c_fill%2Cf_auto%2Cfl_progressive%2Ch_150%2Cq_auto%2Cw_150/https://dev-to-uploads.s3.amazonaws.com/uploads/user/profile_image/78346/653b6169-04fb-4c17-b76a-35f81c265a15.jpg" alt="xiwcx"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="/xiwcx/simple-element-queries-with-react-hooks-253j" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;Simple Element Queries With React Hooks&lt;/h2&gt;
      &lt;h3&gt;i. welch canavan ・ Nov 5 '19 ・ 3 min read&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#javascript&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#react&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#hooks&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#css&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


&lt;p&gt;The third goal, making the filter faster, was the most challenging part of the project. I had to figure out how to filter the package dependency tree down to matches &lt;em&gt;and&lt;/em&gt; their parents, excluding irrelevant children and siblings. Thankfully, I found &lt;a href="https://deepdash.io"&gt;Deepdash&lt;/a&gt;—a tree traversal extension for &lt;a href="https://lodash.com/docs"&gt;lodash&lt;/a&gt;—which took care of a lot of the heavy lifting. Deepdash's &lt;code&gt;reduceDeep&lt;/code&gt; with &lt;code&gt;leavesOnly&lt;/code&gt; set to true allowed me to visit every childless node, trim the path if necessary, and collect it in the final filtered tree. &lt;a href="https://ramdajs.com/"&gt;Ramda&lt;/a&gt;'s &lt;a href="https://ramdajs.com/docs/#set"&gt;&lt;code&gt;set&lt;/code&gt;&lt;/a&gt; and &lt;a href="https://ramdajs.com/docs/#lensPath"&gt;&lt;code&gt;lensPath&lt;/code&gt;&lt;/a&gt; came in handy setting new values on the reducer's accumulator in a performant and immutable fashion.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://welchcanavan.gitlab.io/package-lock-inspecto/"&gt;Package Lock Inspector&lt;/a&gt; is live now and you can also view it's &lt;a href="https://gitlab.com/welchcanavan/package-lock-inspector"&gt;source&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>npm</category>
      <category>react</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Simple Element Queries With React Hooks</title>
      <dc:creator>i. welch canavan</dc:creator>
      <pubDate>Tue, 05 Nov 2019 01:55:00 +0000</pubDate>
      <link>https://dev.to/xiwcx/simple-element-queries-with-react-hooks-253j</link>
      <guid>https://dev.to/xiwcx/simple-element-queries-with-react-hooks-253j</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://xiw.cx/2NeNNqY"&gt;welchcanavan.com&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;During the interminable wait for &lt;a href="https://css-tricks.com/lets-not-forget-about-container-queries/"&gt;element queries&lt;/a&gt; it is difficult to not run ahead and experiment with their immense potential. Though there are a few options for using them in your CSS today, the two primary options (&lt;a href="https://github.com/eqcss/eqcss"&gt;EQCSS&lt;/a&gt; and &lt;a href="https://github.com/marcj/css-element-queries"&gt;CSS Element Queries&lt;/a&gt;) have differing APIs with no clear winner. I try to avoid committing to fluctuating syntaxes in my projects, as I prefer solutions that are more explicit. I've written a few iterations of custom solutions in a few frameworks, but haven't been very happy with them so far. While working on a side project recently I found that &lt;a href="https://reactjs.org/docs/hooks-intro.html"&gt;React Hooks&lt;/a&gt; provide a concise and satisfying solution.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Component
&lt;/h2&gt;

&lt;p&gt;I'm going to presume a general familiarity with React Hooks for this article, but if you would like to familiarize yourself with them you would be hard pressed to do better than &lt;a href="https://dev.to/dan_abramov/making-sense-of-react-hooks-2eib"&gt;Dan Abromov's introduction&lt;/a&gt;. While you could write a custom hook relying on &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver"&gt;&lt;code&gt;ResizeObserver&lt;/code&gt;&lt;/a&gt; directly or &lt;a href="https://www.npmjs.com/package/element-resize-detector"&gt;&lt;code&gt;element-resize-detector&lt;/code&gt;&lt;/a&gt; (if you need broader browser support), I'm relying on the &lt;a href="https://github.com/streamich/react-use/blob/master/docs/useMeasure.md"&gt;&lt;code&gt;useMeasure&lt;/code&gt;&lt;/a&gt; hook from &lt;code&gt;react-use&lt;/code&gt;. If you haven't come across &lt;code&gt;react-use&lt;/code&gt; it is a collection of battle-tested and crowd-sourced React Hooks that address common use cases.&lt;/p&gt;

&lt;p&gt;This example also relies on the &lt;a href="https://github.com/JedWatson/classnames"&gt;&lt;code&gt;classnames&lt;/code&gt;&lt;/a&gt; package. You could absolutely write a version of this that uses CSS-in-JS, but I've got this crazy hangup about legible code, so my example is written with &lt;code&gt;classnames&lt;/code&gt; and &lt;a href="https://sass-lang.com/"&gt;&lt;code&gt;Sass&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Here is a contrived example of what a React functional component conditionally styled by width could look 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="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;classNames&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;classnames&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useMeasure&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react-use&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;MyComponent&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="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;width&lt;/span&gt; &lt;span class="p"&gt;}]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useMeasure&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;containerClasses&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;classNames&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;container&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;container--md&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;width&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;800&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="p"&gt;(&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;containerClasses&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="cm"&gt;/* All of your cool component stuff */&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&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;h2&gt;
  
  
  The styles
&lt;/h2&gt;

&lt;p&gt;The accompanying styles can be written like so, working up from small to large. Again, the following code is contrived, but the sky is the limit in terms of potential.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scss"&gt;&lt;code&gt;&lt;span class="nc"&gt;.container&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;red&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nt"&gt;--md&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;blue&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I've found that element queries can be very powerful with CSS Grid and &lt;code&gt;grid-template-areas&lt;/code&gt;, allowing you to drop a component in to any layout and have its contents arranged logically.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scss"&gt;&lt;code&gt;&lt;span class="nc"&gt;.container&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nt"&gt;--md&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;grid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="na"&gt;grid-template-areas&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="s2"&gt;"A A"&lt;/span&gt;
            &lt;span class="s2"&gt;"B C"&lt;/span&gt;
        &lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="na"&gt;grid-template-columns&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1fr&lt;/span&gt; &lt;span class="m"&gt;1fr&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nt"&gt;--lg&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;grid-template-areas&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"A B C"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="na"&gt;grid-template-columns&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1fr&lt;/span&gt; &lt;span class="m"&gt;2fr&lt;/span&gt; &lt;span class="m"&gt;1fr&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Keeping it DRY
&lt;/h2&gt;

&lt;p&gt;To provide your app with some consistency you could write a utility function like so:&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;const&lt;/span&gt; &lt;span class="nx"&gt;generateWidthClasses&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;containerClassName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;sizes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Object&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sizes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;sizesObj&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;size&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;sizesObj&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;containerClassName&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;--&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;size&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;width&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="nx"&gt;sizes&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;size&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;sizesObj&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You could then use that utility function across many components:&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;containerSizes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;sm&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;600&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;md&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;800&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;lg&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1000&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;MyComponent&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="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;width&lt;/span&gt; &lt;span class="p"&gt;}]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useMeasure&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;containerClasses&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;classNames&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;container&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="nx"&gt;generateWidthClasses&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;container&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;containerSizes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  All Together Now
&lt;/h2&gt;

&lt;p&gt;If you'd like to explore this idea further, here's a working example:&lt;/p&gt;

&lt;p&gt;&lt;iframe src="https://codesandbox.io/embed/simple-element-queries-with-react-hooks-l61v6"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;The web development community has only scratched the surface of element queries' potential, I can only imagine what people will come up with once element queries are easier and more common. If anyone builds on this idea, I'd love to hear from you!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>react</category>
      <category>hooks</category>
      <category>css</category>
    </item>
  </channel>
</rss>
