<?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: Home Officer</title>
    <description>The latest articles on DEV Community by Home Officer (@wolframkriesing).</description>
    <link>https://dev.to/wolframkriesing</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%2F62570%2F245b89af-a95c-4b8d-84e1-fc22edf421d6.jpg</url>
      <title>DEV Community: Home Officer</title>
      <link>https://dev.to/wolframkriesing</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/wolframkriesing"/>
    <language>en</language>
    <item>
      <title>Building PicoSSG: 'Just Enough Code'</title>
      <dc:creator>Home Officer</dc:creator>
      <pubDate>Fri, 16 May 2025 16:50:47 +0000</pubDate>
      <link>https://dev.to/wolframkriesing/building-picossg-just-enough-code-3ad7</link>
      <guid>https://dev.to/wolframkriesing/building-picossg-just-enough-code-3ad7</guid>
      <description>&lt;p&gt;This is the story of how &lt;a href="https://picossg.dev" rel="noopener noreferrer"&gt;PicoSSG&lt;/a&gt; came to be - from its humble beginnings as a minimal static site generator to its current form. &lt;br&gt;
It's a journey about finding the sweet spot between features and simplicity, about writing "just enough code" to get the job done without unnecessary complexity.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Genesis of PicoSSG
&lt;/h2&gt;

&lt;p&gt;The static site generator (SSG) landscape is crowded with feature-rich but increasingly complex solutions. &lt;br&gt;
As I looked at and used tools like &lt;a href="https://lume.land/" rel="noopener noreferrer"&gt;lume&lt;/a&gt;, &lt;a href="https://www.11ty.dev" rel="noopener noreferrer"&gt;11ty&lt;/a&gt;, &lt;a href="https://www.getlektor.com/" rel="noopener noreferrer"&gt;lektor&lt;/a&gt;, or &lt;a href="https://jekyllrb.com/" rel="noopener noreferrer"&gt;jekyll&lt;/a&gt;, &lt;br&gt;
I found myself drowning in configuration options, plugins, and middleware. &lt;br&gt;
What started as a simple desire to convert Markdown content into HTML had evolved into learning complex frameworks with steep learning curves.&lt;/p&gt;

&lt;p&gt;I wanted something &lt;strong&gt;radically simple&lt;/strong&gt; – a tool that would do just what I see an SSG needs to do: &lt;strong&gt;markdown, templating, and simple data handling&lt;/strong&gt;. &lt;br&gt;
The vision was clear: process templates and markdown files predictably, with minimal dependencies and a non-magic transformation process.&lt;/p&gt;

&lt;p&gt;On a spring day in April 2025, &lt;a href="https://codeberg.org/wolframkriesing/picossg/commit/cf6b5bc" rel="noopener noreferrer"&gt;the very first lines of code&lt;/a&gt; emerged with a &lt;br&gt;
commit message that says it all: "The simplest processor, I think." This established the minimalist approach that would guide the entire project. &lt;br&gt;
Just a few lines of code to process &lt;a href="https://mozilla.github.io/nunjucks/" rel="noopener noreferrer"&gt;nunjucks&lt;/a&gt; templates and nothing more.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://codeberg.org/wolframkriesing/picossg/commit/b42be67ea6da9abd7e588767be83b6e400489e72" rel="noopener noreferrer"&gt;second commit was a simple test&lt;/a&gt; &lt;br&gt;
to ensure the processor worked as expected, I just have this testing in my blood.&lt;br&gt;
I mean how can one write software that grows and becomes bigger than what one can hold in their head without testing?&lt;br&gt;&lt;br&gt;
Even the testing must be simple, so I just compared the output with the expected output using the &lt;code&gt;diff&lt;/code&gt; command, and that's how &lt;br&gt;
PicoSSG still works.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Minimal and Maximum Feature Set
&lt;/h2&gt;

&lt;p&gt;From day one, I defined a clear boundary around what PicoSSG would and wouldn't do. The minimal feature set was non-negotiable:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Markdown processing&lt;/strong&gt; - For content-focused writing without HTML clutter&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Nunjucks templating&lt;/strong&gt; - For layout flexibility and component reuse (introduced in &lt;a href="https://codeberg.org/wolframkriesing/picossg/commit/03a5f7a" rel="noopener noreferrer"&gt;the project's first week&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;1:1 file mapping&lt;/strong&gt; - Direct correspondence between source and output files, preserving structure &lt;a href="https://codeberg.org/wolframkriesing/picossg/commit/4266749" rel="noopener noreferrer"&gt;without hidden transformations&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Simple JS configuration&lt;/strong&gt; - A single entry point for extending functionality through JavaScript&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Just as important were the deliberate limitations - features PicoSSG would never implement:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Do the job without configuration and plugins&lt;/li&gt;
&lt;li&gt;No hidden magic or implicit transformations &lt;/li&gt;
&lt;li&gt;No dependencies beyond absolute necessities&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The power of PicoSSG would come not from feature abundance but from its extensibility through a simple JavaScript interface. &lt;br&gt;
Need to process data? Write a function &lt;code&gt;preprocess()&lt;/code&gt; or &lt;code&gt;postprocess()&lt;/code&gt; in &lt;code&gt;_config.js&lt;/code&gt;, there is no more.&lt;br&gt;
Need custom template filters, extend nunjucks (not picossg!)? Create them in &lt;code&gt;_njk-custom/filters.js&lt;/code&gt;. &lt;br&gt;
This approach maximizes flexibility if needed while keeping the code small.&lt;/p&gt;

&lt;h2&gt;
  
  
  v1 – The Minimal Viable Product
&lt;/h2&gt;

