<?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: masters.🤔</title>
    <description>The latest articles on DEV Community by masters.🤔 (@dustinsoftware).</description>
    <link>https://dev.to/dustinsoftware</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%2F6230%2F3IonB4Te.jpg</url>
      <title>DEV Community: masters.🤔</title>
      <link>https://dev.to/dustinsoftware</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/dustinsoftware"/>
    <language>en</language>
    <item>
      <title>Verifying Assembly Redirects Before Runtime</title>
      <dc:creator>masters.🤔</dc:creator>
      <pubDate>Tue, 06 Oct 2020 21:41:55 +0000</pubDate>
      <link>https://dev.to/dustinsoftware/verifying-assembly-redirects-before-runtime-1p4g</link>
      <guid>https://dev.to/dustinsoftware/verifying-assembly-redirects-before-runtime-1p4g</guid>
      <description>&lt;p&gt;This week's "yak shaving" project was updating a library dependency in across several large .NET solutions in a monorepo. It took about as long as we expected, but not &lt;em&gt;for&lt;/em&gt; the reasons we expected - this is a tale about assembly binding redirects. &lt;/p&gt;

&lt;p&gt;The library (Npgsql) was bumped two major versions, from 2.x to 4.x. The primary advantage of the update in our case was added .NET Core support, allowing us to incrementally port services in this monorepo over to .NET Core.&lt;/p&gt;

&lt;p&gt;Our dependency structure looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- Npgsql
  - SharedBusinessLogic
    - Web UI layer
    - Some async services that generate reports
    - An unrelated UI project that doesn't use Npgsql directly
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;There were a few database queries that broke but overall the update seemed to go fine, tests were passing locally and on CI.&lt;/p&gt;

&lt;p&gt;However, after merging and deploying the branch to one of our test environments, one of our projects started throwing errors on certain routes:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--LT0QXguL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/b9ifyghgiuparzryukad.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--LT0QXguL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/b9ifyghgiuparzryukad.png" alt="yellow screen of death"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What happened?&lt;/p&gt;

&lt;p&gt;An updated graph of dependencies after the update:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- System.Runtime.CompilerServices.Unsafe
- System.Numerics.Vectors
- System.Memory
- System.Threading.Tasks.Extensions
  - Npgsql
    - SharedBusinessLogic
      - Web UI layer
      - Some async services that generate reports
      - An unrelated UI project that doesn't use Npgsql directly
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The Npgsql dependency now targets netstandard, which means we can reference it via .NET Core and .NET Framework (legacy) without compatibility hacks. However, to accomplish this, some of the dependencies that were previously referenced in the installed .NET runtime are now referenced via NuGet packages. By convention, most of these are prefixed &lt;code&gt;System.&lt;/code&gt; in the dependency list.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--N1w-72EM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/qyhdh6pya0ihoxm951zh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--N1w-72EM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/qyhdh6pya0ihoxm951zh.png" alt="nuget dependency list"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;However, some of our other app dependencies &lt;em&gt;already&lt;/em&gt; had references to these &lt;code&gt;System.&lt;/code&gt; assemblies, but for different versions.&lt;/p&gt;

&lt;p&gt;Confused? Let's talk a bit about how this works.&lt;/p&gt;

&lt;p&gt;In .NET Core projects assembly binding redirects are not necessary, but many of our projects still run on .NET 4.8, also referred to as .NET Framework, or netfx. &lt;/p&gt;

&lt;p&gt;At runtime, the .NET Framework tries to resolve a specific version of any dependencies requested. If the exact version is not present in the bin folder, an assembly binding redirect is required to "force" the runtime to resolve to a specific version, or an exception will be thrown. These binding redirects are specified in a config file and checked at runtime.&lt;/p&gt;

&lt;p&gt;For further reading, I recommend Nick Craver's excellent post on binding redirects &lt;a href="https://nickcraver.com/blog/2020/02/11/binding-redirects/"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;To complicate matters further, not all assemblies are loaded and checked at application startup. We found that only &lt;em&gt;some&lt;/em&gt; of our server-side routes caused the Npgsql assembly to load, so building and running just the home route was not enough.&lt;/p&gt;

&lt;p&gt;OK, so we'll update these bindings now that we know that the code crashes. But how can we know about this problem before running every possible route on our web app?&lt;/p&gt;

&lt;p&gt;Our first attempt was to use the &lt;code&gt;msbuild /warnaserror&lt;/code&gt; flag. With this switch, warnings will be printed for NuGet level restore problems (downgrade warnings), and binding redirects that are mismatched or missing entirely. More information &lt;a href="https://docs.microsoft.com/en-us/visualstudio/msbuild/msbuild-command-line-reference?view=vs-2019"&gt;here&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\MSBuild\Current\Bin\Microsoft.Common.CurrentVersion.targets(2084,5): warning MSB3247: Found conflicts between different versions of the same dependent assembly. 

In Visual Studio, double-click this warning (or select it and press Enter) to fix the conflicts; otherwise, add the following binding redirects to the "runtime" node in the application configuration file:

&amp;lt;assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"&amp;gt;&amp;lt;dependentAssembly&amp;gt;&amp;lt;assemblyIdentity name="System.Memory" culture="neutral" publicKeyToken="cc7b13ffcd2ddd51" /&amp;gt;&amp;lt;bindingRedirect oldVersion="0.0.0.0-4.0.1.1" newVersion="4.0.1.1" /&amp;gt;&amp;lt;/dependentAssembly&amp;gt;&amp;lt;/assemblyBinding&amp;gt; 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;In our case, we could not use &lt;code&gt;/warnaserror&lt;/code&gt; yet because we wanted to progressively roll out this validation, and additionally:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Alert on binding redirects that are targeting an old version of the library&lt;/li&gt;
&lt;li&gt;Warn on outdated redirects for assemblies not present in the bin folder (deleted dependencies)&lt;/li&gt;
&lt;li&gt;Run the tool on an entire git repository locally to quickly sanity check repos with multiple solution files&lt;/li&gt;
&lt;li&gt;Generate missing bindings without copy-pasting text from msbuild's output&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---7kPse_m--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/qx1pq5teexne98m2yqmw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---7kPse_m--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/qx1pq5teexne98m2yqmw.png" alt="screenshot of assembly checking tool"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We ended up putting together a Powershell script to handle this. It has no dependencies and has been tested on Powershell 5. &lt;a href="https://github.com/dustinsoftware/check-binding-redirects/blob/main/check-binding-redirects.ps1"&gt;Check it out here if you're interested&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The basic idea is this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Find any web.config or app.config files within a folder, recursively&lt;/li&gt;
&lt;li&gt;For each resolved config, open the bin folder and load every DLL, building a map of versions and publicKeyTokens&lt;/li&gt;
&lt;li&gt;Check to make sure the lists match&lt;/li&gt;
&lt;li&gt;If they don't, fail the build&lt;/li&gt;
&lt;li&gt;???&lt;/li&gt;
&lt;li&gt;Profit&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With increased confidence in our build tooling, we can be more proactive about moving shared projects to netstandard, and ultimately ship more projects using .NET Core. &lt;/p&gt;

&lt;p&gt;Happy shipping!&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>nuget</category>
      <category>assemblybindingredirect</category>
    </item>
    <item>
      <title>The case for Embeddable Ember</title>
      <dc:creator>masters.🤔</dc:creator>
      <pubDate>Mon, 17 Jun 2019 21:22:20 +0000</pubDate>
      <link>https://dev.to/dustinsoftware/the-case-for-embeddable-ember-4120</link>
      <guid>https://dev.to/dustinsoftware/the-case-for-embeddable-ember-4120</guid>
      <description>&lt;p&gt;&lt;a href="https://unsplash.com/@karlbewick?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Photo by Karl Bewick on Unsplash&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this post I'm proposing some improvements for Ember in an important, but often overlooked use case: embedding Ember components in non-Ember applications. Ember is great for brand new web applications. But what story do we tell for existing apps that are looking to transition to Ember?&lt;/p&gt;

