<?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: Christian Kotzbauer</title>
    <description>The latest articles on DEV Community by Christian Kotzbauer (@ckotzbauer).</description>
    <link>https://dev.to/ckotzbauer</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%2F376968%2Fba2d1885-7bc1-48f7-ad95-6761559eb8a2.jpeg</url>
      <title>DEV Community: Christian Kotzbauer</title>
      <link>https://dev.to/ckotzbauer</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ckotzbauer"/>
    <language>en</language>
    <item>
      <title>Announcing the Simple-Tree-Component!</title>
      <dc:creator>Christian Kotzbauer</dc:creator>
      <pubDate>Sat, 19 Jun 2021 14:44:30 +0000</pubDate>
      <link>https://dev.to/ckotzbauer/announcing-the-simple-tree-component-46nd</link>
      <guid>https://dev.to/ckotzbauer/announcing-the-simple-tree-component-46nd</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Over a year ago, a colleague of mine and me were searching for a javascript-component capable for tree-rendering. There were a few must-have aspects we were looking for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Zero runtime-dependencies (especially no JQuery)&lt;/li&gt;
&lt;li&gt;Actively maintained&lt;/li&gt;
&lt;li&gt;Framework-agnostic&lt;/li&gt;
&lt;li&gt;Good integration with modern bundlers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These requirements did already reduce the number of possible libraries to a considerable degree. In addition, we had to consider the requirements of our product as well:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Text-search through tree-nodes&lt;/li&gt;
&lt;li&gt;Mode where the tree is rendered in a container&lt;/li&gt;
&lt;li&gt;Dropdown-mode for single-selection&lt;/li&gt;
&lt;li&gt;Dropdown-mode for multi-selection&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Neither did any component meet our requirements, nor did using two libraries for the different use-cases turn out to be sufficient. So we started considering the effort of developing and maintaining our own component with some extras, as TypeScript support. The "&lt;a href="https://github.com/ckotzbauer/simple-tree-component"&gt;Simple-Tree-Component&lt;/a&gt;" was born. The first lockdown-phase of the Covid-pandemic in summer 2020 gave us time to implement the basics.&lt;/p&gt;

&lt;p&gt;Let's have a look at the different features and concepts.&lt;/p&gt;

&lt;h2&gt;
  
  
  Three modes
&lt;/h2&gt;

&lt;p&gt;As mentioned above, we had to implement different modes for multiple use-cases and ui-scenarios. The simplest mode simply renders the tree in a container:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9KLocI_v--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kr1459m93lcqe8s7c5ys.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9KLocI_v--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kr1459m93lcqe8s7c5ys.png" alt="View-Only"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It's possible to enable multi-selection with Checkboxes if needed. Furthermore, it can be configured whether child-nodes are automatically selected or deselected when a parent-node changes its selection-state.&lt;/p&gt;

&lt;p&gt;The second variant we had to get covered, was a single-select dropdown:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2r0NgB8s--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sdvoej46n3j87ptrg75a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2r0NgB8s--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sdvoej46n3j87ptrg75a.png" alt="Single-Select"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When the dropdown-flyout is closed, only the box itself is displayed in the same way as of native &lt;code&gt;&amp;lt;select&amp;gt;&lt;/code&gt; HTML-elements. A function can be defined which is called on each node-selection to customize the text displayed in closed-state. With the Emphasize-feature it is possible to add a custom css-class to the component-box. This, for example, makes it possible to add a icon as "eye-catcher" for the current selection.&lt;/p&gt;

&lt;p&gt;Last but not least, the component can handle multi-selections with a dropdown, too. All selected nodes are rendered as pillboxes and can be deselected individually or all at once.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--jswXg_kG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ahg0dd8i4yxhao47ody3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--jswXg_kG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ahg0dd8i4yxhao47ody3.png" alt="Multi-Select"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Most of the features mentioned for the "single-selection" mode can be used for "multi-selection" as well.&lt;/p&gt;

&lt;h2&gt;
  
  
  Search and Highlighting
&lt;/h2&gt;