&lt;p&gt;A critical early feature was component inclusion. Rather than creating a complex component system, &lt;br&gt;
PicoSSG adopted a simple convention: files starting with underscore (&lt;code&gt;_&lt;/code&gt;) would be excluded from output but available for inclusion. &lt;br&gt;
This &lt;a href="https://codeberg.org/wolframkriesing/picossg/commit/3f5389c" rel="noopener noreferrer"&gt;elegant approach&lt;/a&gt; allowed for reusable components without special handling.&lt;/p&gt;

&lt;p&gt;Testing was also simple but effective - a straightforward comparison between generated output and expected results. &lt;br&gt;
By the end of the first day, a &lt;a href="https://codeberg.org/wolframkriesing/picossg/commit/b42be67" rel="noopener noreferrer"&gt;basic test setup&lt;/a&gt; was in place that would evolve but remain fundamentally simple.&lt;/p&gt;

&lt;p&gt;Within 24 hours of the project's birth, &lt;a href="https://codeberg.org/wolframkriesing/picossg/commit/7db8629" rel="noopener noreferrer"&gt;PicoSSG had a README&lt;/a&gt; &lt;br&gt;
and was taking shape as a usable tool, albeit with limited features.&lt;/p&gt;

&lt;h2&gt;
  
  
  Evolving the Foundation: v2
&lt;/h2&gt;

&lt;p&gt;About a week into development, a breakthrough came with the message &lt;a href="https://codeberg.org/wolframkriesing/picossg/commit/4499675" rel="noopener noreferrer"&gt;"Now the front-matter block parsing is completely dynamic"&lt;/a&gt;. &lt;br&gt;
This allowed metadata to be associated with content without complex infrastructure. &lt;br&gt;
The decision process is documented in &lt;a href="https://codeberg.org/wolframkriesing/picossg/src/branch/main/docs/adr/001-no-extends.md" rel="noopener noreferrer"&gt;ADR-001&lt;/a&gt;, &lt;br&gt;
which compares different approaches and ultimately selects front-matter for its compatibility with other tools and clean syntax.&lt;/p&gt;

&lt;p&gt;The extension processing pipeline also matured during this period. The next morning brought &lt;a href="https://codeberg.org/wolframkriesing/picossg/commit/eba222d" rel="noopener noreferrer"&gt;a key insight&lt;/a&gt; &lt;br&gt;
that established the right-to-left processing of extensions, allowing combined file types like &lt;code&gt;.html.md.njk&lt;/code&gt; to be processed in sequence.&lt;br&gt;
Processing simply stops when there is no more "known" extension to process. Theoretically, one could also build a file such &lt;br&gt;
as &lt;code&gt;index.html.md.njk.md.md.md.njk&lt;/code&gt;. Not sure that makes sense though :).&lt;/p&gt;

&lt;p&gt;After a weekend of experimentation, custom filters &lt;a href="https://codeberg.org/wolframkriesing/picossg/commit/af27632" rel="noopener noreferrer"&gt;became possible&lt;/a&gt;, &lt;br&gt;
and by the following evening, the project &lt;a href="https://codeberg.org/wolframkriesing/picossg/commit/5ef22d7" rel="noopener noreferrer"&gt;added two default filters&lt;/a&gt;: &lt;code&gt;md&lt;/code&gt; and &lt;code&gt;mdinline&lt;/code&gt; &lt;br&gt;
for Markdown processing within templates.&lt;/p&gt;

&lt;h2&gt;
  
  
  Architectural Decisions That Shaped PicoSSG
&lt;/h2&gt;

&lt;p&gt;Several key architectural decisions shaped PicoSSG's development, many documented as Architecture Decision Records (ADRs):&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://codeberg.org/wolframkriesing/picossg/src/branch/main/docs/adr/001-no-extends.md" rel="noopener noreferrer"&gt;ADR-001&lt;/a&gt; explored different approaches to handling mixed &lt;a href="https://daringfireball.net/projects/markdown/" rel="noopener noreferrer"&gt;Markdown&lt;/a&gt; and &lt;a href="https://mozilla.github.io/nunjucks/" rel="noopener noreferrer"&gt;Nunjucks&lt;/a&gt; content, ultimately selecting front-matter as the simplest approach that maintained compatibility with other tools.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://codeberg.org/wolframkriesing/picossg/src/branch/main/docs/adr/002-processor-might-modify-files.md" rel="noopener noreferrer"&gt;ADR-002&lt;/a&gt; made the important design decision to allow user processors to modify the files map directly, optimizing for performance and memory efficiency at the cost of potential side effects.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://codeberg.org/wolframkriesing/picossg/src/branch/main/docs/adr/003-use-markdown-it.md" rel="noopener noreferrer"&gt;ADR-003&lt;/a&gt; documented the choice of &lt;a href="https://markdown-it.github.io/" rel="noopener noreferrer"&gt;markdown-it&lt;/a&gt; over alternatives like &lt;a href="https://marked.js.org/" rel="noopener noreferrer"&gt;marked&lt;/a&gt;, based on careful evaluation of edge cases and built-in features like URL linking.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The decision to avoid framework dependencies and stick to a minimal set of npm packages was not formally documented but is evident throughout the codebase. This approach kept the tool lightweight and reduced potential points of failure from external dependencies.&lt;/p&gt;

&lt;h2&gt;
  
  
  v3 – Maturing the Codebase
&lt;/h2&gt;

&lt;p&gt;Version 3.0 represented a significant maturation of PicoSSG while remaining true to its minimalist principles. In mid-May, &lt;br&gt;
&lt;a href="https://codeberg.org/wolframkriesing/picossg/commit/039d99a" rel="noopener noreferrer"&gt;preparations for this release&lt;/a&gt; were underway.&lt;/p&gt;