&lt;p&gt;Consider a single page application that started in 2016 that uses React and webpack. There's already support for pulling in ES modules and rolling them into the production bundle. However, the team has heard about the many tooling improvements to Ember and wants to experiment shipping a small component in this existing React app. However, because the app uses a client-side router, there needs to be a mechanism to load the Ember app and render into a div without resorting to an iframe.&lt;/p&gt;

&lt;p&gt;Teams might choose not to adopt Ember because they can't afford a several month feature freeze to port components over. This post aims to solve these pain points so that teams are free to progressively ship Ember components in their apps and migrate the application over time.&lt;/p&gt;

&lt;p&gt;Ember applications are built and packaged with the &lt;code&gt;ember-cli&lt;/code&gt; tooling. Because the CLI tooling and the framework are deeply integrated, addons can be developed that make modifications to the build process. A few great examples of this are adding type checking with &lt;code&gt;ember-cli-typescript&lt;/code&gt;, generating thin wrappers for ES modules with &lt;code&gt;ember-auto-import&lt;/code&gt;, or even transforming imports from module syntax &lt;code&gt;import { computed } from '@ember/object'&lt;/code&gt; to &lt;code&gt;Ember.computed&lt;/code&gt;. One drawback of this tooling, however, is the artifacts it emits are not ideal for embedded scenarios.&lt;/p&gt;

&lt;p&gt;Let's consider what embedding an Ember component in a React app could look like:&lt;/p&gt;

&lt;h3&gt;
  
  
  React component
&lt;/h3&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;ListUsers&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;users&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;masters&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="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;UsersWrapper&lt;/span&gt; &lt;span class="na"&gt;users&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;users&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  Ember component, invoked from React
&lt;/h3&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight handlebars"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"some-app__users"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="k"&gt;{{#&lt;/span&gt;&lt;span class="nn"&gt;each&lt;/span&gt; &lt;span class="na"&gt;@users&lt;/span&gt; &lt;span class="nv"&gt;as&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="nv"&gt;user&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="k"&gt;}}&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"some-app__users__id"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;ID: &lt;span class="k"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;id&lt;/span&gt;&lt;span class="k"&gt;}}&lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"some-app__users__id"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Name: &lt;span class="k"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="k"&gt;}}&lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="k"&gt;{{/&lt;/span&gt;&lt;span class="nn"&gt;each&lt;/span&gt;&lt;span class="k"&gt;}}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;There isn't currently a way to mix Ember components in existing React applications like this. However, if we introduce a simple wrapper component:&lt;br&gt;
&lt;/p&gt;

&lt;div class="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;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useRef&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&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="nx"&gt;TinyEmber&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;tiny-ember-app&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="nx"&gt;Users&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;./ember-components/users&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;UsersWrapper&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&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;containerRef&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useRef&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="c1"&gt;// this is invoked when the host component mounts&lt;/span&gt;
  &lt;span class="nx"&gt;useEffect&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;mountedInstance&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;TinyEmber&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Users&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;containerRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// this is called when the host component unmounts&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;mountedInstance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;destroy&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[]);&lt;/span&gt;

  &lt;span class="k"&gt;return&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;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;containerRef&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;TinyEmber in this example is a fake library that provides a thin API over Ember itself. The &lt;code&gt;mount&lt;/code&gt; method takes in a reference to the component to be rendered (which it will handle initializing), a DOM node, and a set of initial component arguments. This is very similar to the design of &lt;code&gt;ReactDOM.render&lt;/code&gt;, but also accepts initial component arguments for the root Ember component. Note that these initial component arguments will only be used for the first render of the Ember component - synchronizing state updates between the parent app and the Ember app left as an exercise for the reader (message passing could be used in this case).&lt;/p&gt;

&lt;p&gt;The consuming app (React in this case) has a different component model, but it can still seamlessly mount and unmount Ember components and pass data to them. As the new app grows in size, "legacy" components can coexist with newer Ember components, and older components ported over one at a time. Optionally in the future, these old components can be removed entirely, and the transition to fully Ember components is complete.&lt;/p&gt;

&lt;p&gt;Embedding Ember applications is &lt;a href="https://guides.emberjs.com/release/configuring-ember/embedding-applications/"&gt;already documented&lt;/a&gt;, but the current approach has a few limitations.&lt;/p&gt;

&lt;h3&gt;
  
  
  Hard-coded selector for root node
&lt;/h3&gt;

&lt;p&gt;The selector for the containing element div is specified at build-time, and the emitted output from &lt;code&gt;ember build&lt;/code&gt; contains statements to initialize the app and render it on the page as soon as the bundle finishes parsing. The current initialization code would need to be handled by the consumer so that the component could be initialized and destroyed when the parent component is unmounting, potentially multiple times within the lifetime of the parent app.&lt;/p&gt;

&lt;h3&gt;
  
  
  Missing API to mount / unmount Ember components
&lt;/h3&gt;

&lt;p&gt;There isn't currently a thin API to render Ember or Glimmer components by themselves. It looks like some support for this lives in the &lt;a href="https://github.com/glimmerjs/glimmer.js"&gt;GlimmerJS repo&lt;/a&gt;, and a new standalone wrapper could probably be written to hack this together. I'd love it if there was a first-class API for this though. There also doesn't seem to be a concept of initializing the root Ember component with initial arguments at runtime.&lt;/p&gt;

&lt;h3&gt;
  
  
  Building Ember components for external use
&lt;/h3&gt;

&lt;p&gt;Components also would need to exported in a way where they can be referenced by an external bundler. For example, &lt;code&gt;ember build&lt;/code&gt; could emit a library Javascript bundle containing just the Ember components, and something like &lt;a href="https://www.npmjs.com/package/webpack-node-externals"&gt;webpack-node-externals&lt;/a&gt; to reference the &lt;code&gt;@ember&lt;/code&gt; vendor imports. That way if &lt;code&gt;lodash&lt;/code&gt; was included in an Ember component and in the host application, the vendor bundle would only include one copy. Webpack has &lt;a href="https://webpack.js.org/configuration/output/#module-definition-systems"&gt;excellent support&lt;/a&gt; for emitting bundles that are compatible with CommonJS import syntax, so maybe some of this support could be leveraged in Embroider. If this wasn't possible in the near term, exposing the root component as &lt;code&gt;window.EmberComponents.MyRootComponentNameHere&lt;/code&gt; could work in the interim before the bundler changes land.&lt;/p&gt;

&lt;h3&gt;
  
  
  Components without the services
&lt;/h3&gt;

&lt;p&gt;The current Ember architecture may not work well with an environment that needs to unmount the root component via a single page app route transition, as the javascript context would not be reloaded between virtual page transitions. If addons or services make assumptions about only being initialized once, this could be problematic. For this reason, we should focus on just supporting rendering Ember components without many of the monolith services that could be injected (such as ember-data and the router). After the story for rendering components is stable, support for these more complicated services could be added.&lt;/p&gt;

&lt;h3&gt;
  
  
  Prior art
&lt;/h3&gt;

&lt;p&gt;After writing this article, I discovered that &lt;a href="https://github.com/Rich-Harris/react-svelte"&gt;react-svelte&lt;/a&gt; exists already! You can check out the &lt;a href="https://github.com/Rich-Harris/react-svelte/blob/10dcc68c26885f9c320823f8864a523f6946e46b/index.js"&gt;component implementation here&lt;/a&gt;, which has support for mounting, updating, and destroying the underlying Svelte component.&lt;/p&gt;

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