&lt;p&gt;In all mode-variants it is possible to enable the text-search-feature to filter tree-nodes. The chain from a matching child-node to its root-node is always displayed. By default non-matching childs are not displayed when a parent-node matches the search-text but this behaviour can be changed individually. In addition to searching in general, the search-results can be highlighted as well.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--AYyh60gT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rziaffu4k5tprwperdbb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--AYyh60gT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rziaffu4k5tprwperdbb.png" alt="Highlighting"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Styling
&lt;/h2&gt;

&lt;p&gt;All styles are implemented with SASS to ensure good adaptability. The sass-files are also part of the NPM package.&lt;/p&gt;

&lt;h2&gt;
  
  
  Data-driven
&lt;/h2&gt;

&lt;p&gt;The main concept for data-handling was using a completely data-driven approach. The reason for it was the necessity of removing and modifying existing tree-nodes and adding new ones when the tree is already rendered. Even though it would be possible to use a DOM-driven approach here, extracting the data-states from the UI and still making it work with any framework at the same time would turn out more difficult.&lt;/p&gt;

&lt;h2&gt;
  
  
  Type-safety
&lt;/h2&gt;

&lt;p&gt;The whole code is developed in &lt;a href="https://www.typescriptlang.org/"&gt;TypeScript&lt;/a&gt; with a very strong typing, especially for the public API. This makes development for library-contributors and for developers easier and more efficient.&lt;/p&gt;

&lt;h2&gt;
  
  
  Browser compatibility
&lt;/h2&gt;

&lt;p&gt;The code is compiled to &lt;code&gt;ES2015&lt;/code&gt; at the moment. This should ensure compability to most modern browsers. However - also due to the lack of cross-browser tests - there is no explicit list of supported browsers or versions. The only thing we can be sure about is, that there will never be support for any Internet Explorer version. :)&lt;/p&gt;

&lt;h2&gt;
  
  
  Documentation
&lt;/h2&gt;

&lt;p&gt;All features, other aspects and a "Getting started" are also &lt;a href="https://www.ckotzbauer.de/simple-tree-component/#/"&gt;documented&lt;/a&gt;. At the &lt;a href="https://github.com/ckotzbauer/simple-tree-component"&gt;Github-Repo&lt;/a&gt; you can find a demo-integration with the SPA-Framework "&lt;a href="https://aurelia.io/"&gt;Aurelia&lt;/a&gt;".&lt;/p&gt;

&lt;h2&gt;
  
  
  Contributions
&lt;/h2&gt;

&lt;p&gt;As every open-source project, this component is also open for issues, discussions and feature-requests. Do not hesistate to reach out to us. We're looking forward to your feedback.&lt;/p&gt;

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

&lt;p&gt;There are some new features in development as well as improvements for increasing the stability even more. At the end of this post I want to say "Thank you!" to my colleague &lt;a href="https://github.com/coding-komek"&gt;Thomas&lt;/a&gt; who helped me a lot in creating this library from the first day on. Many thanks!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>ux</category>
      <category>tree</category>
      <category>typescript</category>
    </item>
    <item>
      <title>Managing K8s Authorization like charm</title>
      <dc:creator>Christian Kotzbauer</dc:creator>
      <pubDate>Sat, 13 Jun 2020 10:27:23 +0000</pubDate>
      <link>https://dev.to/ckotzbauer/managing-k8s-authorization-like-charm-h62</link>
      <guid>https://dev.to/ckotzbauer/managing-k8s-authorization-like-charm-h62</guid>
      <description>&lt;h1&gt;
  
  
  Managing K8s Authorization like charm
&lt;/h1&gt;

&lt;p&gt;Administrating complex authorization scenarios with fine-grained permissions is often difficult. In the Kubernetes ecosystem, the "Role-based-Access-Control" (RBAC) pattern is often used to do authorization for different users and groups in your cluster. RBAC is very powerful, but gets complex if you want to grant permissions on a namespace-basis.&lt;/p&gt;