&lt;p&gt;A major improvement came in the metadata handling. Two weeks after the project began, &lt;a href="https://codeberg.org/wolframkriesing/picossg/commit/a3dfe37" rel="noopener noreferrer"&gt;a subtle but important change&lt;/a&gt; &lt;br&gt;
restructured how data was passed to templates, making it more convenient while maintaining access to the original structure. Later that same day, &lt;br&gt;
&lt;a href="https://codeberg.org/wolframkriesing/picossg/commit/30c887a" rel="noopener noreferrer"&gt;another refinement&lt;/a&gt; further simplified template data access.&lt;/p&gt;

&lt;p&gt;As the project approached its third week, the pre/post processing capability was &lt;a href="https://codeberg.org/wolframkriesing/picossg/commit/6e9dfc2" rel="noopener noreferrer"&gt;significantly enhanced&lt;/a&gt;, &lt;br&gt;
allowing user-defined functions to transform content before and after the main processing pipeline. This expanded what users could do without adding complexity to the core.&lt;/p&gt;

&lt;p&gt;Just days before the v3 release, performance improvements appeared with a change that &lt;a href="https://codeberg.org/wolframkriesing/picossg/commit/57f73a0" rel="noopener noreferrer"&gt;parallelized file writes&lt;/a&gt; &lt;br&gt;
for better efficiency: "Make the writing of the files as parallel as it can be :)." &lt;br&gt;
Maybe it was just me proving I know Promises a bit :). But I have to say adding &lt;code&gt;await&lt;/code&gt; in front of every async operation&lt;br&gt;
does not feel right most of the time, even though there is a lot of room for improvement also in this project.&lt;/p&gt;

&lt;p&gt;With clarity that comes from real-world usage, the directory structure was &lt;br&gt;
&lt;a href="https://codeberg.org/wolframkriesing/picossg/commit/2e3bf16" rel="noopener noreferrer"&gt;reorganized&lt;/a&gt; to make the project more intuitive for newcomers.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Philosophy in Action
&lt;/h2&gt;

&lt;p&gt;Throughout PicoSSG's development, the philosophy of "less code, not smarter code" remains evident. At one point, a commit message &lt;a href="https://codeberg.org/wolframkriesing/picossg/commit/df361b4" rel="noopener noreferrer"&gt;proudly declared&lt;/a&gt;: "I gladly removed (more) code." This reflects the core belief that the best code is often code you don't have to write or maintain.&lt;/p&gt;

&lt;p&gt;The 1:1 file mapping isn't just an implementation detail but a fundamental design principle that creates predictability. Users can look at their source directory and immediately understand what the output will be, without hidden transformations or magic.&lt;/p&gt;

&lt;p&gt;The project embraces convention over configuration without hiding complexity. Rather than extensive configuration options, PicoSSG uses simple conventions (like files starting with underscore being excluded) that are easy to remember and reason about.&lt;/p&gt;

&lt;p&gt;This minimalist approach leads to more maintainable and understandable code. The entire build process in &lt;code&gt;build.js&lt;/code&gt; is under 300 lines, making it possible for users to read and comprehend the entire codebase if needed - something impossible with larger SSG frameworks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Looking Forward
&lt;/h2&gt;

&lt;p&gt;The roadmap for PicoSSG's future is outlined in the &lt;a href="https://codeberg.org/wolframkriesing/picossg/src/branch/main/CHANGELOG.md" rel="noopener noreferrer"&gt;CHANGELOG.md&lt;/a&gt;, with plans for continued refinement rather than feature explosion. Ideas like adding size information and processing times represent the kind of thoughtful additions that add value without complexity.&lt;/p&gt;

&lt;p&gt;The most important challenge going forward will be maintaining the balance between adding useful capabilities and preserving the simplicity that makes PicoSSG special. Each potential feature must be evaluated against the core philosophy: does it add enough value to justify the additional code and complexity?&lt;/p&gt;

&lt;p&gt;Examples like &lt;a href="https://codeberg.org/wolframkriesing/jscc-site-2025" rel="noopener noreferrer"&gt;JSCraftCamp.org's 2025 site&lt;/a&gt; and &lt;a href="https://picostitch.com" rel="noopener noreferrer"&gt;picostitch.com&lt;/a&gt; demonstrate that PicoSSG is already capable of building real-world sites with its minimal feature set. This validates the core premise - that for many static sites, "just enough code" is indeed enough.&lt;/p&gt;

&lt;p&gt;In a world where software tends toward bloat and complexity, PicoSSG stands as a reminder that sometimes, less is truly more.&lt;/p&gt;

&lt;p&gt;You see more code that can be removed? &lt;a href="https://mastodontech.de/@wolframkriesing" rel="noopener noreferrer"&gt;Let me know, please&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
    </item>
    <item>
      <title>How to Control Strict Mode</title>
      <dc:creator>Home Officer</dc:creator>
      <pubDate>Sun, 05 Nov 2023 20:09:00 +0000</pubDate>
      <link>https://dev.to/wolframkriesing/how-to-control-strict-mode-4i82</link>
      <guid>https://dev.to/wolframkriesing/how-to-control-strict-mode-4i82</guid>
      <description>&lt;p&gt;I was surprised to see that the worker threads run in non-strict mode by default. This should rarely happen, because when using ES modules (ESMs), classes or &lt;code&gt;"use strict"&lt;/code&gt; then the engine forces strict mode. I didn't know this in the beginning. I have been working on the katas I use for this site in the &lt;a href="https://codeberg.org/wolframkriesing/javascript-katas" rel="noopener noreferrer"&gt;javascript-katas repo&lt;/a&gt; which uses ESMs and &lt;code&gt;type=module&lt;/code&gt;, my default. This makes the entire nodejs project, any &lt;code&gt;npm ...&lt;/code&gt; command run use strict mode. Escaping from strict mode is not easily possible, but one way to run code in non-strict mode is by using a worker thread.&lt;/p&gt;

&lt;p&gt;I always like to understand where things originate, so let's read about strict mode.&lt;/p&gt;

&lt;h2&gt;
  
  
  Strict Mode – When and Why?