&lt;p&gt;By exposing an API to render components from other JS frameworks, Ember provides a better migration story for existing single page applications. Although React was used as an example, the same concepts apply to an existing app written with jQuery, or any other front-end framework for that matter. Many of the pieces are already in place to support this API (such as explicit &lt;code&gt;this.args&lt;/code&gt; for Glimmer components and removing the dependency on jQuery). I look forward to seeing what progress we can make towards that goal this year!&lt;/p&gt;

&lt;p&gt;Thanks to Frank Tan, Shane Warren, and Chris Krycho for reviewing earlier drafts.&lt;/p&gt;

&lt;h1&gt;
  
  
  EmberJS2019
&lt;/h1&gt;

</description>
      <category>javascript</category>
      <category>ember</category>
    </item>
    <item>
      <title>Build hacks - Faster Ember builds with Docker on Windows</title>
      <dc:creator>masters.🤔</dc:creator>
      <pubDate>Fri, 17 May 2019 17:23:48 +0000</pubDate>
      <link>https://dev.to/dustinsoftware/build-hacks-faster-ember-builds-with-docker-on-windows-7e1</link>
      <guid>https://dev.to/dustinsoftware/build-hacks-faster-ember-builds-with-docker-on-windows-7e1</guid>
      <description>&lt;p&gt;When I joined a team maintaining an Ember web app, I was surprised to learn that almost the whole team developed exclusively on MacBooks. The team experienced slow Ember builds on Windows, and dealing with native Node dependencies (such as node-gyp) was a frustrating experience. Microsoft has made some recent improvements to support Node-based development environments on Windows, so I set out to see what we could do to make this better.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: &lt;a href="https://devblogs.microsoft.com/commandline/announcing-wsl-2/" rel="noopener noreferrer"&gt;WSL2 has been announced&lt;/a&gt;, which resolves many of the performance pains we experienced. This post should still be relevant for those wanting to use Docker as a development container.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Just show me the code!
&lt;/h2&gt;

&lt;p&gt;A working demo of the Docker setup is available &lt;a href="https://github.com/dustinsoftware/ember-docker-starter" rel="noopener noreferrer"&gt;on GitHub&lt;/a&gt;. We'll link to it throughout this article.&lt;/p&gt;

&lt;h1&gt;
  
  
  Why are builds so slow?
&lt;/h1&gt;

&lt;p&gt;Ember's build pipeline creates a lot of temporary files, which we confirmed by using &lt;a href="https://docs.microsoft.com/en-us/sysinternals/downloads/procmon" rel="noopener noreferrer"&gt;Process Monitor&lt;/a&gt;. Our suspicion was that the Windows NTFS filesystem itself has more overhead than other platforms, and creating a bunch of temporary files on disk and then reading them is where our main bottleneck was.&lt;/p&gt;

&lt;p&gt;An example of some of the temporary files created during a build:&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiv9upvx1lbwt4sb1ellp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiv9upvx1lbwt4sb1ellp.png" width="800" height="292"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Our first approach to speed up builds was to leverage the Windows subsystem for Linux (WSL), which simulates a Linux environment without using a VM. You can find more detail &lt;a href="https://github.com/Microsoft/WSL/issues/873" rel="noopener noreferrer"&gt;here&lt;/a&gt; for how the filesystem mapping works, but the important part is the host's native filesystem is still used to store the underlying files (NTFS).&lt;/p&gt;

&lt;p&gt;A screenshot of local filesystem activity running builds under WSL:&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsee7v37ly6oezqdozvod.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsee7v37ly6oezqdozvod.png" width="800" height="284"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We confirmed our expectation that builds would be as slow as they were on a native Windows environment, so we moved on to other options. Our next step was to get the build workspace out of NTFS entirely, which meant using some kind of VM. Docker for Windows turned out to be a great fit for this.&lt;/p&gt;
&lt;h2&gt;
  
  
  What we needed
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;An easy setup for all Windows developers on the team. The only requirements on the host should be Docker and .NET Core.&lt;/li&gt;
&lt;li&gt;Avoid (where possible) native dependencies on the host (such as &lt;code&gt;build-essential&lt;/code&gt; or &lt;code&gt;node-sass&lt;/code&gt; bindings)&lt;/li&gt;
&lt;li&gt;A running dev server in the container (&lt;code&gt;ember serve&lt;/code&gt; in this case) that can be notified when files change, which serves built assets over HTTP&lt;/li&gt;
&lt;li&gt;Very fast access to read and write a bunch of temporary files&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;
  
  
  Configuring the container
&lt;/h1&gt;

&lt;p&gt;We settled on running the entire Ember build pipeline within Docker and using the container's Linux-based filesystem, with some scripts to sync over just the application source from the host workstation. Let's go into detail on how this was accomplished.&lt;/p&gt;

&lt;p&gt;Tools used:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/dustinsoftware/ember-docker-starter/blob/bbff257c32a8bdfc4439e78bded57459f27344d0/docker-compose.yml" rel="noopener noreferrer"&gt;docker-compose.yml&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/dustinsoftware/ember-docker-starter/blob/bbff257c32a8bdfc4439e78bded57459f27344d0/Dockerfile" rel="noopener noreferrer"&gt;Dockerfile&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Docker exposes the application source via a shared &lt;code&gt;/host-app&lt;/code&gt; mount. This is always in sync with the host, but it's a poor place for temporary files, since it's exposed as a SMB mount point. At container start, the source is copied from the host to a directory within the container's filesystem in &lt;code&gt;/app&lt;/code&gt;, and then the build process runs. It's important that the &lt;code&gt;node_modules&lt;/code&gt; restore happens within the container and not over the shared mount so that the build has fast access to its dependencies. Passed in docker-cli arguments can be used via &lt;code&gt;--build-arg&lt;/code&gt; to control steps run during build process, such as doing an initial unit test run.&lt;/p&gt;
&lt;h2&gt;
  
  
  Notifying the container of updates
&lt;/h2&gt;

&lt;p&gt;Tools used:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/dustinsoftware/Docker-Volume-Watcher" rel="noopener noreferrer"&gt;DockerVolumeWatcher&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/dustinsoftware/ember-docker-starter/blob/bbff257c32a8bdfc4439e78bded57459f27344d0/supervisord.conf" rel="noopener noreferrer"&gt;Supervisor&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/dustinsoftware/ember-docker-starter/blob/bbff257c32a8bdfc4439e78bded57459f27344d0/lsyncd.conf.lua" rel="noopener noreferrer"&gt;Lsync&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The &lt;code&gt;/host-app&lt;/code&gt; mount does not raise notifications when files change, so we need a way to sync over changes to the container's &lt;code&gt;/app&lt;/code&gt; directory. We could use polling but that's slow and uses unnecessary CPU time, so instead we built a tool that simulates file change notifications from the container host. The &lt;code&gt;DockerVolumeWatcher&lt;/code&gt; tool uses the Windows Filesystem APIs to watch for all files changed within directories that are mapped to containers via host mounts, ignoring anything listed in &lt;code&gt;.dockerignore&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;When an a file is changed, &lt;code&gt;chmod&lt;/code&gt; is run within the container on the file that was changed (via &lt;code&gt;chmod $(stat -c %a {filepath}) {filepath}&lt;/code&gt;) to raise the file changed event to the container's running processes. This hack works well for this case, as it doesn't actually modify the file contents on the host. Using a tool like &lt;code&gt;touch&lt;/code&gt; would trigger another file modification event, which we don't want here. From here, a simple mirroring tool can be used (such as &lt;code&gt;lsync&lt;/code&gt;) to copy over the changed source from &lt;code&gt;/host-app&lt;/code&gt; to &lt;code&gt;app&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Making the developer experience even better
&lt;/h2&gt;