&lt;p&gt;At work I faced this challange and wanted to simplify the definiton, creation and removal of those rules. The result of this simplification is the "&lt;a href="https://github.com/ckotzbauer/access-manager"&gt;access-manager&lt;/a&gt;", a Kubernetes-Operator I built to manage &lt;code&gt;RoleBinding&lt;/code&gt; and &lt;code&gt;ClusterRoleBinding&lt;/code&gt;s. These two objects are used to assign permissions defined in &lt;code&gt;Role&lt;/code&gt;s and &lt;code&gt;ClusterRole&lt;/code&gt;s to accounts (Users, Groups, ServiceAccounts). And this assignment is often the complex part.&lt;/p&gt;

&lt;h2&gt;
  
  
  Example
&lt;/h2&gt;

&lt;p&gt;Let's start with an example, to make it more descriptive:&lt;/p&gt;

&lt;p&gt;Given you have the following namespaces in Kubernetes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ci-service&lt;/li&gt;
&lt;li&gt;product-a&lt;/li&gt;
&lt;li&gt;product-b&lt;/li&gt;
&lt;li&gt;monitoring&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And you have the following individuals or groups in your cluster:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Jane&lt;/li&gt;
&lt;li&gt;John&lt;/li&gt;
&lt;li&gt;Support (a group of user)&lt;/li&gt;
&lt;li&gt;The ci-service solution&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Jane is an administrator and needs access to all namespaces. John needs write-access to &lt;code&gt;product-a&lt;/code&gt; and &lt;code&gt;product-b&lt;/code&gt;. The support-group has to view (read-only) the two products and the &lt;code&gt;monitoring&lt;/code&gt; namespace. As last requirement, the &lt;code&gt;ServiceAccount&lt;/code&gt; of &lt;code&gt;ci-service&lt;/code&gt; should be able to deploy new versions of the two products. For simplicity the &lt;code&gt;Role&lt;/code&gt;s and &lt;code&gt;ClusterRole&lt;/code&gt;s are already defined and the John and the CI should use the same role.&lt;/p&gt;

&lt;p&gt;This scenario would end up in&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;one &lt;code&gt;ClusterRoleBinding&lt;/code&gt;, where &lt;code&gt;Jane&lt;/code&gt; is assigned to the &lt;code&gt;cluster-admin&lt;/code&gt; role,&lt;/li&gt;
&lt;li&gt;one &lt;code&gt;RoleBinding&lt;/code&gt; in the two product namespaces, which assignes the User &lt;code&gt;John&lt;/code&gt; and the &lt;code&gt;ci-service&lt;/code&gt; ServiceAccount to manage the products,&lt;/li&gt;
&lt;li&gt;one &lt;code&gt;RoleBinding&lt;/code&gt; in the two product namespaces and the &lt;code&gt;monitoring&lt;/code&gt; namespace for the support-group.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So six &lt;code&gt;(Cluster-)RoleBinding&lt;/code&gt;s are needed to achieve this. And the setup has to grow, if there would be a &lt;code&gt;product-c&lt;/code&gt; namespace some day.&lt;/p&gt;

&lt;p&gt;Let's get the operator into play and define the above:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;access-manager.io/v1beta1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;RbacDefinition&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;my-definition&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;namespaced&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;namespaceSelector&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;matchLabels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;management&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;true'&lt;/span&gt;
      &lt;span class="na"&gt;bindings&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;roleName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;product-write-permission&lt;/span&gt;
          &lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ClusterRole&lt;/span&gt;
          &lt;span class="na"&gt;subjects&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ci-service&lt;/span&gt;
              &lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ServiceAccount&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;john&lt;/span&gt;
              &lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;User&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;namespaceSelector&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;matchLabels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;support&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;true'&lt;/span&gt;
      &lt;span class="na"&gt;bindings&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;roleName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;support-permission&lt;/span&gt;
          &lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ClusterRole&lt;/span&gt;
          &lt;span class="na"&gt;subjects&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;support&lt;/span&gt;
              &lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Group&lt;/span&gt;
  &lt;span class="na"&gt;cluster&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;jane-admin&lt;/span&gt;
      &lt;span class="na"&gt;clusterRoleName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;cluster-admin&lt;/span&gt;
      &lt;span class="na"&gt;subjects&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;jane&lt;/span&gt;
          &lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;User&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;I introduced two different labels on namespaces: All namespaces labeled with &lt;code&gt;management: true&lt;/code&gt; are eligible to be managed from John and through the &lt;code&gt;ci-service&lt;/code&gt;. All namespaced which should be viewed from the support-group are labeled with &lt;code&gt;support: true&lt;/code&gt;. If there would be a &lt;code&gt;namespace-c&lt;/code&gt; some day, all you have to do is, to add the needed labels. The operator will do the rest for you. Changes to namespaces or these &lt;code&gt;RbacDefinition&lt;/code&gt;s are automatically detected and the desired state is applied.&lt;/p&gt;