&lt;/h2&gt;

&lt;p&gt;Strict mode was introduced &lt;a href="https://262.ecma-international.org/5.1/#sec-4.2.2" rel="noopener noreferrer"&gt;in ES5 (in 2009)&lt;/a&gt;.&lt;br&gt;
In the specification it says strict mode was added&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;in the interests of security, to avoid what [...] consider to be error-prone features, to get enhanced error checking&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;and  &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The strict variant also specifies additional error conditions that must be reported by throwing error exceptions&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So strict mode was introduced for making JS safer.&lt;/p&gt;
&lt;h2&gt;
  
  
  Strict Mode?
&lt;/h2&gt;

&lt;p&gt;Actually the worker I used was just a mean to solve my actual problem, which was running tests for the &lt;code&gt;arguments&lt;/code&gt; kata. In order to do that I needed to run the tests in non-strict mode, so let's have a look at the strict mode.&lt;/p&gt;

&lt;p&gt;Where does the strict mode play a role now? I had been diving deep into the "function API", digging in the very first &lt;a href="https://www.ecma-international.org/wp-content/uploads/ECMA-262_1st_edition_june_1997.pdf" rel="noopener noreferrer"&gt;ES1 spec&lt;/a&gt; and all versions beyond to find out when was what introduced or deprecated (deprecation happens rarely in JavaScript). So I came across &lt;code&gt;arguments&lt;/code&gt; and when I wrote the following test:&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;fn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&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;arguments&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;arg&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;arguments&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nx"&gt;assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;equal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;the argument&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="s1"&gt;arg&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;It failed with "Uncaught SyntaxError: Unexpected eval or arguments in strict mode", which was not due to the test code itself, but the rest of the code I ran in the worker thread. The above test only got injected and makes only a small part &lt;br&gt;
of the entire code run in the worker. The code has an &lt;code&gt;import&lt;/code&gt; in it, which turned all the code to be run in strict mode.&lt;br&gt;
And as the error says &lt;code&gt;arguments&lt;/code&gt; is not allowed in strict mode.&lt;/p&gt;

&lt;p&gt;So I want to control when to turn on strict mode. But for that let's understand strict mode a bit better first.&lt;/p&gt;
&lt;h3&gt;
  
  
  What forces Strict Mode?
&lt;/h3&gt;

&lt;p&gt;As mentioned above &lt;code&gt;"use strict"&lt;/code&gt; turns on strict mode, but in this case there was none in the worker code yet, so what turned it on? In the &lt;a href="https://262.ecma-international.org/6.0/#sec-strict-mode-code" rel="noopener noreferrer"&gt;ES6 spec chapter "Strict Mode Code"&lt;/a&gt;&lt;br&gt;
the following lines were newly added which force strict mode to turn on:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Module code is always strict mode code.&lt;br&gt;&lt;br&gt;
All parts of a ClassDeclaration or a ClassExpression are strict mode code.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So the &lt;code&gt;import&lt;/code&gt; turned it on.&lt;/p&gt;
&lt;h3&gt;
  
  
  How to Control Strict Mode?
&lt;/h3&gt;

&lt;p&gt;So I rewrote the code to not use &lt;code&gt;import&lt;/code&gt; and it ran in non-strict mode. &lt;/p&gt;

&lt;p&gt;Now I can control strict mode, I just have to add &lt;code&gt;"use strict"&lt;/code&gt; at the top of the code. Even better, I can put &lt;code&gt;"use strict"&lt;/code&gt; at the beginning of a function body, and it makes&lt;br&gt;
only this function run in strict mode. It must be the first statement in this function, see the code below for some exploration. Oooh, I see new katas arising.&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;use strict&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&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;arguments&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;arg&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The above fails with the error message we know from above "Unexpected eval or arguments in strict mode".&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;fn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&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="s1"&gt;use strict&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;     &lt;span class="c1"&gt;// "use strict" inside the function, test still fails.&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;arguments&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;arg&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The above fails too, for the same reason. Here only the function is run in strict mode, but that's also where &lt;code&gt;arguments&lt;/code&gt; is used, so it fails.&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;fn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&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;arguments&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;arg&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="s1"&gt;use strict&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;     &lt;span class="c1"&gt;// "use strict" NOT at the beginning of a function it gets ignored, test passes!&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Passes.&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;fn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&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="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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;use strict&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;     &lt;span class="c1"&gt;// "use strict" at the start of a scope, but NOT at the beginning of a function it gets ignored, test passes!&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;arguments&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;arg&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And this one passes too, because the &lt;code&gt;"use strict"&lt;/code&gt; strings are not at the beginning of a function. I was irritated in the beginning, because I expected it to be at the beginning of a scope, so after the &lt;code&gt;{&lt;/code&gt;, but I was wrong. The &lt;a href="https://262.ecma-international.org/5.1/#sec-10.1.1" rel="noopener noreferrer"&gt;spec also states&lt;/a&gt; this explicitly:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;if the function code begins with a Directive Prologue that contains a Use Strict Directive.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;in human words, this means the function must start with a &lt;code&gt;"use strict"&lt;/code&gt; string. The scope is not mentioned there. The spec defines three more cases in very hard to read words. These are 1) the global code, 2) eval code and 3) &lt;code&gt;Function&lt;/code&gt; code, when either starts with a &lt;code&gt;"use strict"&lt;/code&gt; string, then the entire code is run in strict mode.&lt;/p&gt;

&lt;p&gt;With this I did not only learn what strict mode restricts, but also how to control it. And all the magic is gone. &lt;/p&gt;