&lt;p&gt;Building containers creates a lot of artifacts, and after a few days of building new images, the Docker filesystem may run out of space. To counter this, we made a Powershell script as a part of starting up the dev environment that does a few things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Start &lt;code&gt;DockerVolumeWatcher&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Clean up containers and images older than 24 hours&lt;/li&gt;
&lt;li&gt;Sanity check that the FS watcher is working by creating a file on the host and checking for its existence via &lt;code&gt;docker exec&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can check out the source for the script &lt;a href="https://github.com/dustinsoftware/ember-docker-starter/blob/bbff257c32a8bdfc4439e78bded57459f27344d0/docker-start.ps1" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Rough edges
&lt;/h2&gt;

&lt;p&gt;This setup works well but requires a few workflow changes. For some VS code plugins, a recent version of Node is required for linting support. Package updates also require attaching to the container, running &lt;code&gt;yarn add &amp;lt;package&amp;gt;&lt;/code&gt;, and copying over the changed manifest with &lt;code&gt;cp /app/package.json /host-app/package.json&lt;/code&gt; (same with the lockfile). Rebuilding the container after packages have been updated is also slower than native package updating, as the container is starting from a fresh state. To work around this, you can create a "delta" and run package restore twice:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; --chown=user:user ./package-base.json ./package.json&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; --chown=user:user ./yarn-base.lock ./yarn.lock&lt;/span&gt;

&lt;span class="c"&gt;# Restore initial packages (cached in future container builds)&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;yarn

&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; --chown=user:user ./package.json .&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; --chown=user:user ./yarn.lock .&lt;/span&gt;

&lt;span class="c"&gt;# This should be very fast, since it only restores missing packages&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;yarn
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Switching branches on the host also does not work very well, as hundreds of file notifications are generated at once. Sometimes the container has to be re-started to get back into a good state.&lt;/p&gt;

&lt;h2&gt;
  
  
  How fast is this, really
&lt;/h2&gt;

&lt;p&gt;Results taken using a median after 5 passes, on an Intel Xeon E-2176M processor with 32 GB RAM and SSD.&lt;/p&gt;

&lt;p&gt;The build was run with administrative privileges so the Ember build could use symlinks to speed up the build. &lt;a href="https://ember-cli.com/user-guide/#windows" rel="noopener noreferrer"&gt;More info here&lt;/a&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Environment&lt;/th&gt;
&lt;th&gt;Package restore&lt;/th&gt;
&lt;th&gt;First build&lt;/th&gt;
&lt;th&gt;Watch-mode rebuild&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Windows native&lt;/td&gt;
&lt;td&gt;67.51s&lt;/td&gt;
&lt;td&gt;120.04s&lt;/td&gt;
&lt;td&gt;6.017s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;WSL&lt;/td&gt;
&lt;td&gt;164.67s&lt;/td&gt;
&lt;td&gt;208.13s&lt;/td&gt;
&lt;td&gt;33.52s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Docker container&lt;/td&gt;
&lt;td&gt;118.81s&lt;/td&gt;
&lt;td&gt;70.61s&lt;/td&gt;
&lt;td&gt;0.68s&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h1&gt;
  
  
  Bonus: Containers for continuous integration builds
&lt;/h1&gt;

&lt;p&gt;Many CI services support &lt;code&gt;Dockerfile&lt;/code&gt; as the build recipe, such as &lt;a href="https://github.com/dustinsoftware/ember-docker-starter/actions" rel="noopener noreferrer"&gt;Github Actions&lt;/a&gt; and &lt;a href="https://docs.travis-ci.com/user/docker/" rel="noopener noreferrer"&gt;Travis&lt;/a&gt;. If your build requires complicated setup steps, such as installing a specific version of Chrome or creating symlinks to other folders, using a &lt;code&gt;Dockerfile&lt;/code&gt; can prevent the need to synchronize commands between CI scripts and local dev scripts.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fid07paxy7279kk80a6zp.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fid07paxy7279kk80a6zp.PNG" alt="A screenshot of tests running using the same Dockerfile on Github Actions" width="800" height="492"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Thanks for reading!
&lt;/h1&gt;

&lt;p&gt;This was a fun experiment to see how fast we could get local builds. We're also testing out the &lt;a href="https://code.visualstudio.com/docs/remote/containers" rel="noopener noreferrer"&gt;Remote Containers extention&lt;/a&gt; for VS Code, and we look forward to using WSL2 when it releases in June 2019 to see how we can simplify this setup without sacrificing speed!&lt;/p&gt;

&lt;p&gt;If you made it this far, consider getting involved with an OSS project you use on a daily basis. Chances are they could use a hand updating documentation, tests, or fixing some bugs. The &lt;a href="https://dotnetfoundation.org/projects" rel="noopener noreferrer"&gt;.NET Foundation project list&lt;/a&gt; is a good place to start if you're looking for projects that need help.&lt;/p&gt;

&lt;p&gt;Cheers 🍻&lt;/p&gt;

&lt;p&gt;I'm on Twitter &lt;a href="https://twitter.com/dustinsoftware" rel="noopener noreferrer"&gt;@dustinsoftware&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Thanks to Tamar Kornblum and Frank Tan for reviewing earlier drafts of this post.&lt;/p&gt;

</description>
      <category>docker</category>
      <category>javascript</category>
      <category>node</category>
      <category>ember</category>
    </item>
    <item>
      <title>Making renders faster with the React 16.5 profiler</title>
      <dc:creator>masters.🤔</dc:creator>
      <pubDate>Tue, 25 Sep 2018 22:00:09 +0000</pubDate>
      <link>https://dev.to/dustinsoftware/making-renders-faster-with-the-react-165-profiler-f6f</link>
      <guid>https://dev.to/dustinsoftware/making-renders-faster-with-the-react-165-profiler-f6f</guid>
      <description>&lt;p&gt;React 16.5 recently shipped, which added support for some new Profiling tools. We recently used these tools to identify a major source of slow render performance.&lt;/p&gt;

&lt;p&gt;Faithlife.com is a web application powered by React 16.3. The homepage consists of a reverse-chronological timeline of posts. We received some reports that interactions with posts (such as replying) caused the browser to lag, depending on how far down the post was on the page. The further down the page the post was, the more lag occurred.&lt;/p&gt;

&lt;p&gt;After updating React to 16.5 on a local copy of Faithlife, our next step was to start profiling and capture what components were re-rendering. Below is a screenshot of what the tools showed us clicking the 'Like' button on any post:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--3h6iT8tC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://files.logoscdn.com/v1/files/14522904/content.png%3Fsignature%3DNmNdRI26PmGCtI8F6Z-3-o99Le4" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--3h6iT8tC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://files.logoscdn.com/v1/files/14522904/content.png%3Fsignature%3DNmNdRI26PmGCtI8F6Z-3-o99Le4" alt="Slow renders screenshot"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The blue blocks below NewsFeed show render being called on all the posts in the feed. If there were 10 items loaded, &lt;code&gt;NewsFeedItem&lt;/code&gt; and all its children would get rendered 10 times. This can be fine for small components, but if the render tree is deep, rendering a component and its children unnecessarily can cause performance problems. As a user scrolls down on the page, more posts get loaded in the feed. This causes render to get called for posts all the way at the top, even though they haven't changed!&lt;/p&gt;