&lt;p&gt;For more detailed informations for the definition and other features, please read the &lt;a href="https://github.com/ckotzbauer/access-manager/blob/master/docs/api.md"&gt;api-docs&lt;/a&gt;.&lt;/p&gt;

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

&lt;p&gt;Role-based authorization in Kubernetes becomes more complex as the cluster grows and more different accounts getting access. With the "access-manager" it is possible to just define the Roles needed and the the assignment-rules to accounts. The creation, modification and removal of the concrete Bindings is fully managed and nothing you have to care about.&lt;/p&gt;

&lt;h2&gt;
  
  
  Found a typo?
&lt;/h2&gt;

&lt;p&gt;If you've found a typo, a sentence that could be improved or anything else that should be updated on this blog post, you can access it through a git repository and make a pull request. Instead of posting a comment, please go directly to &lt;a href="https://github.com/ckotzbauer/dev.to-posts"&gt;https://github.com/ckotzbauer/dev.to-posts&lt;/a&gt; and open a new pull request with your changes.&lt;/p&gt;

</description>
      <category>kubernetes</category>
      <category>authorization</category>
      <category>rbac</category>
      <category>k8s</category>
    </item>
    <item>
      <title>Cache-Reset with Webpack</title>
      <dc:creator>Christian Kotzbauer</dc:creator>
      <pubDate>Sun, 03 May 2020 07:59:56 +0000</pubDate>
      <link>https://dev.to/ckotzbauer/cache-reset-with-webpack-2jh4</link>
      <guid>https://dev.to/ckotzbauer/cache-reset-with-webpack-2jh4</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published on January 22, 2017&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;There are several strategies to implement a caching mechanism. The common way with Webpack is, to change the file&lt;br&gt;
name and add a content-based hash. The advantage of this is, that the file only needs to be reloaded if its content&lt;br&gt;
changed. But the disadvantage is (e.g. for images) that all references in your source-code have to be modified in&lt;br&gt;
order to match the different file names, but this seems to be solvable. But what happens, if you start generating some paths&lt;br&gt;
through variables at runtime? So I considered to use a fairly old mechanism: Cache-Busting with a Query-Parameter.&lt;br&gt;
To append this parameter to all the code references, I wrote a custom webpack-loader.&lt;/p&gt;

&lt;h2&gt;
  
  
  Usage
&lt;/h2&gt;

&lt;p&gt;First, install the loader through npm:&lt;/p&gt;

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

npm install cache-bust-loader


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

&lt;/div&gt;

&lt;p&gt;Assuming, that the list of loaders in your &lt;code&gt;webpack.config.js&lt;/code&gt; looks similar to this:&lt;/p&gt;

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

&lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;test&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;\.&lt;/span&gt;&lt;span class="sr"&gt;css$/&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;loader&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ExtractTextPlugin&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;extract&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;loader&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;css-loader&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;span class="na"&gt;test&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;\.&lt;/span&gt;&lt;span class="sr"&gt;html$/&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;loader&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;raw-loader&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="na"&gt;test&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;\.&lt;/span&gt;&lt;span class="sr"&gt;ts$/&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;loader&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;awesome-typescript-loader&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;Now, simply add the &lt;code&gt;cache-bust-loader&lt;/code&gt; to each file-type where you reference other files which you want to be cache-busted:&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;cacheBustLoader&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`cache-bust-loader?name=bust&amp;amp;value=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;bustValue&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;test&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;\.&lt;/span&gt;&lt;span class="sr"&gt;css$/&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;loader&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ExtractTextPlugin&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;extract&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;loader&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;cacheBustLoader&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;!css-loader`&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="na"&gt;test&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;\.&lt;/span&gt;&lt;span class="sr"&gt;html$/&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;loader&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;cacheBustLoader&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;!raw-loader`&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;test&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;\.&lt;/span&gt;&lt;span class="sr"&gt;ts$/&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;loader&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;cacheBustLoader&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;!awesome-typescript-loader`&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 loader has three parameters:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Parameter&lt;/th&gt;
&lt;th&gt;Mandatory&lt;/th&gt;
&lt;th&gt;Data type&lt;/th&gt;
&lt;th&gt;Default value&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;name&lt;/td&gt;
&lt;td&gt;True&lt;/td&gt;
&lt;td&gt;String&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;value&lt;/td&gt;
&lt;td&gt;False&lt;/td&gt;
&lt;td&gt;String&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;types&lt;/td&gt;
&lt;td&gt;False&lt;/td&gt;
&lt;td&gt;String&lt;/td&gt;
&lt;td&gt;eot;woff;woff2;svg;ttf;otf;jpg;jpeg;png;ico;gif;json&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The &lt;code&gt;name&lt;/code&gt; describes the name of the query parameter, the &lt;code&gt;value&lt;/code&gt; the string which should change every build.&lt;br&gt;
If the &lt;code&gt;value&lt;/code&gt; is empty, no parameters are applied (e.g. in development mode). The &lt;code&gt;types&lt;/code&gt; are file-types&lt;br&gt;
which you want to be cache-busted. Split them with a semicolon.&lt;/p&gt;

&lt;p&gt;To generate a short unique string for each build you can fill &lt;code&gt;bustValue&lt;/code&gt; like this:&lt;/p&gt;


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

&lt;p&gt;&lt;span class="nx"&gt;bustValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;randomstring&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;generate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;/p&gt;

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

&lt;/div&gt;
&lt;h2&gt;
&lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
  Result&lt;br&gt;
&lt;/h2&gt;

&lt;p&gt;Open your browser-network-tab:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fckotzbauer%2Fdev.to-posts%2Fmaster%2Fblog-posts%2F2020%2Fcache-reset-with-webpack%2Fassets%2Fnetwork-tab.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fckotzbauer%2Fdev.to-posts%2Fmaster%2Fblog-posts%2F2020%2Fcache-reset-with-webpack%2Fassets%2Fnetwork-tab.jpg" alt="network-tab"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;This webpack-loader makes it easy to implement a basic cache-reset mechanism. All files matching the file-type have the query-parameter appended&lt;br&gt;
and are reloaded if a new version of your frontend-project is deployed.&lt;/p&gt;

&lt;h1&gt;
  
  
  Found a typo?
&lt;/h1&gt;

&lt;p&gt;If you've found a typo, a sentence that could be improved or anything else that should be updated on this blog post, you can access it through a git repository and make a pull request. Instead of posting a comment, please go directly to &lt;a href="https://github.com/ckotzbauer/dev.to-posts"&gt;https://github.com/ckotzbauer/dev.to-posts&lt;/a&gt; and open a new pull request with your changes.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>webpack</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Migrating from Durandal to Aurelia</title>
      <dc:creator>Christian Kotzbauer</dc:creator>
      <pubDate>Sat, 02 May 2020 11:41:01 +0000</pubDate>
      <link>https://dev.to/ckotzbauer/migrating-from-durandal-to-aurelia-o80</link>
      <guid>https://dev.to/ckotzbauer/migrating-from-durandal-to-aurelia-o80</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published on June 15, 2016&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;If you have an existing Durandal application you maybe want to migrate this app to Aurelia. Typically you used&lt;br&gt;