&lt;p&gt;💡 &lt;strong&gt;To turn on strict mode, you can use &lt;code&gt;"use strict"&lt;/code&gt; in the four described ways, classes or modules. &lt;br&gt;
That's how strict mode can be (manually) turned on or forced to be on.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>node</category>
      <category>javascript</category>
      <category>strictmode</category>
      <category>programming</category>
    </item>
    <item>
      <title>JSKatas 🥋 Continuously Learn JavaScript. Your Way.</title>
      <dc:creator>Home Officer</dc:creator>
      <pubDate>Mon, 28 Aug 2023 11:40:59 +0000</pubDate>
      <link>https://dev.to/wolframkriesing/jskatas-continuously-learn-javascript-your-way-c01</link>
      <guid>https://dev.to/wolframkriesing/jskatas-continuously-learn-javascript-your-way-c01</guid>
      <description>&lt;p&gt;This article explains what &lt;a href="https://jskatas.org" rel="noopener noreferrer"&gt;jskatas.org&lt;/a&gt; is.  In short it is: "Continuously Learn JavaScript. Your Way."&lt;/p&gt;

&lt;p&gt;No matter if you are beginner or an expert, a slow or fast learner.&lt;br&gt;
The site &lt;a href="https://jskatas.org" rel="noopener noreferrer"&gt;jskatas.org&lt;/a&gt; aims to allow anyone to discover and learn unknown or new parts of JavaScript. You can also consolidate your JavaScript knowledge or extend your skills and sharpen them.&lt;/p&gt;

&lt;p&gt;Learning with &lt;a href="https://jskatas.org" rel="noopener noreferrer"&gt;jskatas&lt;/a&gt; requires you to &lt;strong&gt;actively&lt;/strong&gt; work with and on the language. There is no lean-back content to "just consume" and hope to have acquired knowledge, this is NOT what &lt;a href="https://jskatas.org" rel="noopener noreferrer"&gt;jskatas&lt;/a&gt; offers, and also does not want to offer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Content
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Learn (With Tests)&lt;/li&gt;
&lt;li&gt;Re-Learn&lt;/li&gt;
&lt;li&gt;(All of) JavaScript&lt;/li&gt;
&lt;li&gt;At Your Level and At Your Speed&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Learn (With Tests)
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://jskatas.org" rel="noopener noreferrer"&gt;JSKatas&lt;/a&gt; strives to allow you to learn the language JavaScript profoundly and complete. The approach to learn is oriented around tests.&lt;/p&gt;

&lt;p&gt;The katas are structured closely with how the language evolves.&lt;br&gt;
Categories like "ECMAScript 6 (ES2015)" which had been introduced&lt;br&gt;
provide a versioning scheme for the language. JSKatas structures its learnings using those categories and will allow you to track and learn all parts of JavaScript.&lt;/p&gt;

&lt;p&gt;The learning itself can be called test-driven, because all one does is working with tests all the time. Tests are an essential part of programming. How can you continuously prove that code works if there are not coherent and expressive tests that can verify the functioning at any time? Why not apply this approach for learning a programming language? That was the thought when jskatas was created.&lt;/p&gt;

&lt;p&gt;A test is made up of a good test description explicitly describing what the test is proving or trying to prove. Each test description you find on jskatas strives to be explaining what the code (the test) is teaching. Each test on &lt;a href="https://jskatas.org" rel="noopener noreferrer"&gt;jskatas&lt;/a&gt; represents a tiny bit of knowledge. For example: &lt;code&gt;'isInteger' is a static function on 'Number'&lt;/code&gt;. This piece of info is knowledge you can take away as soon as you read the test description. To make this knowledge really stick the according test is failing and the learner is supposed to solve it. Sometimes solving is a number of tries and thought processes, or call them learnings. Once learned by having read and proven by making the initially failing test pass, the knowledge might stick easier and once needed will be easy to recall and apply.&lt;/p&gt;

&lt;h2&gt;
  
  
  Re-Learn
&lt;/h2&gt;

&lt;p&gt;Re-learn is the part that I am most excited about and that I find most useful about &lt;a href="https://jskatas.org" rel="noopener noreferrer"&gt;jskatas&lt;/a&gt; and, I believe that this part is far underevaluated by many. Actually I am not really happy with the term "re-learn", I am not sure if it captures the intent best. Let's explore what it means.&lt;/p&gt;

&lt;p&gt;I use &lt;a href="https://jskatas.org" rel="noopener noreferrer"&gt;jskatas&lt;/a&gt; to re-learn parts of JavaScript that I either did not use for a long time, that I never used, that I forgot or parts where I am not sure how they really work. Often I had come back to do the &lt;a href="https://jskatas.org/katas/es6/language/map/basics/" rel="noopener noreferrer"&gt;Map-katas&lt;/a&gt; because I used &lt;code&gt;Map&lt;/code&gt; sporadically. Another one that I often get wrong, even after many years of JavaScript is the &lt;a href="https://jskatas.org/katas/es1/language/array-api/sort-basics/" rel="noopener noreferrer"&gt;Array method &lt;code&gt;sort()&lt;/code&gt;&lt;/a&gt;. So I wrote the &lt;a href="https://jskatas.org/katas/versions/chronological/#bundle-es1-katas" rel="noopener noreferrer"&gt;ES1 kata&lt;/a&gt; for &lt;code&gt;sort()&lt;/code&gt;. I came back to it at least twice already again to re-learn how &lt;code&gt;sort()&lt;/code&gt; works. The last time was just last week. The &lt;code&gt;sort()&lt;/code&gt; function is in JavaScript since ES1, for a long time already,  but it's not that intuitive that I get it right all the time. It might just be me.&lt;/p&gt;

&lt;p&gt;JSKatas allows you to jump in whereever you want and either re-learn a part of JavaScript or harden your existing knowledge. There is no entry or exit point on jskatas, any point can be a starting and ending point for learning. There are no fixed lessons or plans you have to follow when learning. There are only pieces of knowledge that can be arranged and re-arranged any time depending on the current interest. That's why jskatas is also ideal for re-learning and hardening ones JavaScript knowledge.&lt;/p&gt;