&lt;p&gt;This seemed like a good time to try changing &lt;code&gt;NewsFeedItem&lt;/code&gt; to extend &lt;code&gt;PureComponent&lt;/code&gt;, which will skip re-rendering the component and its children if the props have not changed (a shallow comparison is used for this check).&lt;/p&gt;

&lt;p&gt;Unfortunately applying PureComponent was not enough - profiling again showed that unnecessary component renders were still happening. We then uncovered two issues preventing us from leveraging PureComponent's optimizations:&lt;/p&gt;

&lt;h2&gt;
  
  
  First roadblock: Use of children props.
&lt;/h2&gt;

&lt;p&gt;We had a component that looked something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;NewsFeedItem&lt;/span&gt; &lt;span class="na"&gt;contents&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;contents&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;VisibilitySensor&lt;/span&gt; &lt;span class="na"&gt;itemId&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;onChange&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;handleVisibilityChange&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;NewsFeedItem&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This compiles down to:&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="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;NewsFeedItem&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;contents&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;contents&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;VisibilitySensor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;itemId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;onChange&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;handleVisibilityChange&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;Because React creates a new instance of &lt;code&gt;VisibilitySensor&lt;/code&gt; during each render, the &lt;code&gt;children&lt;/code&gt; prop always changes, so making &lt;code&gt;NewsFeedItem&lt;/code&gt; a &lt;code&gt;PureComponent&lt;/code&gt; would make things &lt;em&gt;worse&lt;/em&gt;, since a shallow comparison in &lt;code&gt;shouldComponentUpdate&lt;/code&gt; may not be cheap to run and will always return true.&lt;/p&gt;

&lt;p&gt;Our solution here was to move VisibilitySensor into a render prop and use a bound function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;NewsFeedItemWithHandlers&lt;/span&gt;
  &lt;span class="na"&gt;contents&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;contents&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;itemId&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;handleVisibilityChange&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;handleVisibilityChange&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;NewsFeedItemWithHandlers&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;PureComponent&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// The arrow function needs to get created outside of render, or the shallow comparison will fail&lt;/span&gt;
  &lt;span class="nx"&gt;renderVisibilitySensor&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="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;VisibilitySensor&lt;/span&gt;
      &lt;span class="na"&gt;itemId&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;itemId&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="na"&gt;onChange&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;handleVisibilityChange&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;NewsFeedItem&lt;/span&gt;
      &lt;span class="na"&gt;contents&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;contents&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="na"&gt;renderVisibilitySensor&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;renderVisibilitySensor&lt;/span&gt;&lt;span class="si"&gt;}&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;p&gt;Because the bound function only gets created once, the same function instance will be passed as props to &lt;code&gt;NewsFeedItem&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Second roadblock: Inline object created during render
&lt;/h2&gt;

&lt;p&gt;We had some code that was creating a new instance of a url helper in each render:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;getUrlHelper&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="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;NewsFeedUrlHelper&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;moreItemsUrlTemplate&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pollItemsUrlTemplate&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;updateItemsUrlTemplate&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;NewsFeedItemWithHandlers&lt;/span&gt;
    &lt;span class="na"&gt;contents&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;contents&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="na"&gt;urlHelper&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getUrlHelper&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="c1"&gt;// new object created with each method call&lt;/span&gt;
&lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since &lt;code&gt;getUrlHelper&lt;/code&gt; is computed from props, there's no point in creating more than one instance if we can cache the previous result and re-use that. We used &lt;a href="https://github.com/alexreardon/memoize-one"&gt;&lt;code&gt;memoize-one&lt;/code&gt;&lt;/a&gt; to solve this problem:&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;memoizeOne&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;memoize-one&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;memoizedUrlHelper&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;memoizeOne&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;moreItemsUrlTemplate&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;pollItemsUrlTemplate&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;updateItemsUrlTemplate&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
        &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;NewsFeedUrlHelper&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
            &lt;span class="nx"&gt;moreItemsUrlTemplate&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="nx"&gt;pollItemsUrlTemplate&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="nx"&gt;updateItemsUrlTemplate&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;}),&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// in the component&lt;/span&gt;
&lt;span class="nx"&gt;getUrlHelper&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;memoizedUrlHelper&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;moreItemsUrlTemplate&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pollItemsUrlTemplate&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;updateItemsUrlTemplate&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we will create a new url helper only when the dependent props change.&lt;/p&gt;

&lt;h2&gt;
  
  
  Measuring the difference
&lt;/h2&gt;

&lt;p&gt;The profiler now shows much better results: rendering NewsFeed is now down from ~50ms to ~5ms!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_41QwIJ0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://files.logoscdn.com/v1/files/14522909/content.png%3Fsignature%3DFzQeT-m0XOUSU2hSJ7x2cYMqNlo" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_41QwIJ0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://files.logoscdn.com/v1/files/14522909/content.png%3Fsignature%3DFzQeT-m0XOUSU2hSJ7x2cYMqNlo" alt="Better renders screenshot"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  PureComponent may make your performance worse
&lt;/h2&gt;

&lt;p&gt;As with any performance optimization, it's critical to measure the how changes impact performance.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;PureComponent&lt;/code&gt; is not an optimization that can blindly be applied to all components in your application. It's good for components in a list with deep render trees, which was the case in this example. If you're using arrow functions as props, inline objects, or inline arrays as props with a &lt;code&gt;PureComponent&lt;/code&gt;, both &lt;code&gt;shouldComponentUpdate&lt;/code&gt; &lt;em&gt;and&lt;/em&gt; &lt;code&gt;render&lt;/code&gt; will always get called, because new instances of those props will get created each time! Measure the performance of your changes to be sure they are an improvement.&lt;/p&gt;

&lt;p&gt;It may be perfectly fine for your team to use inline arrow functions on simple components, such as binding onClick handlers on &lt;code&gt;button&lt;/code&gt; elements inside a loop. Prioritize readability of your code first, then measure and add performance optimizations where it makes sense.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bonus experiment
&lt;/h2&gt;

&lt;p&gt;Since the pattern of creating components just to bind callbacks to props is pretty common in our codebase, we wrote a helper for generating components with pre-bound functions. Check it out &lt;a href="https://github.com/Faithlife/react-util/tree/dcdeed8e2b24562766150661aaae8cfcd07c2de8/src/withEventHandlers"&gt;on our Github repo&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;You can also use windowing libraries, such as &lt;a href="https://github.com/bvaughn/react-virtualized"&gt;react-virtualized&lt;/a&gt; to avoid rendering components that aren't in view.&lt;/p&gt;

&lt;p&gt;Thanks to Ian Mundy, Patrick Nausha, and Auresa Nyctea for providing feedback on early drafts of this post.&lt;/p&gt;

&lt;p&gt;Cover photo from Unsplash: &lt;a href="https://unsplash.com/photos/ot-I4_x-1cQ"&gt;https://unsplash.com/photos/ot-I4_x-1cQ&lt;/a&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>performance</category>
      <category>webdev</category>
      <category>javascript</category>
    </item>
    <item>
      <title>.NET Core in Docker on a Raspberry Pi</title>
      <dc:creator>masters.🤔</dc:creator>
      <pubDate>Fri, 04 May 2018 03:28:58 +0000</pubDate>
      <link>https://dev.to/dustinsoftware/net-core-in-docker-on-a-raspberry-pi-4ha6</link>
      <guid>https://dev.to/dustinsoftware/net-core-in-docker-on-a-raspberry-pi-4ha6</guid>
      <description>&lt;h3&gt;
  
  
  May 20, 2018 Update: This post is now obsolete as of .NET Core 2.1! Please see &lt;a href="https://blogs.msdn.microsoft.com/dotnet/2018/05/07/announcing-net-core-2-1-rc-1/"&gt;this&lt;/a&gt; blog post for details.