Knockout for data-binding. Because Aurelia brings its own data-binding language the usage of Knockout&lt;br&gt;
is not necessary anymore. But probably especially this part of the migration requires the greatest effort,&lt;br&gt;
because you have to modify much of your code or partially rewrite it. So let's split this effort as much as possible:&lt;/p&gt;

&lt;p&gt;Here's a way how you can use Aurelia side-by-side with the Knockout technology and then migrate each view and&lt;br&gt;
view-model step-by-step. You can use your old Knockout views and their backed JavaScript code with its observables&lt;br&gt;
and subscriptions, as if you were still using Durandal.&lt;/p&gt;
&lt;h2&gt;
  
  
  First Steps
&lt;/h2&gt;

&lt;p&gt;First, install the Aurelia plugin&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;jspm &lt;span class="nb"&gt;install &lt;/span&gt;aurelia-knockout
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;and register it during the startup of your app:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;configure&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;aurelia&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;aurelia&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;use&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;standardConfiguration&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;developmentLogging&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;plugin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;aurelia-knockout&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nx"&gt;aurelia&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;start&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;then&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;aurelia&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setRoot&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 next step will be, to add the &lt;code&gt;knockout&lt;/code&gt; custom attribute to each view which uses Knockout syntax:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;template&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;knockout&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;data-bind=&lt;/span&gt;&lt;span class="s"&gt;"click: changeVisibility"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Change Visibility&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;data-bind=&lt;/span&gt;&lt;span class="s"&gt;"if: isVisible"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;data-bind=&lt;/span&gt;&lt;span class="s"&gt;"text: firstName"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;br&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;data-bind=&lt;/span&gt;&lt;span class="s"&gt;"text: lastName"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/span&amp;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&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/template&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The element with the custom attribute has to wrap all code with Knockout syntax.&lt;/p&gt;

&lt;p&gt;This attribute binds the HTML to the current BindingContext of Aurelia.&lt;/p&gt;

&lt;p&gt;And that's it! With these small modifications you can use all Knockout bindings which are available.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using Compositions
&lt;/h2&gt;

&lt;p&gt;Durandal also provided a binding to compose views. Because this binding was implemented from Durandal and not&lt;br&gt;
from Knockout you can not use this feature natively. But the &lt;code&gt;aurelia-knockout&lt;/code&gt; plugin supports the composition&lt;br&gt;
with all possible variants listed in the &lt;a href="http://durandaljs.com/documentation/Using-Composition.html"&gt;official Durandal docs&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;data-bind=&lt;/span&gt;&lt;span class="s"&gt;"compose: 'path/to/view.html'"&lt;/span&gt;&lt;span class="nt"&gt;&amp;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;data-bind=&lt;/span&gt;&lt;span class="s"&gt;"compose: 'path/to/module'"&lt;/span&gt;&lt;span class="nt"&gt;&amp;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;data-bind=&lt;/span&gt;&lt;span class="s"&gt;"compose: { view: 'path/to/view.html' }"&lt;/span&gt;&lt;span class="nt"&gt;&amp;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;data-bind=&lt;/span&gt;&lt;span class="s"&gt;"compose: { model: 'path/to/module' }"&lt;/span&gt;&lt;span class="nt"&gt;&amp;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;data-bind=&lt;/span&gt;&lt;span class="s"&gt;"compose: { model: moduleInstance }"&lt;/span&gt;&lt;span class="nt"&gt;&amp;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;data-bind=&lt;/span&gt;&lt;span class="s"&gt;"compose: { view: 'path/to/view.html' model: 'path/to/module' }"&lt;/span&gt;&lt;span class="nt"&gt;&amp;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;data-bind=&lt;/span&gt;&lt;span class="s"&gt;"compose: { view: 'path/to/view.html' model: moduleInstance }"&lt;/span&gt;&lt;span class="nt"&gt;&amp;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;data-bind=&lt;/span&gt;&lt;span class="s"&gt;"compose: moduleInstance"&lt;/span&gt;&lt;span class="nt"&gt;&amp;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;data-bind=&lt;/span&gt;&lt;span class="s"&gt;"compose: moduleConstructorFunction"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Set @bindable properties
&lt;/h2&gt;