&lt;p&gt;In the future test plans and guides might be provided, to give guidance on how to learn, what to learn next, where to start and/or where to continue. But this is still some time out. Even given these guides would exist, learning can still start, continue and end anywhere with any kata. Such a guide is easy to arrange depending on the desired learning goal. And yet it can make use of the entire pool of katas.&lt;/p&gt;

&lt;h2&gt;
  
  
  (All of) JavaScript
&lt;/h2&gt;

&lt;p&gt;As mentioned before JavaScript is very well structured, versioned and named, in it's own way though. "ECMAScript 1 (ES1)", "ES5", "ES6" or "ES2015", the names make the evolution of JavaScript easy to understand and allow jskatas to easily structure all the knowledge.&lt;/p&gt;

&lt;p&gt;Due to this crystal clear and simple structure of the JavaScript knowledge it is also very easy to measure how much of JavaScript one can learn using jskatas, and also how much jskatas provides to be learned. Currently I would claim that &lt;a href="https://jskatas.org/katas/versions/chronological/#bundle-es6-katas" rel="noopener noreferrer"&gt;80% of ES6&lt;/a&gt; can be learned using jskatas. But how much of all JavaScript, that is left to be made measurable correctly. This is not done yet.&lt;/p&gt;

&lt;p&gt;That's why the "All of" in the headline of this paragraph is set in parantheses. JSKatas does not allow to learn all of JavaScript yet.&lt;br&gt;
But measuring it is not that difficult using the approach of providing the knowledge as jskatas does it.&lt;/p&gt;

&lt;h2&gt;
  
  
  At Your Level and At Your Speed
&lt;/h2&gt;

&lt;p&gt;The level of knowledge and the speed of learning is so very different among people, that everyone has their own way of learning. One person knows all about arrays, but not all about string, the next one knows half of each. Offering these people the same learning materials is not efficient.&lt;/p&gt;

&lt;p&gt;On &lt;a href="https://jskatas.org" rel="noopener noreferrer"&gt;jskatas&lt;/a&gt; you determine the speed at which you solve the katas that provide the knowledge. Let's see an example. The Array API katas for ES6 at some point consisted of eight katas.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Frr0lstzxq321lpl3a2bb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Frr0lstzxq321lpl3a2bb.png" alt="The eight ES6 Array katas." width="382" height="472"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://jskatas.org/katas/es6/language/array-api/from/" rel="noopener noreferrer"&gt;The &lt;code&gt;Array.from()&lt;/code&gt; kata&lt;/a&gt; consists of five tests, or five pieces of knowledge. You can always decide how much of the kata you do, if you use it for re-learning or if you want to learn all the kata provides for this topic.&lt;/p&gt;

&lt;p&gt;Every tiny test is a progress. One test can take as little as five seconds to solve. So even re-learning might not be a huge time invest. And you can stop learning even within a kata whenever you like.&lt;/p&gt;

&lt;p&gt;So the depth and intensity is up to you, your discipline, interest, drive and endurance. JSKatas allows you to learn at your level and your speed.&lt;/p&gt;

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

&lt;p&gt;Are you up for trying a different approach to learning JavaScript? One where you have to be actively learning, where you are steering your progress and you determine the speed? Try solving some tests &lt;a href="https://jskatas.org" rel="noopener noreferrer"&gt;jskatas&lt;/a&gt; and learn or learn again what you do or didn't know yet.&lt;br&gt;&lt;br&gt;
Continuously Learn JavaScript. Your Way.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>learning</category>
      <category>kata</category>
      <category>testing</category>
    </item>
    <item>
      <title>Discover and extract dependencies</title>
      <dc:creator>Home Officer</dc:creator>
      <pubDate>Tue, 20 Mar 2018 00:03:11 +0000</pubDate>
      <link>https://dev.to/wolframkriesing/discover-and-extract-dependencies-16ip</link>
      <guid>https://dev.to/wolframkriesing/discover-and-extract-dependencies-16ip</guid>
      <description>&lt;p&gt;While refactoring some badly tested code, a pattern of how I extract dependencies emerged. The actual intention was to improve the testability. In this case dependency injection is the tool that helped me. Read here to find out the steps I found to separate the dependencies.&lt;/p&gt;

&lt;h2&gt;
  
  
  The pattern that emerged (the quick version)
&lt;/h2&gt;

&lt;p&gt;From this article you may learn that those steps are all that is necessary in order to get a better feeling on the dependencies of your code, how to separate them and make the code easy to test.&lt;/p&gt;

&lt;p&gt;The steps are:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Write a first test&lt;/li&gt;
&lt;li&gt;Find and use first dependency in test&lt;/li&gt;
&lt;li&gt;Isolate dependencies&lt;/li&gt;
&lt;li&gt;Provide production/default dependencies&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;And you end up with &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;fast and small tests&lt;/li&gt;
&lt;li&gt;separated dependencies&lt;/li&gt;
&lt;li&gt;maybe hints for how to modularize your code&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The task
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Fpicostitch.com%2Fblog%2F2017%2F03%2Fdiscover-extract-dependencies%2Fload-student-flow.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/http%3A%2F%2Fpicostitch.com%2Fblog%2F2017%2F03%2Fdiscover-extract-dependencies%2Fload-student-flow.png" alt="program flow"&gt;&lt;/a&gt;&lt;br&gt;
&lt;br&gt;&lt;em&gt;loadStudent function flow&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I want to show how to separate dependencies that might not been obvious at first. And by adding tests I will "feel" them. And I will be pushed to separate them out. Which makes my code easier to test and also make me understand what (external) dependencies the code has.&lt;/p&gt;

&lt;p&gt;I broke down the original code, to really make the actual dependencies stick out. The code loads some data, a student in this case. To speed up performance the student is first read from a cache, if that fails it is loaded from a (slower) backend.&lt;/p&gt;