&lt;/h3&gt;




&lt;h3&gt;
  
  
  Out of date information below:
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;dotnet new react&lt;/code&gt; by default will give you a project that runs fine on x86/x64 architectures. The RPI, however, runs on arm32v7. We'll need to make a few small changes to support this architecture within Docker.&lt;/p&gt;

&lt;h3&gt;
  
  
  ARM is supported by ASP.NET Core, so why doesn't it just work in Docker?
&lt;/h3&gt;

&lt;p&gt;New projects by default include the metapackage &lt;a href="https://docs.microsoft.com/en-us/aspnet/core/fundamentals/metapackage"&gt;Microsoft.AspNetCore.All&lt;/a&gt;, which makes some assumptions about what libraries are already on the runtime target. For this to work with Docker, this means the runtime image needs to be &lt;a href="https://hub.docker.com/r/microsoft/aspnetcore/"&gt;microsoft/aspnetcore&lt;/a&gt;. However, this poses a problem!&lt;/p&gt;

&lt;p&gt;There is no ARM package for the microsoft/aspnetcore Docker image. The &lt;a href="https://github.com/aspnet/aspnet-docker/blob/3fb758ced1e1735d604b30dfc2ff554d2b7a2f5d/2.0/jessie/runtime/Dockerfile#L5"&gt;dockerfile&lt;/a&gt; indicates that pre-made binaries for this image are pulled from a CDN, but there don't appear to be any that exist for armv7.&lt;/p&gt;

&lt;h3&gt;
  
  
  Using a different base image
&lt;/h3&gt;

&lt;p&gt;Fortunately, there is a docker image already for the &lt;a href="https://github.com/dotnet/dotnet-docker/blob/master/2.0/runtime/stretch/arm32v7/Dockerfile"&gt;ARMv7 .NET Core runtime&lt;/a&gt;, we are be able to use that as a base image! Now we just have to declare the AspNetCore dependencies explicitly.&lt;/p&gt;

&lt;h3&gt;
  
  
  Getting started
&lt;/h3&gt;

&lt;p&gt;A working example of this project lives at &lt;a href="https://github.com/dustinsoftware/RPI-Docker-ASPNetCore"&gt;this GitHub repo&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a new project with &lt;code&gt;dotnet new react&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Remove the &lt;code&gt;Microsoft.AspNetCore.All&lt;/code&gt; reference in the project file and replace it with these references:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;    &lt;span class="nt"&gt;&amp;lt;PackageReference&lt;/span&gt; &lt;span class="na"&gt;Include=&lt;/span&gt;&lt;span class="s"&gt;"Microsoft.AspNetCore"&lt;/span&gt; &lt;span class="na"&gt;Version=&lt;/span&gt;&lt;span class="s"&gt;"2.0.0"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;PackageReference&lt;/span&gt; &lt;span class="na"&gt;Include=&lt;/span&gt;&lt;span class="s"&gt;"Microsoft.AspNetCore.Mvc"&lt;/span&gt; &lt;span class="na"&gt;Version=&lt;/span&gt;&lt;span class="s"&gt;"2.0.0"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;PackageReference&lt;/span&gt; &lt;span class="na"&gt;Include=&lt;/span&gt;&lt;span class="s"&gt;"Microsoft.AspNetCore.SpaServices"&lt;/span&gt; &lt;span class="na"&gt;Version=&lt;/span&gt;&lt;span class="s"&gt;"2.0.0"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;PackageReference&lt;/span&gt; &lt;span class="na"&gt;Include=&lt;/span&gt;&lt;span class="s"&gt;"Microsoft.AspNetCore.StaticFiles"&lt;/span&gt; &lt;span class="na"&gt;Version=&lt;/span&gt;&lt;span class="s"&gt;"2.0.0"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Verify the app still works with &lt;code&gt;dotnet run&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Create a Dockerfile that looks something like this:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; microsoft/aspnetcore-build:2 AS build-env&lt;/span&gt;
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /app&lt;/span&gt;

&lt;span class="c"&gt;# Copy csproj and restore as distinct layers&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; *.csproj ./&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;dotnet restore

&lt;span class="c"&gt;# Copy everything else and build&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; . ./&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;dotnet publish &lt;span class="nt"&gt;-c&lt;/span&gt; Release &lt;span class="nt"&gt;-o&lt;/span&gt; out

&lt;span class="c"&gt;# Build runtime image&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; microsoft/dotnet:2.0-runtime&lt;/span&gt;
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /app&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; --from=build-env /app/out ./&lt;/span&gt;
&lt;span class="k"&gt;ENTRYPOINT&lt;/span&gt;&lt;span class="s"&gt; ["dotnet", "DpmWebsite.dll"]&lt;/span&gt;
&lt;span class="k"&gt;EXPOSE&lt;/span&gt;&lt;span class="s"&gt; 5000&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, copy this dockerfile to a new file named &lt;code&gt;Dockerfile.arm32&lt;/code&gt;. This should be identical, except we're going to change the runtime image to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; microsoft/dotnet:2.0.0-runtime-stretch-arm32v7&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This allows the application to boot from the ARM version of the .NET SDK.&lt;/p&gt;

&lt;p&gt;Now, ensure a local build works:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker build &lt;span class="nt"&gt;-t&lt;/span&gt; netcore-local &lt;span class="nb"&gt;.&lt;/span&gt;
docker run &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; 5000:5000 netcore-local
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once this is confirmed working, build an ARM specific image:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker build &lt;span class="nt"&gt;-t&lt;/span&gt; yourdockerid/rpi-net-core &lt;span class="nt"&gt;-f&lt;/span&gt; Dockerfile.arm32 &lt;span class="nb"&gt;.&lt;/span&gt;
docker push yourdockerid/rpi-net-core
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, pull the image and run it on your Raspberry Pi!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker pull yourdockerid/rpi-net-core
docker run &lt;span class="nt"&gt;--restart&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;always &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; 5000:5000 yourdockerid/rpi-net-core
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you are having trouble, get the ID of the image, then use &lt;code&gt;docker logs (containerid)&lt;/code&gt;&lt;/p&gt;

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

&lt;p&gt;This was a fun exercise. It's so exciting to see the .NET platform become more accessible, hats off to the whole team for making this a reality!&lt;/p&gt;

</description>
      <category>docker</category>
      <category>dotnet</category>
      <category>raspberrypi</category>
    </item>
    <item>
      <title>Inspecting application state with the SOS debugging tools</title>
      <dc:creator>masters.🤔</dc:creator>
      <pubDate>Tue, 09 Jan 2018 23:44:10 +0000</pubDate>
      <link>https://dev.to/dustinsoftware/inspecting-application-state-with-the-sos-debugging-tools-i3a</link>
      <guid>https://dev.to/dustinsoftware/inspecting-application-state-with-the-sos-debugging-tools-i3a</guid>
      <description>&lt;p&gt;This post originally appeared on &lt;a href="https://faithlife.codes/blog/2018/01/using-sos/"&gt;Faithlife.Codes&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In this post, we'll cover how to use the SOS debugging tools to inspect variables from a process dump of a .NET Framework / .NET Core application.&lt;/p&gt;

&lt;p&gt;Required:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/en-us/sysinternals/downloads/procdump"&gt;ProcDump&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.microsoft.com/en-us/windows/hardware/download-windbg"&gt;Debugging Tools for Windows&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Obtaining a memory dump
&lt;/h3&gt;

&lt;p&gt;In this first example, we'll use a running ASP.NET MVC 5 application hosted by IIS, but the steps here can be used on a normal .NET framework Windows application. Let's start by taking a full memory dump of a running application.&lt;/p&gt;