&lt;p&gt;To enhance the flexibility of your migration process, this plugin also supports the ability to set &lt;code&gt;@bindable&lt;/code&gt;&lt;br&gt;
variables in rewritten subordinated Aurelia views through the activationData. This offers the possibility to rewrite&lt;br&gt;
single views in lower hierarchies without the need to do the same with their parent views.&lt;/p&gt;
&lt;h4&gt;
  
  
  Parent Knockout based view
&lt;/h4&gt;

&lt;p&gt;Supposed that there is a parent view using Knockout technology which composes a child view like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;template&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;data-bind=&lt;/span&gt;&lt;span class="s"&gt;"compose: { model: 'path/to/submodule', activationData: data }"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/template&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The appropriate data object would looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;price&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ko&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;observable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="nx"&gt;productName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Apples&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;h4&gt;
  
  
  Child Aurelia based view
&lt;/h4&gt;

&lt;p&gt;The child view and view-model uses Aurelia:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;template&amp;gt;&lt;/span&gt;
  Product:
  &lt;span class="nt"&gt;&amp;lt;span&amp;gt;&lt;/span&gt;${productName}&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;br&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  Price:
  &lt;span class="nt"&gt;&amp;lt;span&amp;gt;&lt;/span&gt;${price}&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/template&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;





&lt;div class="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;bindable&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;aurelia-framework&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;inject&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;aurelia-dependency-injection&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;KnockoutBindable&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;aurelia-knockout&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="nd"&gt;inject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;KnockoutBindable&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;ProductView&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;bindable&lt;/span&gt;
  &lt;span class="nx"&gt;price&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;productName&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nx"&gt;knockoutBindable&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="kd"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;knockoutBindable&lt;/span&gt;&lt;span class="p"&gt;)&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;knockoutBindable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;knockoutBindable&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;activate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;activationData&lt;/span&gt;&lt;span class="p"&gt;)&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;knockoutBindable&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;applyBindableValues&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;activationData&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="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;This will set the value from &lt;code&gt;activationData.price&lt;/code&gt; to &lt;code&gt;this.price&lt;/code&gt;. &lt;code&gt;this.productName&lt;/code&gt; however, is not&lt;br&gt;
updated because it has no &lt;code&gt;@bindable&lt;/code&gt; decorator and the variable from &lt;code&gt;activationData&lt;/code&gt; is no Knockout&lt;br&gt;
observable. To process non Knockout observables anyway you have to pass &lt;code&gt;false&lt;/code&gt; as third parameter to the&lt;br&gt;
&lt;code&gt;applyBindableValues&lt;/code&gt; function. If the outer value changed (and is an observable) the corresponding inner&lt;br&gt;
variable is updated too.&lt;/p&gt;

&lt;p&gt;Subscriptions for Knockout observables which are created from this plugin internally will be disposed automatically&lt;br&gt;
if the child view is unbound.&lt;/p&gt;

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

&lt;p&gt;The migration to a new framework is often a big task depending on your application. But that does not mean that you have to implement it all at once. This plugin offers you a possibility to ship preliminary results during the transition phase of your application.&lt;/p&gt;

&lt;h1&gt;
  
  
  Found a typo?
&lt;/h1&gt;

&lt;p&gt;If you've found a typo, a sentence that could be improved or anything else that should be updated on this blog post, you can access it through a git repository and make a pull request. Instead of posting a comment, please go directly to &lt;a href="https://github.com/ckotzbauer/dev.to-posts"&gt;https://github.com/ckotzbauer/dev.to-posts&lt;/a&gt; and open a new pull request with your changes.&lt;/p&gt;

</description>
      <category>aurelia</category>
      <category>knockout</category>
      <category>durandal</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