&lt;p&gt;Let's get started.&lt;br&gt;&lt;br&gt;
This code was &lt;strong&gt;missing tests&lt;/strong&gt;. So I will start to add them. The starting point was the following 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="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;fetch&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;./backend&lt;/span&gt;&lt;span class="dl"&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;cache&lt;/span&gt; &lt;span class="o"&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;loadStudent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;studentId&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="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="nx"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;studentId&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;studentId&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;studentId&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;cache&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;studentId&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;
  
  
  First test
&lt;/h2&gt;

&lt;p&gt;The first test I wrote was for the cache (&lt;a href="https://gitlab.com/wolframkriesing/article-discover-extract-dependencies/commit/a3dba52ce7789c5517ceb60f953cfa33bb6ad499" rel="noopener noreferrer"&gt;see the commit&lt;/a&gt;). Actually I am not sure it's the right test to write, since the fetch is more important. But anyways. I follow the code's flow.&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="nf"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Load a student&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;from the cache&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;student 42&lt;/span&gt;&lt;span class="dl"&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;student&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;loadStudent&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;studentId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="nf"&gt;assertThat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;student&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;equalTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;student 42&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="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first thing that jumps out is the sharing of the &lt;strong&gt;&lt;em&gt;global&lt;/em&gt;&lt;/strong&gt; &lt;code&gt;cache&lt;/code&gt; variable. The production code and the test share it now through the access of a global variable. Scary. This is not good. In this case I want to have the cache under control, so I need to inject it. That is my first conclusion and the first dependency I found. NOTE: first dependency &lt;code&gt;cache&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Isolate first dependency
&lt;/h2&gt;

&lt;p&gt;I rewrite the test (and make it fail), I pass the &lt;code&gt;cache&lt;/code&gt; into the function as a parameter (&lt;a href="https://gitlab.com/wolframkriesing/article-discover-extract-dependencies/commit/2c485ba353c252e913d8430a49cda39894f30431" rel="noopener noreferrer"&gt;see the commit&lt;/a&gt;). I isolate the first dependency. At least for the test it is isolated now.&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="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;from the cache&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="o"&gt;=&amp;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;cache&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;student 42&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt; &lt;span class="c1"&gt;// &amp;lt;&amp;lt;&amp;lt; no more globals :)&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;student&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;loadStudent&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;studentId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;cache&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="nf"&gt;assertThat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;student&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;equalTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;student 42&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To make this test green I need to change the production code. I need to &lt;br&gt;
use the cache as given via parameter.&lt;/p&gt;

&lt;p&gt;I am going to change the production code, the function &lt;code&gt;loadStudent()&lt;/code&gt; without having it fully covered with tests. The &lt;code&gt;fetch()&lt;/code&gt; method is not tested yet at all. True. I am fine with that for now.&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;loadStudent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;studentId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;cache&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="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="nx"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;studentId&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;studentId&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;studentId&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;cache&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;studentId&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;No more global &lt;code&gt;cache&lt;/code&gt; variable. Great for testability. But actually the real cache functionality got lost. Since there is no global cache anymore. Right. That is a real issue. I will cover this in a second. Hold on! Let's clean up a bit first.&lt;/p&gt;

&lt;h2&gt;
  
  
  Separating dependencies
&lt;/h2&gt;