&lt;p&gt;Download &lt;a href="https://docs.microsoft.com/en-us/sysinternals/downloads/procdump"&gt;ProcDump&lt;/a&gt; and copy it to the server that runs the application you want to debug. Obtain the process ID from the application you want to profile by using Task Manager, and then pass it as an argument to &lt;code&gt;procdump&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;procdump -ma &amp;lt;pid&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should now have a dump named similar to &lt;code&gt;w3wp_171229_151050.dmp&lt;/code&gt; in the working directory.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note:&lt;/p&gt;

&lt;p&gt;If you're running several applications under a single app pool in IIS, it may be easier to debug by changing the app to run under its own application pool, which allows the ASP.NET app to run under a dedicated process.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Inspecting the ASP.NET application state (.NET Framework)
&lt;/h3&gt;

&lt;p&gt;Now that we have a memory dump, it's time to look at the suspended state of the application. Copy the dump file to your workstation, and then open it via &lt;code&gt;File &amp;gt; Open Crash Dump&lt;/code&gt; in WinDBG. Your screen should look like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--LWKe7llj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://files.logoscdn.com/v1/files/9282765/content.png%3Fsignature%3DOutnTBW6SL3XDlxpFWtUZ2RUzfc" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--LWKe7llj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://files.logoscdn.com/v1/files/9282765/content.png%3Fsignature%3DOutnTBW6SL3XDlxpFWtUZ2RUzfc" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Load the SOS debugging extension, which will allow us to inspect the managed threads:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;!loadby sos clr
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, list the stack trace of every thread:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Note:&lt;/p&gt;

&lt;p&gt;If get an exception when running this command and you are using IIS Express, try the command again. There appears to be a bug that throws an exception only for the first command run from WinDbg, which should not affect the rest of your debugging session.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--pqihxRtd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://files.logoscdn.com/v1/files/9282876/content.png%3Fsignature%3DP1C00NAOb2CSQf4qm0Qg37XH3ls" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--pqihxRtd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://files.logoscdn.com/v1/files/9282876/content.png%3Fsignature%3DP1C00NAOb2CSQf4qm0Qg37XH3ls" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You should see a lot of threads in the output. To narrow the results down, search for the namespace of your project in the output text.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--VRfpCxAk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://files.logoscdn.com/v1/files/9282925/content.png%3Fsignature%3DsEIcoMZ_m8UjW8JMkJKq5bAkuD0" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--VRfpCxAk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://files.logoscdn.com/v1/files/9282925/content.png%3Fsignature%3DsEIcoMZ_m8UjW8JMkJKq5bAkuD0" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can see that there is an external web request being made in Thread 34. Let's look at what external URL is being requested. Switch to the thread, and then run &lt;code&gt;clrstack -p&lt;/code&gt; to get some more detailed information about each method call.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;~34 s
!clrstack -p
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--wFJYt5xT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://files.logoscdn.com/v1/files/9282962/content.png%3Fsignature%3Da-iJjR35uoEII6z6HF9A8CrY-As" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--wFJYt5xT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://files.logoscdn.com/v1/files/9282962/content.png%3Fsignature%3Da-iJjR35uoEII6z6HF9A8CrY-As" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note:&lt;/p&gt;

&lt;p&gt;You may see many arguments that contain the value &lt;code&gt;&amp;lt;no data&amp;gt;&lt;/code&gt;. This can be caused by compiler optimizations; inspecting the state of these parameters is beyond the scope of this article.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The controller is present in this call stack, so let's inspect the object instance by clicking on the &lt;code&gt;this&lt;/code&gt; instance address, which is a shortcut for the &lt;code&gt;!DumpObj&lt;/code&gt; command.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--DLqoWK0j--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://files.logoscdn.com/v1/files/9283010/content.png%3Fsignature%3DncBPHOf0p0B2gOBoHMkOF1WVCdU" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DLqoWK0j--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://files.logoscdn.com/v1/files/9283010/content.png%3Fsignature%3DncBPHOf0p0B2gOBoHMkOF1WVCdU" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This instance contains a field named &lt;code&gt;_request&lt;/code&gt;, which contained a field named &lt;code&gt;requestUri&lt;/code&gt;, which has the original URI for this request:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--7bQ9KjGb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://files.logoscdn.com/v1/files/9283018/content.png%3Fsignature%3DGqnF5Ecb6yNF9VOBWnH08UjeT8g" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7bQ9KjGb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://files.logoscdn.com/v1/files/9283018/content.png%3Fsignature%3DGqnF5Ecb6yNF9VOBWnH08UjeT8g" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That's it! The commands vary slightly for dumping different field types.&lt;/p&gt;




&lt;h3&gt;
  
  
  .NET Core application on Linux
&lt;/h3&gt;

&lt;p&gt;Required:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;LLDB 3.9&lt;/li&gt;
&lt;li&gt;Locally-built copy of the SOS plugin in the CoreCLR repo - &lt;a href="https://github.com/dotnet/coreclr/blob/e432923a0cc31e1c34f94c5a2e9b75570ecf9d9a/Documentation/building/linux-instructions.md"&gt;instructions&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In this next scenario, we'll look at inspecting a core dump from a .NET Core app running on an Ubuntu x64 instance. The instance will have a core dump taken while a request is processing, which we will then inspect.&lt;/p&gt;

&lt;p&gt;Take a core dump of the process using the &lt;code&gt;createdump&lt;/code&gt; utility. These commands assume you have the coreclr repo checked out to &lt;code&gt;~/git/coreclr&lt;/code&gt;, and that you're running an application built with .NET Core 2.0.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo ~/git/coreclr/bin/Product/Linux.x64.Debug/createdump -u (pid)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Load the dump in LLDB. This command also loads the SOS debugging extension.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;lldb-3.9 dotnet -c /tmp/coredump.18842 -o "plugin load ~/git/coreclr/bin/Product/Linux.x64.Debug/libsosplugin.so"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After a few moments, a CLI will become available. Run &lt;code&gt;eestack&lt;/code&gt; to dump the state of all CLR threads. If you get an empty output or a segmentation fault, verify that you are running the correct version of &lt;code&gt;lldb&lt;/code&gt; and are loading &lt;code&gt;libsosplugin&lt;/code&gt; from the bin directory, and that you have created the core dump with &lt;code&gt;createdump&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--DVliqqn9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://files.logoscdn.com/v1/files/9344627/content.png%3Fsignature%3D8MbFKjB-x-o5H7aI6yf8JKSj7U4" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DVliqqn9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://files.logoscdn.com/v1/files/9344627/content.png%3Fsignature%3D8MbFKjB-x-o5H7aI6yf8JKSj7U4" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There is an instance of &lt;code&gt;HomeController&lt;/code&gt; in the stack of Thread 17. Switch to it to reveal more information about the current request. This time, we'll inspect the state of an internal .NET Core request frame, since information about the current request isn't as accessible as it was in ASP.NET MVC 5.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;thread select 17
sos DumpStackObjects
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Look for the address of &lt;code&gt;Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.Frame'1[[Microsoft.AspNetCore.Hosting.Internal.HostingApplication+Context, Microsoft.AspNetCore.Hosting]]&lt;/code&gt; in the output, and then dump the object. The name of this class might differ slightly based on the version of the framework you're running.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ILgf-ila--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://files.logoscdn.com/v1/files/9344645/content.png%3Fsignature%3DFvWisjSHfow2R8CetEVQF-BSTss" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ILgf-ila--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://files.logoscdn.com/v1/files/9344645/content.png%3Fsignature%3DFvWisjSHfow2R8CetEVQF-BSTss" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Identify the &lt;code&gt;QueryString&lt;/code&gt; field address:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Sza0tIAJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://files.logoscdn.com/v1/files/9344656/content.png%3Fsignature%3DtSUH7-hjtnIhxElgR2JYdsKx6Ng" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Sza0tIAJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://files.logoscdn.com/v1/files/9344656/content.png%3Fsignature%3DtSUH7-hjtnIhxElgR2JYdsKx6Ng" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Dumping that field reveals the query part of the URL the browser requested!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--hhBWPgqj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://files.logoscdn.com/v1/files/9344665/content.png%3Fsignature%3D6oo1knWMliccP1fnUFtQblQQwjk" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hhBWPgqj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://files.logoscdn.com/v1/files/9344665/content.png%3Fsignature%3D6oo1knWMliccP1fnUFtQblQQwjk" alt=""&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;Thanks to Kyle Sletten, Justin Brooks, and Bradley Grainger for reviewing early drafts of this post.&lt;/p&gt;

&lt;p&gt;Further reading:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.microsoft.com/en-us/dotnet/framework/tools/sos-dll-sos-debugging-extension"&gt;SOS.dll (SOS Debugging Extension)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/dotnet/coreclr/blob/e432923a0cc31e1c34f94c5a2e9b75570ecf9d9a/Documentation/building/debugging-instructions.md"&gt;.NET Core Debugging Instructions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/dotnet/coreclr/blob/e432923a0cc31e1c34f94c5a2e9b75570ecf9d9a/Documentation/building/osx-instructions.md"&gt;Building CoreCLR on OS X&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/dotnet/coreclr/blob/e432923a0cc31e1c34f94c5a2e9b75570ecf9d9a/Documentation/building/buildinglldb.md"&gt;Building LLDB&lt;/a&gt; - Required for debugging .NET Core on OS X&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/dotnet/coreclr/blob/38ec680aa59010221bfc15afa23af73764fd0406/Documentation/botr/xplat-minidump-generation.md"&gt;.NET Core MiniDump Format&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>coreclr</category>
      <category>dotnet</category>
      <category>debugging</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Mitigating cross-site scripting with Content Security Policy</title>
      <dc:creator>masters.🤔</dc:creator>
      <pubDate>Thu, 21 Dec 2017 19:18:20 +0000</pubDate>
      <link>https://dev.to/dustinsoftware/mitigating-cross-site-scripting-with-content-security-policy-40gb</link>
      <guid>https://dev.to/dustinsoftware/mitigating-cross-site-scripting-with-content-security-policy-40gb</guid>
      <description>&lt;p&gt;In this post, we're going to look at using Content Security Policy (CSP) as a defense-in-depth technique to block script injection attacks.&lt;/p&gt;

&lt;p&gt;When building website that hosts user-generated content, such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;Great to be here!
&lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://example.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's necessary to encode user-generated content so that browsers don't mistake it for markup, and execute an untrusted script. This is easy to do for plain text, but what if a page needs to render user-generated HTML? Here's an example of HTML that contains inline Javascript, which browsers could execute:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;Great to &lt;span class="nt"&gt;&amp;lt;b&amp;gt;&lt;/span&gt;be&lt;span class="nt"&gt;&amp;lt;/b&amp;gt;&lt;/span&gt; here!&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt; &lt;span class="na"&gt;onerror=&lt;/span&gt;&lt;span class="s"&gt;"alert(0)"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"javascript:alert(0)"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Hi&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://example.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This content must be sanitized before rendering. Libraries such as HTMLAgilityPack or DOMPurify provide a way to parse the HTML and strip out elements or attributes known to execute scripts.&lt;/p&gt;

&lt;p&gt;Sanitization is important, but what if an attacker has discovered a way around the filter? This is where &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/script-src"&gt;Content Security Policy&lt;/a&gt; comes in.&lt;/p&gt;

&lt;p&gt;If the &lt;code&gt;Content-Security-Policy&lt;/code&gt; header is present when retrieving the page, and contains a &lt;code&gt;script-src&lt;/code&gt; definition, scripts will be blocked unless they match one of the sources specified in the policy. A policy might look something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;script-src 'self'; object-src 'none'; base-uri 'none';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This policy disallows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;External scripts not hosted on the same domain as the current page.&lt;/li&gt;
&lt;li&gt;Inline script elements, such as &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Evaluated Javascript, such as &lt;code&gt;&amp;lt;img src="" onerror="alert(0)" /&amp;gt;&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Base elements, which could break scripts loaded from a relative path&lt;/li&gt;
&lt;li&gt;Object elements, which can host interactive content, such as Flash&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Whitelisting inline scripts
&lt;/h3&gt;

&lt;p&gt;Sometimes it is necessary to run inline scripts on your page. In these cases, the &lt;code&gt;nonce&lt;/code&gt; attribute on &lt;code&gt;script&lt;/code&gt; elements can be used to whitelist scripts that you control.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;nonce=&lt;/span&gt;&lt;span class="s"&gt;"00deadbeef"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;doSomething&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A matching nonce must be present in the CSP for the script to run. For compatibility with older browsers, &lt;code&gt;unsafe-inline&lt;/code&gt; allows scripts to run if the &lt;code&gt;nonce&lt;/code&gt; tag is unsupported.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;script-src 'self' 'nonce-00deadbeef' 'unsafe-inline'; object-src 'none'; base-uri 'none';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It is critical that this nonce is derived from a cryptographic random number generator so that an attacker can't guess a future nonce. In .NET, &lt;code&gt;RNGCryptoServiceProvider.GetBytes&lt;/code&gt; can be used to fill a 16 byte array:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;random&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;RNGCryptoServiceProvider&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;nonce&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;16&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="n"&gt;random&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetBytes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nonce&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Convert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ToBase64String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nonce&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;h3&gt;
  
  
  Whitelisting external scripts
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;strict-dynamic&lt;/code&gt; can be used to allow scripts hosted on a third-party domain to be loaded by scripts that you control. However, at the time of writing, this isn't supported by all major browsers, so a host whitelist should be used as well as a fallback until it has broad support.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;script-src 'self' 'nonce-00deadbeef' 'unsafe-inline' 'strict-dynamic' https://example.com; object-src 'none'; base-uri 'none';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When using &lt;code&gt;strict-dynamic&lt;/code&gt;, you will also need to add a &lt;code&gt;nonce&lt;/code&gt; to any external scripts that are referenced.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;script nonce="00deadbeef" src="https://example.com/analytics.js" /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Be careful what sources you whitelist. If any endpoints return JSONP and fail to sanitize the callback, it is possible to inject code. For example:&lt;/p&gt;


&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://example.com/getuser?callback=window.location='http://google.com';test"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;Might return &lt;code&gt;window.location='http://google.com';test({})&lt;/code&gt; in the JSONP response, which would cause arbitrary code to be executed!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;There are other policies that you can define to strengthen your site's security, such as restricting where stylesheets are loaded from. This post only focuses on mitigating cross-site scripting attacks.&lt;/p&gt;

&lt;h3&gt;
  
  
  Further Reading
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.w3.org/TR/CSP3/"&gt;CSP 3&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://csp-evaluator.withgoogle.com/"&gt;CSP Evaluator&lt;/a&gt; can be used to spot vulnerabilities in a policy.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://csp.withgoogle.com/docs/index.html"&gt;Introduction to CSP&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP"&gt;Mozilla Documentation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thanks to Bradley Grainger and Kyle Sletten for reviewing this implementation.&lt;/p&gt;

</description>
      <category>security</category>
      <category>xss</category>
      <category>javascript</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