&lt;p&gt;First I would like to refactor the code a little bit. The parameters are nice and the destructuring makes it nice to have named parameters. But I think that &lt;code&gt;studentId&lt;/code&gt; and &lt;code&gt;cache&lt;/code&gt; are two different kind of parameters. The &lt;code&gt;studentId&lt;/code&gt; is the actual parameter that this function requires in order to do something useful. And the &lt;code&gt;cache&lt;/code&gt; is an injected dependency. I want to make that clear in the function. So I split them (&lt;a href="https://gitlab.com/wolframkriesing/article-discover-extract-dependencies/commit/a17fec979562c0d58311b87bf431a8542878212f" rel="noopener noreferrer"&gt;the commit&lt;/a&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;loadStudent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;studentId&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;cache&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="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And since I am a fan of explicitness I prefer to not destructure the second parameter, but to name the entire thing, like so (&lt;a href="https://gitlab.com/wolframkriesing/article-discover-extract-dependencies/commit/ce657f84069e27a4640c8fa0759b7fe7a5bf2bae" rel="noopener noreferrer"&gt;commit&lt;/a&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;loadStudent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;studentId&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="nx"&gt;dependencies&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="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will bubble through the code and inside the function &lt;code&gt;cache&lt;/code&gt; will need to be replaced by &lt;code&gt;dependencies.cache&lt;/code&gt;. Which is more to write but every reader of the code will benefit from it. It will be clear that the cache is a dependency and is not a main concern of this function. And how the cache works is nothing of importance in here. I personally like that and think it adds value to the code for any future reader.&lt;/p&gt;

&lt;h2&gt;
  
  
  Discover second dependency, the &lt;code&gt;fetch()&lt;/code&gt; function
&lt;/h2&gt;

&lt;p&gt;Let's tackle one of the open issues, which is testing the &lt;code&gt;fetch()&lt;/code&gt; function. It is a global function, currently. So we are treating it as a nasty global function for now, and just overriding it in the following test (&lt;a href="https://gitlab.com/wolframkriesing/article-discover-extract-dependencies/commit/aaf3278c68aaf39b060585b9b309f3a1295a0bbc" rel="noopener noreferrer"&gt;commit&lt;/a&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="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;fetch the student if not in the cache&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="o"&gt;=&amp;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;emptyCache&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;
  &lt;span class="nx"&gt;fetch&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;student 23&lt;/span&gt;&lt;span class="dl"&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;student&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;loadStudent&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;studentId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;23&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;emptyCache&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="nf"&gt;assertThat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;student&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;equalTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;student 23&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We &lt;strong&gt;know&lt;/strong&gt; now that &lt;code&gt;fetch()&lt;/code&gt; is used inside of &lt;code&gt;loadStudent()&lt;/code&gt;. And that knowledge is not in our test, that is nasty too. We need to make that obvious.&lt;/p&gt;

&lt;h2&gt;
  
  
  Inject the second dependency
&lt;/h2&gt;

&lt;p&gt;We make this obvious by (just say it with me), yes, correct: &lt;strong&gt;injecting the dependency&lt;/strong&gt; (&lt;a href="https://gitlab.com/wolframkriesing/article-discover-extract-dependencies/commit/9d808180666de271e1c7a37e4e2a4f96add0b08f" rel="noopener noreferrer"&gt;commit&lt;/a&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="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;fetch the student if not in the cache&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="o"&gt;=&amp;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;emptyCache&lt;/span&gt; &lt;span class="o"&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;dependencies&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;emptyCache&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;student 23&lt;/span&gt;&lt;span class="dl"&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;student&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;loadStudent&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;studentId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;23&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="nx"&gt;dependencies&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nf"&gt;assertThat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;student&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;equalTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;student 23&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;See &lt;code&gt;fetch()&lt;/code&gt; is passed in the &lt;code&gt;dependencies&lt;/code&gt; object. And no global is overridden anymore.&lt;/p&gt;

&lt;h2&gt;
  
  
  Provide production dependencies
&lt;/h2&gt;

&lt;p&gt;Now we have all the dependencies identified. We have &lt;code&gt;cache&lt;/code&gt; and &lt;code&gt;fetch()&lt;/code&gt; (even though &lt;code&gt;fetch&lt;/code&gt; is a pretty bad name). Those two dependencies can be injected, the function works using them. Now we should not just have the tests run, but also the production setup. And for that we need to provide the dependencies to it too.&lt;/p&gt;

&lt;p&gt;How? Let's try an integrated test for it, one that takes a working cache and a working &lt;code&gt;fetch()&lt;/code&gt; function as given (&lt;a href="https://gitlab.com/wolframkriesing/article-discover-extract-dependencies/commit/5f18dfbdc69fc38f4ee636f04aac286072ecdac8" rel="noopener noreferrer"&gt;commit&lt;/a&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="nf"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Load a student&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;from the cache&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="o"&gt;=&amp;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;student&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;loadStudent&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;studentId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="nf"&gt;assertThat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;student&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;equalTo&lt;/span&gt;&lt;span class="p"&gt;(&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="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, this test assumes 1) there is no student with the ID 42 and 2) a fetch for this student returns  an empty string. Yep, we are assuming to have these external dependencies under control that we &lt;strong&gt;know&lt;/strong&gt; those things. &lt;/p&gt;

&lt;p&gt;Deploying this and having it run in a real CI environment there might be a bit more setup to make in order to get those integrated tests provided with the right data. And it might also be a bit more work to get them stable. That's why one should very well figure out what the right set of (mostly happy path) tests is. And if you throw many of them at your code, do also think that they must stay maintainable! This one here serves as an example for understanding that a safe software might not only consist of tiny and small tests (I am preventing the polluted name "unit tests").&lt;/p&gt;

&lt;p&gt;To get this test green, we set up the default dependencies that our production environment will use. There is many other ways of injecting dependencies. The following worked quite well for me until now (&lt;a href="https://gitlab.com/wolframkriesing/article-discover-extract-dependencies/commit/b58a9de0424f16b58a50b422c6c49e27d8f0c101" rel="noopener noreferrer"&gt;commit&lt;/a&gt;). Though remember to try to keep the dependencies to be injected as tiny as possible and it will serve you well.&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;defaultDependencies&lt;/span&gt; &lt;span class="o"&gt;=&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="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;cache&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;loadStudent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;studentId&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="nx"&gt;dependencies&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;defaultDependencies&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="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you see above, I define the &lt;code&gt;defaultDependencies&lt;/code&gt; above the function. Mostly those consist only of some imported items. One could go further and move this out and just inject a structure into this file. I saw it working well until now with this less generic, more explicit approach and allowing the reader (of the code) to see what the dependencies consist of, right where they are used.&lt;/p&gt;

&lt;p&gt;Why a function &lt;code&gt;defaultDependencies()&lt;/code&gt; and not just a simple object? Simple answer, a function makes it lazy. Until the dependencies are not needed they don't get resolved, this might dribble down the call stack. And it also allows for configuring a dependency, if necessary.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's left?
&lt;/h2&gt;

&lt;p&gt;The variable &lt;code&gt;cache&lt;/code&gt; is a very simple, very stupid cache now. Which is quite cool. But thinking about a cache, there might be more to it. I might want to create a simple API for the reading from and writing to the cache.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;fetch()&lt;/code&gt; as such is a very generic name. But it could be named better, something like &lt;code&gt;readFromBackend()&lt;/code&gt; or &lt;code&gt;loadStudentFromStorage()&lt;/code&gt;. That there might just be the simple &lt;code&gt;fetch()&lt;/code&gt; function behind it, is secondary.&lt;/p&gt;

&lt;p&gt;Maybe making it asynchronous would be a nice add-on. It would be very easy, but unfortunately this involves also changes in the test code. But that is the nature of JavaScript, it can not simply hide asynchronicity in code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusions
&lt;/h2&gt;

&lt;p&gt;Separating dependencies can be done by writing tests for untested code. It looks like it blows up the code? Think again! It also decouples your code in the places where you might not want it coupled. Decoupling is just like every person using a different glass when drinking from the same bottle, in order to not share all germs. It's pure hygiene.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>dependencyinjection</category>
      <category>testing</category>
    </item>
  </channel>
</rss>
