<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[blog.marlas.pl RSS Feed]]></title><description><![CDATA[Ogrodnik Internetu]]></description><link>https://blog.marlas.pl</link><generator>GatsbyJS</generator><lastBuildDate>Sun, 16 Jul 2023 09:28:03 GMT</lastBuildDate><item><title><![CDATA[Debugging Travis issue]]></title><description><![CDATA[This is a story that happened to me recently and I wanted to share how I approach debugging problems and what is my thought process. I found this particular issue worth describing, because as usual the most interesting problems are made of smaller problems combined together that you might have never discover otherwise. Enjoy the journey.]]></description><link>https://blog.marlas.pl/debugging-travis-issue/</link><guid isPermaLink="false">https://blog.marlas.pl/debugging-travis-issue/</guid><pubDate>Sun, 10 May 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;This is a story that happened to me recently and I wanted to share how I approach debugging problems and what is my thought process. I found this particular issue worth describing, because as usual the most interesting problems are made of smaller problems combined together that you might have never discover otherwise. Enjoy the journey.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;Before I go to the real issue let me shortly describe the project background. More than 20 people regularly commit code to the project. To maintain quality of the code we require that each PR passes all required checks. In our case all unit tests have to pass, critical e2e tests are passing and linter doesn&apos;t catch any errors. Additionally we commit to 2 main branches. One branch for stable version maintenance and the other for next version development. Recently we worked on major release, so we have a lot of differences between those branches that will play a role in this story.&lt;/p&gt;
&lt;p&gt;The story starts with this image
&lt;img src=&quot;/debugging-travis-issue/commits.JPG&quot; alt=&quot;Failing Travis job for latest commit&quot;&gt;&lt;/p&gt;
&lt;p&gt;Suddenly Travis job failed for the change that shouldn&apos;t break anything. It was only the library version bump in maintenance branch. Everything should be okay.&lt;/p&gt;
&lt;p&gt;Let&apos;s see what failed in this job.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;✓ Linter passed&lt;/li&gt;
&lt;li&gt;✓ Prettier passed&lt;/li&gt;
&lt;li&gt;✓ Unit tests for core library passed&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Aha. Unit tests for storefront library failed.&lt;/p&gt;
&lt;p&gt;Let&apos;s look at the details
&lt;img src=&quot;/debugging-travis-issue/unit-tests.JPG&quot; alt=&quot;Failing unit test in storefront library&quot;&gt;&lt;/p&gt;
&lt;p&gt;Ok. Only one unit test failing. I&apos;ll just checkout to this branch and run the tests locally.&lt;/p&gt;
&lt;p&gt;Few moments later... What! All tests green. Not a single failure! Wtf&lt;/p&gt;
&lt;p&gt;Let me just check the changes in the last commit once again. Maybe I messed up the last commit.&lt;/p&gt;
&lt;p&gt;Hmmm. It looks alright. Maybe that was random Travis failure. Maybe job restart will solve this.&lt;/p&gt;
&lt;p&gt;Few minutes passed by. Travis failed once again. The same test failed. I&apos;m getting closer. Now I know that this is something with the Travis environment. Let me check if that also fails on the development branch.&lt;/p&gt;
&lt;p&gt;Weird. It works there. The test and the the function haven&apos;t changed between the branches. So definitely it&apos;s not the issue with the code.&lt;/p&gt;
&lt;p&gt;Why only this one particular test failed? Not the others if that&apos;s the issue with environment. What makes it so special? Let&apos;s inspect that code.&lt;/p&gt;
&lt;p&gt;Let&apos;s start with the failing test&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;ts&quot;&gt;&lt;pre class=&quot;language-ts&quot;&gt;&lt;code class=&quot;language-ts&quot;&gt;&lt;span class=&quot;token function&quot;&gt;describe&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;when unknown titles are added&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;they should be put at the end&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; mockTitles&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Title&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        code&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;dr&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        name&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Dr.&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        code&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;mrs&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        name&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Mrs.&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        code&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;rev&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        name&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Rev.&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        code&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;unknown&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        name&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Unknown&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        code&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;mr&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        name&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Mr.&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; expectedTitles&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Title&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        code&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;mr&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        name&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Mr.&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        code&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;mrs&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        name&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Mrs.&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        code&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;dr&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        name&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Dr.&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        code&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;rev&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        name&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Rev.&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        code&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;unknown&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        name&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Unknown&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; sortedTitles &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; mockTitles&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;sort&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;sortTitles&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token function&quot;&gt;expect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;sortedTitles&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toEqual&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;expectedTitles&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Nothing complicated. Only some sorting. Let&apos;s look at the sorting function.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;ts&quot;&gt;&lt;pre class=&quot;language-ts&quot;&gt;&lt;code class=&quot;language-ts&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; Title &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@spartacus/core&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; titleScores &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  mr&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  mrs&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  miss&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  ms&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  dr&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  rev&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;sortTitles&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;title1&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Title&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; title2&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Title&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;titleScores&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;title1&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;code&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;titleScores&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;title2&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;code&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; titleScores&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;title1&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;code&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; titleScores&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;title2&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;code&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Okay. It only returns integers in that setup. A lot of 1 in this test case. And the failure stated different expected order that the actual one.&lt;/p&gt;
&lt;p&gt;Aha!!! Sort doesn&apos;t guarantee order preservation! That must have been the issue in this case! But why it changed the order only in this job? Why is it always passing?&lt;/p&gt;
&lt;p&gt;Gotcha! I remember that some time ago they changed the sort function implementation in V8. That must be it.&lt;/p&gt;
&lt;p&gt;Let&apos;s look at what exactly we use on Travis. We are running Node.js 10 on maintenance branch, but Node.js 12 on develop branch.&lt;/p&gt;
&lt;p&gt;Let&apos;s check when the V8 update got into the Node.js. Version 11. Bingo. That must be it. Let&apos;s confirm it. Change version of Node.js locally to 10 and rerun unit tests. Maybe then I would see the issue locally.&lt;/p&gt;
&lt;p&gt;What?! Green again. How is it possible?&lt;/p&gt;
&lt;p&gt;I&apos;m stupid! Unit test are run with Chrome not the Node :facepalm:&lt;/p&gt;
&lt;p&gt;Weird. I don&apos;t see any differences in Chrome setup on Travis between maintenance and development branch. Time to check the Travis logs for the chrome setup.
&lt;img src=&quot;/debugging-travis-issue/chrome-install-failure.JPG&quot; alt=&quot;Chrome install failure on Travis&quot;&gt;&lt;/p&gt;
&lt;p&gt;I&apos;m onto something. Installation of the stable chrome failed in the job. Let&apos;s see how it worked previously.
&lt;img src=&quot;/debugging-travis-issue/chrome-install-success.JPG&quot; alt=&quot;Chrome install success on Travis&quot;&gt;&lt;/p&gt;
&lt;p&gt;Ok. In the previous job Chrome 81 was successfully installed and replaced default Chrome 62. When the V8 change got into Chrome? Let&apos;s google.&lt;/p&gt;
&lt;p&gt;Chrome 70 landed the fix for sort function. That explains why the test failed in this particular job.&lt;/p&gt;
&lt;p&gt;Why on development branch Chrome is installed successfully and why it fails on maintenance branch?&lt;/p&gt;
&lt;p&gt;Oh yeah! We changed the OS distribution from trusty to bionic! Let&apos;s check if someone also had this problem with Chrome on trusty distro.&lt;/p&gt;
&lt;p&gt;Perfect! &lt;a href=&quot;https://travis-ci.community/t/travis-is-downloading-older-chrome-versions-in-place-of-chrome-stable/5040/2&quot;&gt;https://travis-ci.community/t/travis-is-downloading-older-chrome-versions-in-place-of-chrome-stable/5040/2&lt;/a&gt; Exactly the same issue. But why it happened to us half a year later than for these folks?&lt;/p&gt;
&lt;p&gt;I guess maybe Chrome team prolonged trusty distribution support to increase the transition period. I don&apos;t have time to dive into what changed in this deb packages over last 2 weeks. I found the issue, fix is easy. Let&apos;s just bump the distribution to match the one from development branch and we are green once again. Let&apos;s go to the next topic.&lt;/p&gt;
&lt;p&gt;Ah. Almost forgot. Let&apos;s create a ticket to improve the title util function to work correctly in non deterministic environment as well.&lt;/p&gt;
&lt;p&gt;Thanks for reading the story. Hope that&apos;s been journey full of surprises for you as well. I&apos;ve felt great once I figured out the underlying cause of this problem. That&apos;s what makes my job satisfying and that&apos;s why I love being a programmer.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Post nr 20]]></title><description><![CDATA[Od rozpoczęcia akcji "Daj się poznać 2017" minęło już sporo czasu i w końcu udaje mi się wykonać cel postawiony przed każdym z uczestników. Udało mi się napisać 20 postów (ten post jest postem nr 20) i rozwijać mały projekt Open Source przez 2,5 miesiąca. Oto parę rzeczy, których się nauczyłem przez ten okres oraz plany na przyszłość.]]></description><link>https://blog.marlas.pl/post-20/</link><guid isPermaLink="false">https://blog.marlas.pl/post-20/</guid><pubDate>Fri, 16 Jun 2017 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Od rozpoczęcia akcji &quot;Daj się poznać 2017&quot; minęło już sporo czasu i w końcu udaje mi się wykonać cel postawiony przed każdym z uczestników. Udało mi się napisać 20 postów (ten post jest postem nr 20) i rozwijać mały projekt Open Source przez 2,5 miesiąca. Oto parę rzeczy, których się nauczyłem przez ten okres oraz plany na przyszłość.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;Blogowanie nie zajmuje jednak tak dużo czasu jak myślałem, ale nie jest to aż takie proste. Pisanie sprawiło mi trochę przyjemnośći, ale skala, której wymagał konkurs &quot;Daj się poznać&quot; była zdecydowanie za duża. Pisanie 2 postów tygodniowo to było ciągłe szukanie wolnego czasu na napisanie kolejnego posta i popracowanie nad projektem. Po tym maratonie blogowania mam zamiar zrobić sobie dłuższą przerwę od tego. Zamiast pisać krótkie lub średniej długości teksty wolałbym badać konkretne zagadnienie przez dłuższy okres i tworzyć obszerny, i bardzo treściwy materiał. O niektórych elementach nie da się pisać dłuższych wypowiedzi, bo są tak proste i łatwe do wytłumaczenia, ale takie materiały do mnie nie przemawiają. Wolę przeczytać &quot;kawał&quot; dobrych badań i wyciągniętych z nich wniosków z pomysłami na ich wykorzystanie, niż dostać bardzo krótki wstęp do jakiegoś zagadanienia, który i tak mogę znaleźć w dokumentacji, czy mnóstwie innych artykułów na jego temat. Myślę, że w przyszłości pójdę raczej w dłuższe formy, które wnoszą coś nowego do środowiska, a nie są jednym z kilkunastu artykułów mówiących o tym samym. Tutaj bardzo doceniam wkład od &lt;a href=&quot;https://medium.com/@addyosmani&quot;&gt;Addy Osmani&lt;/a&gt;, który przy swoich materiałach bardzo dogłębnie bada temat i daje kompletny poradnik wyjaśniający najlepsze praktyki i możliwe rozwiązania badanych problemów.&lt;/p&gt;
&lt;p&gt;Projekt, który wybrałem sobie do konkursu jest bardzo ambitny i zakres jego funkcjonalności ma być ogromny, skrojony pod moje potrzeby. Jednak już na samym początku wiedziałem, że nie jest on do wykonania w okresie konkursu. Planowałem pracować nad nim powoli i dokładnie przemyśleć jak wszystko w nim rozwiążę. Z tego powodu, większość mojej pracy z projektem to było szukanie rozwiązań pod tą aplikację i ich integracja w istniejący zalążek. Nadal mam kilka pomysłów na duże zmiany przed przejściem w prawdziwą część projektu - tworzenie funkcjonalności.&lt;/p&gt;
&lt;p&gt;Pakiet startowy, który wybrałem na start trochę mnie zawiódł i będzie raczej zmieniony na &lt;a href=&quot;https://github.com/zeit/next.js/&quot;&gt;next.js&lt;/a&gt;, ale dużo rzeczy, które poznałem z React Go mam zamiar dalej wykorzystać (np. stylowanie modułami i korzystanie z cssnext). Na pewno dalej będę korzystał z Redux, ale może w ramach nauki nowego rodzaju API zbadam Graph QL, zamiast klasycznego REST API. Jedną rzeczą, którą muszę teraz wykonać, jest stworzenie kompletnego backlogu, żeby potem w czasie prac nie zbaczać z obranego kursu.&lt;/p&gt;
&lt;p&gt;W czasie trwania konkursu pracowałem również nad kilkoma innymi aplikacjami korzystającymi z React, Redux i wiele się w tym czasie nauczyłem. Tę wiedzę zdobytą w innych projektach, chcę również wykorzystać przy rozwoju projektu i poprawie niektórych części kodu.&lt;/p&gt;
&lt;p&gt;To teraz trochę o mnie. Nie pisałem jeszcze na blogu kim jestem, czym się dokładnie zajmuję, więc pora na parę wyjaśnień. Aktualnie jestem studentem informatyki na Politechnice Wrocławskiej na Wydziale Informatyki i Zarządzania. W czasie akcji &quot;Daj się poznać 2017&quot; jestem na 6 semestrze studiów i zbliżam się dużymi krokami do obrony pracy inżynierskiej. Poza tym pracuję na 1/2 etatu w świetnej firmie &lt;a href=&quot;https://divante.co&quot;&gt;Divante&lt;/a&gt;, jako Frontend Developer.&lt;/p&gt;
&lt;p&gt;Aktualny stan studenta/pracownika jest bardzo wymagający (trochę trzeba się napracować na tym 6 semestrze) i wiedziałem, że udział w &quot;Daj się poznać&quot; zajmie resztki mojego wolnego czasu, ale teraz na finiszu jestem zadowolony z tego, że wziąłem w nim udział. Konkurs zmotywował mnie do startu przygody z blogowaniem, do którego mam nadzieję niedługo wrócić. Dodatkowo udowodniłem sobie, że da się pracować, studiować i blogować w tym samym czasie, ale nie polecam tego nikomu. Taki ogrom kontaktu z programowaniem prowadzi do szybkiego wypalenia i tutaj narazie chcę wypocząć przynajmniej z programowaniem do blogowania. Zachęcam każdego do wypróbowania swoich sił w pisaniu bloga, bo może przypadnie to wam do gustu. Ja z chęcią wrócę do tego, jeśli zmniejszę swoje obłożenie innymi sprawami. Do usłyszenia jak najszybciej. :)&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Prettier]]></title><description><![CDATA[Jednym z problemów w środowisku Javascript jest formatowanie kodu. Istnieje masę udokumentowanych koncepcji z udokomentowanymi wszystkimi zasadami, według których się powinno formatować kod. Najpopularniejsze wzorce to AirBnB style guide, Standard.js, XO i niedawno stworzony Prettier.]]></description><link>https://blog.marlas.pl/prettier/</link><guid isPermaLink="false">https://blog.marlas.pl/prettier/</guid><pubDate>Fri, 12 May 2017 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Jednym z problemów w środowisku Javascript jest formatowanie kodu. Istnieje masę udokumentowanych koncepcji z udokomentowanymi wszystkimi zasadami, według których się powinno formatować kod. Najpopularniejsze wzorce to AirBnB style guide, Standard.js, XO i niedawno stworzony Prettier.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;Dotychczas próbowałem korzystać z wzorców AirBnb oraz Standard.js. Jednak dopiero Prettier spełnił wszystkie moje wymagania. Wiele z tych standardów jest odpowiedzialnych nie tylko za styl kodu, ale również za elementy dotyczące dostępności, reguły niezwiązane z stylem kodu, a użyciem nowszych funkcjonalności JS.&lt;/p&gt;
&lt;p&gt;Prettier różni się od nich tym, że nie jest to linter. Prettier na wejście dostaje nasz kod i na wyjściu zwraca sformatowany kod. Tutaj właśnie jest zaleta tego formattera. Jeśli wywołujemy funkcję z 4 krótkimi parametrami i będzie ona się mieściła w 80 znakach to nadal będzie ona tak zapisana. Jeśli jednak nie zmieści się ta funkcja w limicie znaków w linii, to każdy argument zostanie zapisany w osobnej linii. Dzięki temu dostajemy kod, który zawsze mieści się w naszym limicie znaków.&lt;/p&gt;
&lt;p&gt;Konfiguracja Prettier jest bardzo uboga i to jest właśnie bardzo dobre rozwiązanie, bo nie wprowadza dużego rozłamu. Możemy tylko ustawić rozmiar wcięcia, rodzaj &apos;trailing comma&apos;, rodzaje apostrofów, odstępy w obiektach i użycie średników. Reszta jest poza naszą kontrolą.&lt;/p&gt;
&lt;p&gt;Ja korzystam z tego rozszerzenia w edytorze Visual Studio Code - Prettier - Javascript formatter i działa to bardzo sprawnie. Jeśli chcę sformatować plik to tylko korzystam z skrótu &lt;code class=&quot;language-text&quot;&gt;Ctrl + Shift + i&lt;/code&gt; i dokument jest poprawnie sformatowany. Konfigurację formatera ustawiam w konfiguracji edytora i to wszystko. Już nie muszę patrzeć do konsoli lintera i sprawdzać co muszę poprawić. Teraz formatowanie kodu przypomina korzystanie z takich narzędzi jak formater do Javy w edytorze IntelliJ. Plusem Prettier jest również to, że wspiera JSX oraz funkcjonalności ES2017.&lt;/p&gt;
&lt;p&gt;W przypadku, gdy potrzebujemy jeszcze sprawdzania rzeczy poza formatowaniem możemy skorzystać z pluginu do eslint: &lt;code class=&quot;language-text&quot;&gt;eslint-config-prettier&lt;/code&gt;, który wyłączy wszystkie reguły eslint, które mogą konfliktować z Prettier, a pozwoli na lintowanie zasad, które nie są obsługiwane przez Prettier.&lt;/p&gt;
&lt;p&gt;Polecam wszystkim sprawdzenie &lt;a href=&quot;https://github.com/prettier/prettier&quot;&gt;Prettier&lt;/a&gt; i przestanie się martwić o formatowanie kodu i wybieranie miliona reguł do lintowania. Ja już wybrałem Prettier w połączeniu z ESlint i przestałem się martwić.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[ReDucks]]></title><description><![CDATA[Zagłębiłem się ostatnio bardzo w tematykę Redux. Podczas czytania różnych artykułów natrafiłem na rodzaj architektury Redux nazwany Ducks. Cała idea Ducks wygląda bardzo prosto i pozwala trzymać powiązane elementy razem, zamiast dzielić części Redux zależnie do typu (akcje, reduktory, typy). Postanowiłem ją wytestować w projekcie.]]></description><link>https://blog.marlas.pl/reducks/</link><guid isPermaLink="false">https://blog.marlas.pl/reducks/</guid><pubDate>Mon, 08 May 2017 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Zagłębiłem się ostatnio bardzo w tematykę Redux. Podczas czytania różnych artykułów natrafiłem na rodzaj architektury Redux nazwany Ducks. Cała idea Ducks wygląda bardzo prosto i pozwala trzymać powiązane elementy razem, zamiast dzielić części Redux zależnie do typu (akcje, reduktory, typy). Postanowiłem ją wytestować w projekcie.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;Cała idea &lt;a href=&quot;https://github.com/erikras/ducks-modular-redux&quot;&gt;Ducks&lt;/a&gt; opiera się na trzymaniu reduktora razem z jego typami i kreatorami akcji w jednym pliku. Dzięki czemu unikamy wielu eksportów/importów i powiązane funkjonalności edytujemy w jednym miesjcu.&lt;/p&gt;
&lt;p&gt;Mamy jednak parę zasad:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;reduktor musi być eksportowany domyślnie&lt;/li&gt;
&lt;li&gt;każda akcja musi być eksportowana&lt;/li&gt;
&lt;li&gt;typy są zdefiniowane w tym samym pliku i mogą być eksportowane, jeśli są potrzebne w innych reduktorach&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Z tymi zasadami przerobiłem swoje wszystkie reduktory w projekcie. Całość zajęła kilka minut i zaoszczędziłem kilka eksportów, zmniejszyłem liczbę plików oraz wszystkie funkcjonalności związane z reduktorem mogę szybciej edytować. Poniżej przykład reduktora zadań przerobiony na Ducks.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;ADD_TASK&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;ADD_TASK&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;REMOVE_TASK&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;REMOVE_TASK&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;taskReducer&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;state &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; action&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;switch&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;action&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;type&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;ADD_TASK&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;action&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;payload&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;state&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;REMOVE_TASK&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; state&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;filter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;element&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; element&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name &lt;span class=&quot;token operator&quot;&gt;!==&lt;/span&gt; action&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;payload&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; state&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt; taskReducer&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;addTask&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;task&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;ADD_TASK&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;payload&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; task&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;removeTask&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;task&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;REMOVE_TASK&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;payload&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; task&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;W przypadku potrzeby zmienienia akcji możemy zmienić reduktor i kreator akcji w jednym miejscu, bez potrzeby wyszukiwania odpowiednich plików. Do tego nie muszę już nigdzie eksportować typów i nie mam jednego folderu, który był tylko od trzymania pliku z listą typów. W przypadku większych reduktorów importowanie po każdym typie było straszne, a import grupowy dodawał dodatkowej składni. Dzięki tej architekturze zarządzanie Redux jest jeszcze prostsze.&lt;/p&gt;
&lt;p&gt;Bardzo polecem ją przetestować i zobaczyć jak sprawdzi się w waszych projektach. Jeśli pliki staną się bardzo obszerne będzie to sygnał, że może reduktor ma za dużo odpowiedzialności i należy go odpowiednio rozbić na mniejsze składowe reduktory. Miłej zabawy z kaczuszkami.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Visual Studio Code]]></title><description><![CDATA[W tym poście chcę coś opowiedzieć o swoim podstawowym edytorze - Visual Studio Code. Jest to nowy edytor stworzony przez Microsoft w 2015 roku i od oficjalnego wypuszczenia edytora w marcu 2016 rozwijany jako projekt Open Source. Ja zacząłem korzystać z VS Code 1,5 roku temu, gdy jeszcze był w wersji Beta i jeszcze nie znalazłem powodu, żeby go zamienić na jakikolwiek inny.]]></description><link>https://blog.marlas.pl/visual-studio-code/</link><guid isPermaLink="false">https://blog.marlas.pl/visual-studio-code/</guid><pubDate>Thu, 04 May 2017 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;W tym poście chcę coś opowiedzieć o swoim podstawowym edytorze - Visual Studio Code. Jest to nowy edytor stworzony przez Microsoft w 2015 roku i od oficjalnego wypuszczenia edytora w marcu 2016 rozwijany jako projekt Open Source. Ja zacząłem korzystać z VS Code 1,5 roku temu, gdy jeszcze był w wersji Beta i jeszcze nie znalazłem powodu, żeby go zamienić na jakikolwiek inny.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;Edytor ten jest bardzo lekki. Jest oparty na silniku Electron, na którym można tworzyć aplikacje desktopowe korzystające z Node.js i silnika Blink. Na tym samym silniku działa również inny popularny edytor - Atom. Od pierwszego publicznego wypuszczenia VS Code jest on regularnie, co miesiąc aktualizowany o masę nowych funkcjonalności i z miesiąca na miesiąc coraz bardziej dojrzeje.&lt;/p&gt;
&lt;p&gt;Za co lubię VS Code:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;bardzo schludny i prosty interfejs&lt;/li&gt;
&lt;li&gt;dobry system rozszerzeń&lt;/li&gt;
&lt;li&gt;dobre wsparcie dla Javascript&lt;/li&gt;
&lt;li&gt;wbudowany Debugger JS&lt;/li&gt;
&lt;li&gt;świetna integracja z GIT&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Oprócz wyżej wymienionych zalet bardzo dobrze działa dzielenie edytora na wiele grup zakładek, wbudowany Emmet, łatwość konfiguracji i paletę komend. Te rzeczy są wykorzystywane wielokrotnie każdego dnia i działają bez zarzutu, i bardzo ułatwiają pracę. Przez to, że edytor jest pisany w JS mogę w przyszłości wesprzeć jego rozwój, czy stworzyć potrzebny plugin. A co do pluginów - to naprawdę ciężko wpaść na pomysł pluginu, bo społeczność tworzy je bardzo szybko i większosć z nich jest bardzo dobrej jakości. Jeśli wchodzi jakaś nowa biblioteka czy framework to Visual Studio Code ma wcześnie dostępny plugin jako jeden z niewielu edytorów.&lt;/p&gt;
&lt;p&gt;A jeśli mowa o pluginach to mogę wspomnieć kilka, które są warte uwagi i mi się bardzo przydały:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;pluginy do wsparcia języków: PostCSS syntax, Docker, Handlebars&lt;/li&gt;
&lt;li&gt;Settings Sync - mój plugin no. 1 - to dzięki niemu wszystkie moje urządzenia zawsze mają te same wersje rozszerzeń i ustawienia są przenoszone między edytorami. Dzięki niemu instalacja edytora z wszystkimi ustawieniami i rozszerzeniami zajmuje tylko 5 minut.&lt;/li&gt;
&lt;li&gt;markdownlint&lt;/li&gt;
&lt;li&gt;vscode-icons - ikony dla różnych plików pozwalają naprawdę sprawnie poruszać się w drzewie katalogów&lt;/li&gt;
&lt;li&gt;SVG Viewer&lt;/li&gt;
&lt;li&gt;Path Intellisense - importy wszystkich plików są dzięki niemu banalne&lt;/li&gt;
&lt;li&gt;Prettier - Javascript formatter&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Chcę jeszcze wspomnieć o powodzie, dla którego naprawdę polubiłem ten edytor - integracja z GIT. Dzięki temu byłem w stanie wyrobić w sobie praktykę częstych commitów, pracowania na osobnych branchach dla zadań oraz bardzo prosto synchronizowałem wszystko z centralnymi serwerami. Jedynej rzeczy, której mi tutaj brakuje to dobry mechanizm obsługi konfliktów, ale do ręcznej pracy na konfliktach da się przyzwyczaić. W końcu nie ma ich tak dużo.&lt;/p&gt;
&lt;p&gt;Ja z mojej stronę chcę bardzo polecić Visual Studio Code. Jeśli piszecie dużo Javascriptu i frontendowych rzeczy to jest to edytor stworzony pod te potrzeby. Dodatkowo polecem wspominaną integrację z GIT oraz mnóstwo dobrej jakości pluginów do najróżniejszych potrzeb.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[CSSnext w projekcie]]></title><description><![CDATA[Przy tworzeniu projektów z użyciem React odchodzi się od praktyki tworzenia jednego głównego arkusza styli na rzecz tworzenia styli indywidualnie dla każdego komponentu. Jak już opisałem w poprzednim poście o projekcie, że korzystam w nim z modułów CSS i nie korzystam z SCSS. Dzisiaj opiszę trochę cssnext, który usprawnia pracę z stylami w modułach i daje możliwość wykorzystania przyszłych funkcjonalności języka CSS.]]></description><link>https://blog.marlas.pl/cssnext-w-projekcie/</link><guid isPermaLink="false">https://blog.marlas.pl/cssnext-w-projekcie/</guid><pubDate>Sun, 30 Apr 2017 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Przy tworzeniu projektów z użyciem React odchodzi się od praktyki tworzenia jednego głównego arkusza styli na rzecz tworzenia styli indywidualnie dla każdego komponentu. Jak już opisałem w poprzednim poście o projekcie, że korzystam w nim z modułów CSS i nie korzystam z SCSS. Dzisiaj opiszę trochę cssnext, który usprawnia pracę z stylami w modułach i daje możliwość wykorzystania przyszłych funkcjonalności języka CSS.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;Od kilku lat korzystam z SCSS i stał się on jednym z moich podstawowych narzędzi do pisania styli, ale zawsze z chęcią poznaję nowości. Już jakiś czas temu usłyszałem o postcss i bardzo szybko w mój workflow wprowadziłem świetne narzędzie - autoprefixer. Nie wgłębiałem się natomiast w resztę możliwości jakie oferuje ekosystem. Teraz mam świetną okazję je poznać pisząc tę aplikację w React i mając już skonfigurowany projekt do obsługi cssnext i importów.&lt;/p&gt;
&lt;p&gt;Głównymi funkcjonalnościami jakie używam w SCSS są zmienne, mixiny, importy oraz świetny nesting. Te funkcjonalności najbardziej usprawniają pracę i ciężko będzie mi bez nich pisać style. Po szybkim przejrzeniu dokumentacji cssnext okazuje się, że wszystko to mogę wykonać.&lt;/p&gt;
&lt;p&gt;Na początku import. Tutaj składnia jest identyczna jak w przypadku SCSS i obsługiwana jest przez plugin &lt;code class=&quot;language-text&quot;&gt;postcss-import&lt;/code&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;css&quot;&gt;&lt;pre class=&quot;language-css&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;@import &lt;span class=&quot;token string&quot;&gt;&quot;settings.css&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Następnie zmienne. Tutaj następuje spora zmiana, bo użycie zmiennych wymaga zmiany podejścia na nowe, które wprowadzone jest powoli do przeglądarek. Zmiennych w CSS. Zmienne definiujemy w elemencie &lt;code class=&quot;language-text&quot;&gt;:root&lt;/code&gt; i odwołujemy się do nich poprzez funkcję &lt;code class=&quot;language-text&quot;&gt;var()&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;css&quot;&gt;&lt;pre class=&quot;language-css&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;:root&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;--gray&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; #ddd&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token selector&quot;&gt;.button&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;border-color&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--gray&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Kolej na mixiny. Tutaj znowu są zauważalne różnice, ale jeśli potrafimy korzystać z zmiennych CSS to mixiny również nie powinny sprawiać problemów.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;css&quot;&gt;&lt;pre class=&quot;language-css&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;:root&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token selector&quot;&gt;--box:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token property&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 64px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token property&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 64px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;


&lt;span class=&quot;token selector&quot;&gt;.box&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;background-color&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; goldenrod&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token atrule&quot;&gt;&lt;span class=&quot;token rule&quot;&gt;@apply&lt;/span&gt; --box&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Na koniec zostaje mój ulubiony nesting. Tutaj znacznie przyjemniej pracowało mi się z SCSS, ale można przywyknąć. Nesting media query zostaje taki sam. Prosty nesting również, jedynie w przypadku nestingu odwrotnego trzeba korzystać z dyrektywy @nest.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;css&quot;&gt;&lt;pre class=&quot;language-css&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;.box&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token selector&quot;&gt;&amp;amp; span&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token property&quot;&gt;font-size&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 1.2em&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token atrule&quot;&gt;&lt;span class=&quot;token rule&quot;&gt;@nest&lt;/span&gt; .container &amp;amp;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token property&quot;&gt;max-width&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 34em&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token atrule&quot;&gt;&lt;span class=&quot;token rule&quot;&gt;@media&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;max-width&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 30px&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token property&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 200px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Cssnext oferuje poza przedstawionymi wyżej funkcjonalnościami jeszcze parę innych smaczków: proste tworzenie customowych media queries, mnóstwo funkcji kolorów, wsparcie dla rem, wbudowany autoprefixer, korzystanie z pseudoklas i funkcje do resetu właściwości. Więcej możecie znaleźć w &lt;a href=&quot;http://cssnext.io/features/&quot;&gt;dokumentacji cssnext&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Praca z cssnext w projekcie bardzo ułatwia pisanie styli i raczej zmienię swój sposób pisania z SCSS na rozszerzalnego postcssa i na korzystanie z przyszłych funkcjonalności CSS, zamiast korzystać z specjalnej składni preprocesora.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Create React App]]></title><description><![CDATA[Od początku mojej podróży z React obijał się temat wymaganego środowiska, narzędzi budowania i całej konfiguracji wymaganej do odpalenia projektu korzystającego z nowych funkcjonalności ES6. Na szczęście bardzo szybko trafiłem na projekt Create React App, który pozwolił uniknąć mi mnóstwo problemów związanych z podstawową konfiguracją Webpack, Babel przydatnych przy pracy z React.]]></description><link>https://blog.marlas.pl/create-react-app/</link><guid isPermaLink="false">https://blog.marlas.pl/create-react-app/</guid><pubDate>Wed, 26 Apr 2017 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Od początku mojej podróży z React obijał się temat wymaganego środowiska, narzędzi budowania i całej konfiguracji wymaganej do odpalenia projektu korzystającego z nowych funkcjonalności ES6. Na szczęście bardzo szybko trafiłem na projekt Create React App, który pozwolił uniknąć mi mnóstwo problemów związanych z podstawową konfiguracją Webpack, Babel przydatnych przy pracy z React.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/facebookincubator/create-react-app&quot;&gt;Create React App&lt;/a&gt; jest bardzo proste w użyciu, a instalacja wymaga tylko zainstalowania globalnego pakietu.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sh&quot;&gt;&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;token function&quot;&gt;yarn&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; create-react-app &lt;span class=&quot;token parameter variable&quot;&gt;-g&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Do utworzenia nowego projektu wystarczy tylko uruchomić jedną komendę i mamy postawiony nowy projekt z podstawowymi komponentami.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sh&quot;&gt;&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;create-react-app my-app&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Odpalenie projektu to też jedna linijka, podobnie jak uruchomienie testów opartych na Jest oraz zbudowanie projektu na produkcję. Przy odpaleniu projektu stronę możemy podejrzeć pod podanym adresem przez Create React App.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sh&quot;&gt;&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Dev&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;yarn&lt;/span&gt; start

&lt;span class=&quot;token comment&quot;&gt;# Test&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;yarn&lt;/span&gt; &lt;span class=&quot;token builtin class-name&quot;&gt;test&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Build&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;yarn&lt;/span&gt; build&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Dla mnie ten projekt bardzo ułatwił start z Reactem i gorąco go polecam. Mimo, że zaczynam się rozglądać za nowymi pakietami startowymi, które oferują renderowania po stronie serwera oraz hot module replacement (obiecująco wygląda &lt;a href=&quot;https://github.com/zeit/next.js&quot;&gt;next.js&lt;/a&gt;), to Create React App sprawdza się bardzo dobrze przy prostych projektach, które musimy szybko stworzyć i chcemy uniknąć problemów związanych ze środowiskiem. Jeśli potrzebujemy roszerzać naszą konfigurację, to mamy dostępną dobrą &lt;a href=&quot;https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md&quot;&gt;dokumentację&lt;/a&gt;, która podpowie jak np. podpiąć style pisane z SASS lub deployować na popularne platformy. Jeśli jeszcze nie poznaliście Reacta i chcecie szybko zacząć z nim pracę to Create React App zdecydowanie wam to ułatwi.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Style w projekcie]]></title><description><![CDATA[Wszystkie moje prace do tej pory skupiały się na pisaniu kodu javascript. Dzisiaj trochę odskoczni - stylowanie komponentów z użyciem modułów CSS.]]></description><link>https://blog.marlas.pl/style-w-projekcie/</link><guid isPermaLink="false">https://blog.marlas.pl/style-w-projekcie/</guid><pubDate>Tue, 25 Apr 2017 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Wszystkie moje prace do tej pory skupiały się na pisaniu kodu javascript. Dzisiaj trochę odskoczni - stylowanie komponentów z użyciem modułów CSS.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;Pakiet startowy na którym oparłem projekt ma wbudowane wsparcie dla modułów css i zobaczmy jak w tym się pisze style.
Na start zabieram się za pisanie styli dla formularza dodawania zadania. Mamy na nim dwa pola tekstowe z opisami oraz przycisk.
Zacznijmy od napisania prostych styli dla tych elementów. Korzystam z zwykłej składni CSS i nie wykorzystuję tutaj żadnych zaawansowanych opcji. Dostępny jest tu postCSS, ale narazie skupmy się na połączeniu styli z komponentem React.
Tworzę sobie plik o nazwie komponentu przy pliku komponentu, przez co nie muszę długo szukać plików podczas pracy nad jednym komponentem. Wszystkie pliki z nim związane są w jednym miejscu.&lt;/p&gt;
&lt;p&gt;Styluję podstawowe komponenty:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;css&quot;&gt;&lt;pre class=&quot;language-css&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;.label&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;font-family&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; sans-serif&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;margin-bottom&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 4px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;display&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; inline-block&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token selector&quot;&gt;.input&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 32px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;line-height&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 28px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;padding&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 0 8px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;border&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 1px solid #333&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;font-family&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; sans-serif&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token selector&quot;&gt;.button&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 32px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;line-height&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 28px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;padding&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 0 20px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;font-size&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 1.2em&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;border&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 2px solid #333&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;font-family&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; sans-serif&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;background-color&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; white&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;transition&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; border-color 0.2s ease-in-out&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;cursor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; pointer&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token selector&quot;&gt;.button:hover&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;border-color&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; royalblue&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Teraz pora na połączeniu styli z komponentem. Tutaj wykorzystujemy bibliotekę &lt;code class=&quot;language-text&quot;&gt;classnames&lt;/code&gt;. Zaczynam od importu tej biblioteki i importu styli.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; classNames &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;classnames/bind&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; styles &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./new-todo.css&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Potem łączymy nasze klasy z styli z komponentem.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; cx &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;classNames&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;bind&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;styles&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Na końcu użycie styli jest banalnie proste. Przy elemencie dodajemy tylko atrybut &lt;code class=&quot;language-text&quot;&gt;className&lt;/code&gt; z naszą połączoną klasą.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;label className&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;cx&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;label&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; htmlFor&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;Zadanie&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;label&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;br &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Użycie modułów CSS z biblioteką classnames jest banalnie proste i problem z globalnymi stylami zostaje rozwiązany. Teraz możemy pisać wyizolowane style dla każdego komponentu i nie martwić się ich wpływem na resztę dokumentu.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Plan na mój stos technologiczny]]></title><description><![CDATA[Chyba każdy, kto ma jakikolwiek kontakt z javascript wie jak dynamiczny jest ekosystem zgromadzony wokół tego języka. Codziennie wychodzi nowy frameworka, mnóstwo bibliotek, dobre praktyki też cały czas ewoluują i bardzo ciężko być z tym wszystkim na bieżąco. Zawsze chcę nauczyć się czegoś nowego, przyjrzeć się innemu frameworkowi i napisać probjekt z użyciem czegoś nowego. Problemem jest ilość nowości, którymi jesteśmy bomboradowani. Jakiś czas temu postanowiłem się zdecydować, w którym kierunku zamierzam iść i ustaliłem sobie swój stos technologiczny, którego chcę dogłebnie poznać.]]></description><link>https://blog.marlas.pl/plan-na-moj-stos-technologiczny/</link><guid isPermaLink="false">https://blog.marlas.pl/plan-na-moj-stos-technologiczny/</guid><pubDate>Tue, 11 Apr 2017 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Chyba każdy, kto ma jakikolwiek kontakt z javascript wie jak dynamiczny jest ekosystem zgromadzony wokół tego języka. Codziennie wychodzi nowy frameworka, mnóstwo bibliotek, dobre praktyki też cały czas ewoluują i bardzo ciężko być z tym wszystkim na bieżąco. Zawsze chcę nauczyć się czegoś nowego, przyjrzeć się innemu frameworkowi i napisać probjekt z użyciem czegoś nowego. Problemem jest ilość nowości, którymi jesteśmy bomboradowani. Jakiś czas temu postanowiłem się zdecydować, w którym kierunku zamierzam iść i ustaliłem sobie swój stos technologiczny, którego chcę dogłebnie poznać.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;Ustalenie swojego stosu wcale nie ogranicza mnie od nowych rzeczy. Nastał taki moment, w którym chcę znać parę podstawowych narzędzi bardzo dobrze i mieć dobrą bazę do pisania nowoczesnych aplikacji webowych. Oczywiście staram się na bieżąco obserwować co nowego wychodzi, czego inni zaczynają używać, ale już nie mam zamiaru zaraz skakać na coś nowego, tylko z powodu tego, że to jest nowe. Jeśli coś przynosi sporą wartość, jest stabilne i sprawdzone, wtedy można zagłebić się bardziej w temat i szukać zastosowania w swojej pracy.&lt;/p&gt;
&lt;p&gt;Pierwszą dużą rzeczą na którą się zdecydowałem jest React, o którym już trochę pisałem. Wprowadził on trochę zamieszania w środowisku i upowszechnił nowy sposób tworzenia aplikacji, bardzo modularnych napisanych w prosty sposób z użyciem najnowszych możliwości języka Javascript. Kolejnymi plusami jest upowszechnienie Reacta na innych platformach np. React Native, co może w przyszłości mi bardzo pomóc, jeśli będę musiał stworzyć aplikację mobilną. Widząc aktualny stan tej biblioteki i jaki ekosystem narzędzi został zbudowany wokół niej przyszłość Reacta widzę, bardzo stabilną i nie sądzę, żeby w ciągu 5 latach znikł on z rynku.&lt;/p&gt;
&lt;p&gt;Kolejny element układanki to narzędzia budujące. Tu wybrałem i od jakiegoś czasu uczę się Webpacka, wspartego skryptami npm i Gulpem. Webpack ostanio bardzo dojrzał, wydana została wersja druga. Jest aktualnie chyba najpopularniejszym narzędziem do bundlowania JS i podobnie jak w przypadku Reacta ekosystem jest mocno rozwijany wokół tego. Dodatkowo do prostych zadań, czy procesowania plików zostają skrypty i Gulp, którego całkiem dobrze już poznałem do tej pory i jeśli jest z czymś problem w Webpacku, to zawsze mogę wspomóc się sprawdzonym Gulpem.&lt;/p&gt;
&lt;p&gt;Kolejnym elementem do układanki jest SASS i preprocessor PostCSS. Te narzędzia już weszły jakiś czas temu do mojego arsenału i udowodniły swoją wartość. Pisanie styli z ich pomocą, zgodnie z dobrą architekturą jest bardzo proste i szybkie. Chodź na horyzoncie jest sporo rozwiązań do styli w komponencie React np. styled-jsx, narazie stare, dobre rozwiązanie prowadzi. Jednak w niektórych projektach może wykorzystm nowe podejście do styli.&lt;/p&gt;
&lt;p&gt;Do tych elementów dorzucam parę elementów backendowych z Node.js na czele. Mam zamiar skupić się trochę bardziej na stronie serwerowej i wyrobić trochę praktyki w tworzeniu API, innych zadań do przetwarzania danych i obsługi baz danych. Do tego dochodzi świetny framework do tworzenia API - Express.js. Na takim stosie chcę oprzeć swoje umiejętności w zakresie serwerowym.&lt;/p&gt;
&lt;p&gt;Z serwerami od jakiegoś czasu pomaga mi juz Docker i docker-compose, które bardzo ułatwiają mi przenoszenie aplikacji między urządzeniami, serwerami. Mam dalej zamiar szukać najlepszego podejścia do kontenerów i być może wspomoże mnie w tym jeszcze Rancher. Ale z Rancherem nie miałem jeszcze tak dużego kontaktu i wymaga jeszcze sprawdzenia, ale wygląda obiecująco.&lt;/p&gt;
&lt;p&gt;W części serwerowej nie można zapomnieć o jeszcze jednym ważnym aspekcie - bazy danych. Tutaj chciałbym wgłebić się w MongoDB, Redis i 2 bazy relacyjne MySQL i PostgreSQL. Taka urozmaicona wiedza może się bardzo przydać dla różnych rodzajów projektów. Dla niektórych lepiej nadaje się baza NoSQL, dla drugich baza relacyjna i tutaj chcę wybierać odpowiednie narzędzia do pracy, a nie tylko to co znam. Z czasem może dojdzie jeszcze ElasticSearch do wyszukiwarek, ale to już bardzo dalekie plany.&lt;/p&gt;
&lt;p&gt;Na koniec zostawiam sobie narzędzia do testów. Tutaj jeszcze muszę wybrać, czy lepiej korzystać z popularnego zestawu Mocha+Karma, czy już zająć się nowym dzieckiem na podwórku - Jest. Jako, że zaczynam jeszcze zabawę z testami, muszę trochę popracować i z jednym, i z drugim i sprawdzić, co bardziej pomaga mi w pracy i jest prostsze w użyciu.&lt;/p&gt;
&lt;p&gt;A wszystko chcę dalej pisać w Visual Studio Code, którego używam już od ponad roku i spełnia wszystkie moje oczekiwania. Co jakiś czas odkrywam kolejny smaczek, nowy skrót klawiszowy i praca z nim staje się jeszcze szybsza i przyjemniejsza.&lt;/p&gt;
&lt;p&gt;Taki oto stos technologiczny wybrałem na swój początek kariery i zobaczę, jak wypadnie mój plan po 3 latach, bo w takim czasie chciałbym poznać te wszystkie narzędzia dogłębnie i zrobić kilka aplikacji z ich wykorzystaniem. 3 lata wydają się bardzo odległe, ale i narzędzi jest trochę do poznania, więc każdego dnia będę miał okazję nauczyć się czegoś nowego i dużo pracy przede mną. Pewnie w czasie tej drogi niektóre narzędzia stracą na znaczeniu, a inne wejdą na ich miejsce, ale liczę, że taki stos nie wyjdzie szybciej z użytku, niż go poznam dogłębnie.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Immutable.js w reduktorach]]></title><description><![CDATA[Przy ostatnich pracach nad aplikacją i pisaniu reduktorów nie podobało mi się zwracanie za każdym razem nowego obiektu i braku mutacji w aktualnym stanie. Dodawanie atrybutów do obiektu z pomocą Object.assign jest całkiem przyjemne, natomiast usuwanie atrybutu z obiektu już nie wygląda w kodzie tak ładnie i wymaga trochę uwagi przy zarządzaniu stanem. Wtedy pojawił się pomysł na użycie Immutable.js. Dzisiaj pokażę, co z tego wyszło i sądzę, że zachowanie stanu aplikacji z niemutowalnymi obiektami jest całkiem proste.]]></description><link>https://blog.marlas.pl/immutable-js-reducers/</link><guid isPermaLink="false">https://blog.marlas.pl/immutable-js-reducers/</guid><pubDate>Fri, 07 Apr 2017 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Przy ostatnich pracach nad aplikacją i pisaniu reduktorów nie podobało mi się zwracanie za każdym razem nowego obiektu i braku mutacji w aktualnym stanie. Dodawanie atrybutów do obiektu z pomocą Object.assign jest całkiem przyjemne, natomiast usuwanie atrybutu z obiektu już nie wygląda w kodzie tak ładnie i wymaga trochę uwagi przy zarządzaniu stanem. Wtedy pojawił się pomysł na użycie Immutable.js. Dzisiaj pokażę, co z tego wyszło i sądzę, że zachowanie stanu aplikacji z niemutowalnymi obiektami jest całkiem proste.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;Zaczynamy od instalacji, wystarczy &lt;code class=&quot;language-text&quot;&gt;npm install immutable --save&lt;/code&gt; i możemy używać Immutable.js w Redux.&lt;/p&gt;
&lt;p&gt;Potem tylko &lt;code class=&quot;language-text&quot;&gt;import Immutable from &apos;immutable&apos;&lt;/code&gt; i można podpiąć zamiast pustego obiektu JS do domyślnego stanu reduktora pustą niemodyfikowalną mapę: &lt;code class=&quot;language-text&quot;&gt;state = Immutable.Map({})&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Główne metody, które musimy poznać do Map to: &lt;code class=&quot;language-text&quot;&gt;set()&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;get()&lt;/code&gt; i &lt;code class=&quot;language-text&quot;&gt;delete()&lt;/code&gt;. Za pomocą funkcji &lt;code class=&quot;language-text&quot;&gt;set()&lt;/code&gt; ustawiamy wartość atrybutu lub tworzymy nowy atrybut z wartością. Żeby odczytać z mapy wartość wykorzystujemy funkcję &lt;code class=&quot;language-text&quot;&gt;get()&lt;/code&gt; do której przekazujemy klucz. Do usuwania atrybutu służy polecenie &lt;code class=&quot;language-text&quot;&gt;delete()&lt;/code&gt;. Z tymi informacjami możemy zabierać się za przerobienie naszego reduktora.&lt;/p&gt;
&lt;p&gt;Na początku wszystkie miejsca, gdzie przypisuję obiekt zamieniam na przypisania do Immutable.Map().&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; types&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;ADD_PROJECT&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; state&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;action&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;payload&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; Immutable&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Map&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token literal-property property&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; action&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;payload&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token literal-property property&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token literal-property property&quot;&gt;description&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token literal-property property&quot;&gt;categories&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Immutable&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Map&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Następnie przekształcam po kolei reduktory. Usuwanie projektu z obiektu z starej wersji z użyciem biblioteki lodash zamieniam z:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; _&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;omit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;state&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;action&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;payload&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;na:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; state&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;delete&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;action&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;payload&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Przy zmianie wartości wewnętrznych obiektu jest trochę więcej zmian. Poprzedni kod:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; Object&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;assign&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        _&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;state&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;action&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;payload&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;projectId&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;].name&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
          action&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;payload&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Kod z Immutable.js:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; state&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;action&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;payload&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;projectId&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        state
          &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;action&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;payload&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;projectId&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
          &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;name&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;action&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;payload&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Mi bardzo przypadła do gustu biblioteka Immutable.js i korzystanie z niej jest znacznie prostsze niż rokminianie, jak zrobić immutability z dostępnymi w języku metodami. Składnia jest bardzo prosta i dostaję gwarancję, że nie zmodyfikuję przypadkowo obiektu. W przyszłości postaram się zwiększyć użycie Immutable.js w reszcie projektu i zobaczę jakie będą tego efekty.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Lighthouse]]></title><description><![CDATA[Lighthouse. Co to takiego? Co ma wspólnego latarnia z IT?
Okazuje się, że coś wspólnego ma. Lighthouse to projekt o otwrtym kodzie źródłowym pozwalającym sprawdzić różne metryki strony internetowej. Dzięki niej możemy się dowiedzieć, czego brakuje naszej aplikacji do stania się Progresywną Aplikacją Webową.]]></description><link>https://blog.marlas.pl/lighthouse/</link><guid isPermaLink="false">https://blog.marlas.pl/lighthouse/</guid><pubDate>Wed, 05 Apr 2017 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Lighthouse. Co to takiego? Co ma wspólnego latarnia z IT?
Okazuje się, że coś wspólnego ma. Lighthouse to projekt o otwrtym kodzie źródłowym pozwalającym sprawdzić różne metryki strony internetowej. Dzięki niej możemy się dowiedzieć, czego brakuje naszej aplikacji do stania się Progresywną Aplikacją Webową.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;Korzystać z &lt;a href=&quot;https://github.com/GoogleChrome/lighthouse&quot;&gt;Lighthouse&lt;/a&gt; możemy na kilka sposobów. Dostepne jest rozszerzenie do przeglądarki Google Chrome i jako aplikacja konsolowa. Skupię się dzisiaj na rozszerzeniu i pokażę jak z pomocą tak prostego, łatwego w użyciu narzędzia możemy odkryć błędy naszej aplikacji oraz znaleźć potencjalne miejsca na ulepszenia.&lt;/p&gt;
&lt;p&gt;Instrukcje instalacji są dostępne w &lt;a href=&quot;https://github.com/GoogleChrome/lighthouse&quot;&gt;repozytorium projektu&lt;/a&gt;. Aplikacja jest dostępna w sklepie z rozszerzeniami Chrome i instalacja zajmuje krótką chwilkę. Po instalacji w oknie przeglądarki zostaje dodana ikona z latarnią i możemy zabrać się za sprawdzanie aplikacji webowych.&lt;/p&gt;
&lt;p&gt;Wystarczy tylko przejść na stronę, którą chcemy przetestować, kliknąć ikonkę i przycisk &quot;generate report&quot; i po kilkunastu sekundach dostajemy ładny raport o stronie i ewentualnych błędach + ogólny wynik strony w 100 punktowej skali.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/blog-marlas-pl-lighthouse.png&quot; alt=&quot;Wynik lighthouse dla blog.marlas.pl&quot;&gt;&lt;/p&gt;
&lt;p&gt;Na blogu jest jeszcze parę rzeczy do poprawy i mój ogólny wynik wyniósł 38/100 punktów, ale nie jest najgorzej. Przy każdym błedzie jest dokładna informacja o przyczynie i o zalecanych krokach do naprawy tego problemu. Naprawdę polecam każdemu te rozszerzenie, bo pozwala złapać poważne błędy, które możemy czasem poprawić w bardzo krótkim czasie. Aktualnie blog nie ma pliku manifestu oraz service workera i przez to tracę masę punktów, ale reszta wyników jest bardzo dobra.&lt;/p&gt;
&lt;p&gt;Nazwa lighthouse wzięła się z tego, że te narzędzie miało być latarnią, która prowadzi do Progresywnych Aplikacji Webowych. Działa bardzo dobrze i warto z niego korzystać, nawet jeśli nie tworzymy progresywnych aplikacji. Twórcy cały czas dorzucają nowe metryki i dzięki temu z czasem będziemy w stanie z Lighthouse wyłapać jeszcze więcej niedociągnięć strony.&lt;/p&gt;
&lt;p&gt;Każdemu polecam sprawdzić swoje aplikacje z pomocą Lighthouse i dzięki temu poprawić swoje aplikacje.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Types, reducers, action creators]]></title><description><![CDATA[W ostatnim poście na temat projektu opisywałem strukturę stanu aplikacji. Dzisiaj pora na kodzenie ostatnich ustaleń w projekcie. Pokażę, jak w projekcie wyglądają typy, kreatory akcji i reduktory.]]></description><link>https://blog.marlas.pl/types,reducers,actionCreators/</link><guid isPermaLink="false">https://blog.marlas.pl/types,reducers,actionCreators/</guid><pubDate>Fri, 31 Mar 2017 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;W ostatnim poście na temat projektu opisywałem strukturę stanu aplikacji. Dzisiaj pora na kodzenie ostatnich ustaleń w projekcie. Pokażę, jak w projekcie wyglądają typy, kreatory akcji i reduktory.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;Skupię się tutaj na głównie na akcjach i ich kreatorach. Część akcji już ma jest zaimplementowana w reduktorze, ale nie wszystkie. W trakcie prac nie spodobał mi się kod reduktorów i muszę znaleźć lepszy sposób na ich pisanie. Tworzenie nowych obiektów, bez mutacji starych nie jest takie proste jak myślałem, więc może tu wykorzystam bibliotekę do immutability. Może będzie nią Immutability.js, ale to już opiszę w następnym poście.&lt;/p&gt;
&lt;p&gt;Prace zacząłem od części stanu - projektów. Na początek zabieram się za pisanie akcji. Wszystkie typy akcji są przechowywane w projekcie w osobnym pliku, przez co powinienem uniknąć błędów z źle wprowadzonymi nazwami typów. Jest to polecana dobra praktyka przy organizacji stanu Redux i każdemu polecam jej używać. Dodatkowo dostajemy lepsze wsparcie w edytorze niż w przypadku ręcznie wpisywanych typów.&lt;/p&gt;
&lt;p&gt;Dla projektów stworzyłem następujące typy:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;ADD_PROJECT&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;ADD_PROJECT&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;REMOVE_PROJECT&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;REMOVE_PROJECT&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;SET_PROJECT_NAME&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;SET_PROJECT_NAME&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;SET_PROJECT_DESCRIPTION&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;SET_PROJECT_DESCRIPTION&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;ADD_PROJECT_CATEGORY&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;ADD_PROJECT_CATEGORY&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;REMOVE_PROJECT_CATEGORY&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;REMOVE_PROJECT_CATEGORY&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;SET_PROJECT_CATEGORY_NAME&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;SET_PROJECT_CATEGORY_NAME&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;SET_PROJECT_CATEGORY_DESCRIPTION&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;SET_PROJECT_CATEGORY_DESCRIPTION&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;EDIT_PROJECT_ID&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;EDIT_PROJECT_ID&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;EXPORT_PROJECT_CATEGORY_ID&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;EDIT_PROJECT_CATEGORY_ID&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Teraz pora na kolejną część układanki - kreatory akcji. Kolejna rzecz, ktora może wydawać się niepotrzebna, jeśli zaczynamy pracę z Redux. Przecież przy wywoływaniu akcji zawsze ręcznie możemy sobie stworzyć obiekt akcji, to w takim razie po co nam kreatory akcji? Kreatory mają taką samą funkcję, co w przypadku zmiennych do typów. Mają nam ułatwić pracę i wyeliminować często popełniane błędy. Dzięki temu, że akcję deklarujemy w jednym miejscu nie mamy duplikacji kodu, a jeśli potrzebujemy wywołać akcję to wystarczy teraz tylko wywołać jedną funkcję, zamiast ręcznie tworzyć obiekt akcji.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;ADD_PROJECT&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;REMOVE_PROJECT&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;SET_PROJECT_NAME&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token constant&quot;&gt;SET_PROJECT_DESCRIPTION&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;ADD_PROJECT_CATEGORY&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;REMOVE_PROJECT_CATEGORY&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token constant&quot;&gt;SET_PROJECT_CATEGORY_NAME&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;SET_PROJECT_CATEGORY_DESCRIPTION&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token constant&quot;&gt;EDIT_PROJECT_ID&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;EDIT_PROJECT_CATEGORY_ID&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./../types&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;addProject&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;projectId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token literal-property property&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;ADD_PROJECT&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token literal-property property&quot;&gt;payload&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; projectId
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;removeProject&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;projectId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token literal-property property&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;REMOVE_PROJECT&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token literal-property property&quot;&gt;payload&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; projectId
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;setProjectName&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;projectId&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token literal-property property&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;SET_PROJECT_NAME&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token literal-property property&quot;&gt;payload&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            projectId&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            name
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;setProjectDescription&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;projectId&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; description&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token literal-property property&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;SET_PROJECT_DESCRIPTION&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token literal-property property&quot;&gt;payload&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            projectId&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            description
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;addProjectCategory&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;projectId&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; categoryId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token literal-property property&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;ADD_PROJECT_CATEGORY&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token literal-property property&quot;&gt;payload&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            projectId&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            categoryId
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;removeProjectCategory&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;projectId&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; categoryId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token literal-property property&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;REMOVE_PROJECT_CATEGORY&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token literal-property property&quot;&gt;payload&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            projectId&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            categoryId
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;setProjectCategoryName&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;projectId&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; categoryId&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token literal-property property&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;SET_PROJECT_CATEGORY_NAME&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token literal-property property&quot;&gt;payload&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            projectId&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            categoryId&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            name
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;setProjectCategoryDescription&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;projectId&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; categoryId&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; description&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token literal-property property&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;SET_PROJECT_CATEGORY_DESCRIPTION&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token literal-property property&quot;&gt;payload&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            projectId&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            categoryId&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            description
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;editProjectId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;projectId&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token literal-property property&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;EDIT_PROJECT_ID&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token literal-property property&quot;&gt;payload&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            projectId&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            id
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;editProjectCategoryId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;projectId&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; categoryId&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token literal-property property&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;EDIT_PROJECT_CATEGORY_ID&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token literal-property property&quot;&gt;payload&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            projectId&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            categoryId&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            id
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Każdą akcję mamy dobrze przygotowaną, widzimy jakie parametry otrzymamy w naszym reduktorze, więc możemy zabierać się za jego implementację.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; _ &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;lodash&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;ADD_PROJECT&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;REMOVE_PROJECT&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;SET_PROJECT_NAME&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token constant&quot;&gt;SET_PROJECT_DESCRIPTION&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;ADD_PROJECT_CATEGORY&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;REMOVE_PROJECT_CATEGORY&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token constant&quot;&gt;SET_PROJECT_CATEGORY_NAME&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;SET_PROJECT_CATEGORY_DESCRIPTION&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token constant&quot;&gt;EDIT_PROJECT_ID&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;EDIT_PROJECT_CATEGORY_ID&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;../types&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;projectsReducer&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
  &lt;span class=&quot;token parameter&quot;&gt;state &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  action&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;switch&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;action&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;type&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;ADD_PROJECT&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; Object&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;assign&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;state&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;action&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;payload&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token literal-property property&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; action&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;payload&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token literal-property property&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token literal-property property&quot;&gt;description&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token literal-property property&quot;&gt;categories&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;REMOVE_PROJECT&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; _&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;omit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;state&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;action&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;payload&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;SET_PROJECT_NAME&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; Object&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;assign&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        _&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;state&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;action&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;payload&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;projectId&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;].name&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
          action&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;payload&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;SET_PROJECT_DESCRIPTION&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; Object&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;assign&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        _&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;state&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;action&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;payload&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;projectId&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;].description&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
          action&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;payload&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;description&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;ADD_PROJECT_CATEGORY&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;REMOVE_PROJECT_CATEGORY&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;SET_PROJECT_CATEGORY_NAME&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;SET_PROJECT_CATEGORY_DESCRIPTION&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;EDIT_PROJECT_ID&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;EDIT_PROJECT_CATEGORY_ID&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; state&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; state&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt; projectsReducer&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Reduktor zawsze powinien zwracać nam nowy obiekt, przez co używam &lt;code class=&quot;language-text&quot;&gt;Object.assign&lt;/code&gt;. Jest to nowa metoda z ES6, która pomaga w tworzeniu nowych obiektów na podstawie istniejących. Przy usuwaniu atrybutów z obiektu korzystam z &lt;code class=&quot;language-text&quot;&gt;_.omit&lt;/code&gt;. Ta funkcja biblioteki lodash pozwala usuwac z obiektu pojedyncze atrybuty i wynik zwraca w postaci nowego obiektu, przez co nie jest tutaj wymagana metoda &lt;code class=&quot;language-text&quot;&gt;assign&lt;/code&gt; dla obiektu. Nieobsłużone przypadki zwracają poprzedni stan zgodnie z dobrą praktyką przy korzystaniu z Redux.&lt;/p&gt;
&lt;p&gt;Tak wygląda moje podejście do zarządzania akcjami w Redux. Sam nie miałem jeszcze dużej praktyki z Redux i moje rozwiązania mogą nie być optymalne, więc jeśli możecie coś poradzić, to czekam na komentarze. W następnym poście wrócę do reduktorów i spróbuję podejść do nich z niemutowalnymi obiektami.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Najlepsza nowość w ES6 - modules]]></title><description><![CDATA[Już od długiego czasu w użyciu jest nowy standard dla javascriptu - ES6 (zwany również ES2015). Może jego użycia jeszcze nie widać w plikach wielu aplikacji, bo w większośći przypadków musi być on jeszcze transpilowany do wspieranego niemal wszędzie poprzedniego standardu ES5. Mimo tego standard ten szybko został zaadoptowany w społeczności programistów JS i ciężko natknąć się jeszcze na nowy kod JS, który nie jest pisany w tym standardzie. ES6 wnosi sporo fajnych usprawnień do języka, ale dzisiaj chcę omówić moją ulubioną część tego standardu - moduły.]]></description><link>https://blog.marlas.pl/najlepsza-nowosc-w-es6-modules/</link><guid isPermaLink="false">https://blog.marlas.pl/najlepsza-nowosc-w-es6-modules/</guid><pubDate>Wed, 29 Mar 2017 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Już od długiego czasu w użyciu jest nowy standard dla javascriptu - ES6 (zwany również ES2015). Może jego użycia jeszcze nie widać w plikach wielu aplikacji, bo w większośći przypadków musi być on jeszcze transpilowany do wspieranego niemal wszędzie poprzedniego standardu ES5. Mimo tego standard ten szybko został zaadoptowany w społeczności programistów JS i ciężko natknąć się jeszcze na nowy kod JS, który nie jest pisany w tym standardzie. ES6 wnosi sporo fajnych usprawnień do języka, ale dzisiaj chcę omówić moją ulubioną część tego standardu - moduły.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;Moduły w języku JS pojawiły się już dawno temu, ale tylko w formie konwencji. Były moduły CommonJS i AMD, ale teraz mamy już dostęp do natywnych modułów zdefiniowanych już w standardzie javascript. Dzięki temu powinien zakończyć się odwieczny problem gigantycznych plików JS, w których znajduje się cały kod aplikacji. Pisanie prostego, modularnego kodu jest banalnie proste i moduły powinny być stosowane przy wszystkich nowych projektach. Jedyną aktualną wadą jest brak natywnego wsparcia modułów w przeglądarkach. Z pomocą przychodzi jednak webpack, który bez żadnej dodatkowej konfiguracji transpiluje nasz kod używający modułów ES6 do jednego pliku, który możemy wysłać do każdej przeglądarki. Więcej na temat webpacka i jego instalacji można znaleźć na &lt;a href=&quot;https://webpack.js.org/&quot;&gt;oficjalnej stronie&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;To teraz pora na przedstawienie składni modułów. Moduły opierają się na eksporcie i imporcie. Do eksportu używamy polecenia: &lt;code class=&quot;language-text&quot;&gt;export&lt;/code&gt;, a do importu &lt;code class=&quot;language-text&quot;&gt;import&lt;/code&gt;. Tak proste są moduły ES6. Pokażę teraz różne rodzaje eksportów: domyślne, nazywane i jak się je obsługuje.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// plik a.js&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;INCREMENT&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; x &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;INCREMENT&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;doubleIncrement&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;INCREMENT&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// plik b.js&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; increment&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;INCREMENT&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; b&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; doubleIncrement &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./a&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token function&quot;&gt;increment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;b&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;doubleIncrement&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;


&lt;span class=&quot;token comment&quot;&gt;// plik c.js&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; inc &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./a&apos;&lt;/span&gt;

inc&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;increment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Na powyższym przykładzie pokazałem z czego najcześciej korzystam i co wystarczy, żeby zacząć korzystać z modułów.
W pliku a.js w pierwszej linii zdefiniowałem standardowy export zmiennej z pliku. Eksportować w ten sposób możemy funkcje, zmienne, klasy.&lt;/p&gt;
&lt;p&gt;Kolejnym typem eksportu jest eksport domyślny. Żeby go użyć po słowie &lt;code class=&quot;language-text&quot;&gt;export&lt;/code&gt; używamy słowa &lt;code class=&quot;language-text&quot;&gt;default&lt;/code&gt;. Należy tutaj zauważyć, że w jednym pliku możemy tylko raz eksportować domyślnie i wtedy w przypadku zmiennych &lt;code class=&quot;language-text&quot;&gt;const&lt;/code&gt; i &lt;code class=&quot;language-text&quot;&gt;let&lt;/code&gt; nie definiujemy zmiennej, tylko zwracamy wartość(np. &lt;code class=&quot;language-text&quot;&gt;export default 5&lt;/code&gt;). Później eksportuję jeszcze jedną funkcję w taki sam sposób jak zmienną &lt;code class=&quot;language-text&quot;&gt;INCREMENT&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Zamiast tej składni możemy wszystkie rzeczy wyeksportować w innym miejscu kodu i nie potrzebujemy wtedy przy każdej zmiennej, czy funkcji pisać słowa &lt;code class=&quot;language-text&quot;&gt;export&lt;/code&gt;. Wtedy na przykład na końcu pliku deklarujemy &lt;code class=&quot;language-text&quot;&gt;export { INCREMENT, doubleIncrement }&lt;/code&gt;. Przy takiej deklaracji możemy również zmieniać nazwę eksportu (np. &lt;code class=&quot;language-text&quot;&gt;export { INCREMENT as INC, doubleIncrement as default }&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;Przejdźmy teraz do tego w jaki sposób zaimportować to co wyeksportowaliśmy z innego pliku. Zaczynamy on słowa &lt;code class=&quot;language-text&quot;&gt;import&lt;/code&gt; potem deklarujemy co chcemy zaimportować z pliku, następnie słowo kluczowe &lt;code class=&quot;language-text&quot;&gt;from&lt;/code&gt; i definujemy ścieżkę pliku. W przypadku braku ścieżki plik będzie szukany wśród modułów w &lt;code class=&quot;language-text&quot;&gt;node_modules&lt;/code&gt;. Rozszerzenie &lt;code class=&quot;language-text&quot;&gt;js&lt;/code&gt; może zostać pominięte.&lt;/p&gt;
&lt;p&gt;Jeśli potrzebujemy zaimportować tylko domyślny eksport to wystarczy nam &lt;code class=&quot;language-text&quot;&gt;import nazwa from &apos;./plik&apos;&lt;/code&gt;. Nazwa może być jakakolwiek i pod nią będziemy móc się dostać do zaimportowanej zmiennej, funkcji, czy klasy. Jeśli chcemy zaimportować jeden z nazwanych eksportów - deklarujemy je w klamrach i podejemy nazwę elementu, który eksportujemy (np. &lt;code class=&quot;language-text&quot;&gt;import { a, b as c } from &apos;./moj-plik&apos;&lt;/code&gt;). W tym przykładzie pokazałem, że nawany eksport można zaimportować pod konkretną nazwą z użyciem słowa &lt;code class=&quot;language-text&quot;&gt;as&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Został nam ostatni typ importu. &lt;code class=&quot;language-text&quot;&gt;import * as inc from &apos;./a&apos;&lt;/code&gt; - przy tym imporcie zaimportowane zostaną wszystkie wyeksportowane elementy do obiektu o nazwie &lt;code class=&quot;language-text&quot;&gt;inc&lt;/code&gt;. Żeby wykonać wyeksportowaną funkcję b wykonujemy &lt;code class=&quot;language-text&quot;&gt;inc.b()&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Tak oto wygląda praca z modułami w ES6. Opanowanie ich nie jest ciężkie, a składnia jest bardzo prosta. Po poznaniu tej funkcji języka już nigdy nie wrócisz do pisania gigantycznych plików, a cały Twój kod będzie znacznie lepiej uporządkowany. Po więcej informacji na temat modułów zapraszam do &lt;a href=&quot;http://2ality.com/2014/09/es6-modules-final.html&quot;&gt;artykułu&lt;/a&gt; na blogu Dr. Axela Rauschmayer, który jest poświęcony nowym standardom JS.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Struktura stanu aplikacji]]></title><description><![CDATA[Zaczyna się prawdziwy etap tworzenia aplikacji. Podstawowy szkielet aplikacji już istnieje, narzędzia działają, podstawowe zadania można dodawać. Teraz pora implementować główne funkcjonalności. Ale zanim przejdę do pisania funkcjonalności, chcę zaplanować bardzo ważną część aplikacji - jej stan.]]></description><link>https://blog.marlas.pl/struktura-stanu-aplikacji/</link><guid isPermaLink="false">https://blog.marlas.pl/struktura-stanu-aplikacji/</guid><pubDate>Tue, 28 Mar 2017 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Zaczyna się prawdziwy etap tworzenia aplikacji. Podstawowy szkielet aplikacji już istnieje, narzędzia działają, podstawowe zadania można dodawać. Teraz pora implementować główne funkcjonalności. Ale zanim przejdę do pisania funkcjonalności, chcę zaplanować bardzo ważną część aplikacji - jej stan.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;Pisanie aplikacji w React to jedna ciągła refaktoryzacja. Cały czas wydziela się nowe komponenty, rozbija zakres odpowiedzalności aktualnych komponentów, niektóre komponenty przerabia się na prezentacyjne, inne stają się kontenerami. Jednak już na początku prac ważne jest dobre rozplanowanie stanu aplikacji w Redux. Zaprezentuję dzisiaj, jak sobie wyobrażam mój stan aplikacji do mojego MVP.&lt;/p&gt;
&lt;p&gt;W skład MVP ma wchodzić definiowanie zadań. Każde zadanie może być jednorazowe lub może być zadaniem cyklicznym. Każde zadanie ma swoją wagę w punktach i możemy do zadania przypisać projekt i kategorię w projekcie. Takie są założenia do MVP menedżera życia. Przejdźmy więc do tworzenia struktury stanu aplikacji.&lt;/p&gt;
&lt;p&gt;Zacznijmy od mniej skompilkowanej części - projektu.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token literal-property property&quot;&gt;projects&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token literal-property property&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;test&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token literal-property property&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Testowy projekt&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token literal-property property&quot;&gt;description&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Projekt dla sąsiada testa&quot;&lt;/span&gt;
        &lt;span class=&quot;token literal-property property&quot;&gt;categories&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token literal-property property&quot;&gt;estimation&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;token literal-property property&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;estimation&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;token literal-property property&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Estymacja&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;token literal-property property&quot;&gt;description&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Kategoria dla szacunków&quot;&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;token literal-property property&quot;&gt;development&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;token literal-property property&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;development&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;token literal-property property&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Programowani&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;token literal-property property&quot;&gt;description&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Prace programistyczne&quot;&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;drugi_test&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token literal-property property&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;drugi_test&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token literal-property property&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Kolejny test&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token literal-property property&quot;&gt;description&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Opis dla drugiego projektu&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token literal-property property&quot;&gt;categories&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Projekty i kategorie mają zostać w przyszłości użyte do generowania różnego rodzaju statystyk i raportów. Taka struktura powinna zapewnić łatwość dodawania kolejnych atrybutów do projektów, jak również zapewnić proste przeszukiwanie po stronie kodu. Nie zostały tutaj użyte żadne tablice. Do wszystkiego można się dostać po identyfikatorze, co pozwoli uniknąć przechodzenia po całej liście przy próbie znalezienia konkretnego projektu.&lt;/p&gt;
&lt;p&gt;Przejdźmy teraz do definiowania zadań.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token literal-property property&quot;&gt;tasks&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token literal-property property&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token literal-property property&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Pierwsze zadanie&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token literal-property property&quot;&gt;project&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;test&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token literal-property property&quot;&gt;project_category&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;estimation&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token literal-property property&quot;&gt;points&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;15&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token literal-property property&quot;&gt;cyclic&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;
        &lt;span class=&quot;token literal-property property&quot;&gt;date&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;2017-04-20&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token literal-property property&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;todo&quot;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token literal-property property&quot;&gt;cyclic_tasks&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token literal-property property&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token literal-property property&quot;&gt;start_date&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;2017-03-21&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token literal-property property&quot;&gt;end_date&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;2017-06-20&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token literal-property property&quot;&gt;repeat&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;*&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token literal-property property&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Pierwsze zadanie&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token literal-property property&quot;&gt;project&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;test&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token literal-property property&quot;&gt;project_category&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;estimation&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token literal-property property&quot;&gt;points&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;15&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Obiekt zadań będzie przechowywać wszystkie zadania. Każde zadanie ma swoje atrybuty: nazwę, status, datę i może mieć przypisany projekt i kategorię projektu. Kolejnym obiektem są cykliczne zadania. Tutaj definiujemy zadania cykliczne, jak często mają być powtarzane (* - każdy dzień, liczby 0-6 rozdzielone przecinkiem poszczególne dni tygodnia). Dodatkowo dajemy datę początkową zadań cyklicznych i końcową. Definiujemy także domyślną nazwę, punkty i dane projektu.&lt;/p&gt;
&lt;p&gt;Dzięki takiemu rozwiązaniu będziemy mogli generować pojedyncze zadania do obiektu tasks, które będą miały przypisywane domyślne atrybuty. Każde pojedyncze zadanie będziemy mogli osobno modyfikować, jak również będziemy mogli zmienić wszystkie zadania z cyklicznej grupy. Podobnie działa taki mechanizm w kalendarzu Google. Przy edycji wydarzenia cyklicznego możemy edytować pojedyncze wydarzenie lub wszystkie wydarzenia w cyklu. Myślę, że to zapewni odpowiednią elastyczność i nie będzie wymagać dużych zmian w miarę rozwoju aplikacji.&lt;/p&gt;
&lt;p&gt;W następnych postach zabierzemy się za implementację przemyślanego dzisiaj stanu aplikacji i zobaczymy, czy to co sobie wymyśliłem będzie działać dobrze.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Yarn - lepszy klient npm?]]></title><description><![CDATA[W październiku zeszłego roku został udostępniony światu nowy menedżer pakietów dla javascriptu - Yarn. Od tamtego czasu nowy klient zdobywa coraz większą popularność. Przy wielu bibliotekach, modułach w instrukcjach instalacyjnych zaczyna się pojawiać oprócz  komenda . Ja też już jakiś czas temu przerzuciłem się z klienta npm na Yarna. Opowiem trochę o moich doświadczeniach z nowym menedżerem i przedstawię trochę różnic między tymi klientami.]]></description><link>https://blog.marlas.pl/yarn-vs-npm/</link><guid isPermaLink="false">https://blog.marlas.pl/yarn-vs-npm/</guid><pubDate>Wed, 22 Mar 2017 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;W październiku zeszłego roku został udostępniony światu nowy menedżer pakietów dla javascriptu - Yarn. Od tamtego czasu nowy klient zdobywa coraz większą popularność. Przy wielu bibliotekach, modułach w instrukcjach instalacyjnych zaczyna się pojawiać oprócz &lt;code class=&quot;language-text&quot;&gt;npm install&lt;/code&gt; komenda &lt;code class=&quot;language-text&quot;&gt;yarn add&lt;/code&gt;. Ja też już jakiś czas temu przerzuciłem się z klienta npm na Yarna. Opowiem trochę o moich doświadczeniach z nowym menedżerem i przedstawię trochę różnic między tymi klientami.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;Dla mnie głównym powodem, żeby skorzystać z Yarna były długie czasy instalacji pakietów, czy to przy stawianiu projektu, czy przy instalowaniu pojedynczych modułów. Yarn bardzo mocno reklamuje to, że jest znacznie szybszy od klienta npm. Moje subiektywne wrażenia przy instalacji również to potwierdzają. Wszystko działa znacznie szybciej niż npm, w informacje wyświetlane przy instalacji pakietów są bardziej czytelne. Według benchamrków Yarn jest zazwyczaj 2 razy szybszy niż npm.&lt;/p&gt;
&lt;p&gt;Kolejną bardzo fajną funkcjonalnością Yarna jest plik &lt;code class=&quot;language-text&quot;&gt;yarn.lock&lt;/code&gt;, który blokuje nam pakiety na konkretnych wersjach. W pliku tym są informacje o wersji pakietu, miejsca z którego został pobrany i jego suma kontrolna. W npm też coś takiego istnieje i nazywa się &lt;code class=&quot;language-text&quot;&gt;shrinkwrap&lt;/code&gt;, ale obsługa tego w kliencie npm jest mniej przyjemna. Nie musimy pamiętać o tym pliku, o jego aktualizowaniu przy zmianie wersji. W Yarn każda instalacja pakietu, aktualizacja automatycznie zaktualizuje plik &lt;code class=&quot;language-text&quot;&gt;yarn.lock&lt;/code&gt;. Dzięki temu wszyscy zawsze mają takie same wersje pakietów. Problemy z różnymi wersjami pakietów czasem stwarzały problemy, zwłaszcza, jeśli twórca pakietu nie przestrzegał zasad wersjonowania według &lt;code class=&quot;language-text&quot;&gt;semver&lt;/code&gt;, na którym opiera się cały system npm.&lt;/p&gt;
&lt;p&gt;Yarn ma jeszcze jedną drobną nowość, której brakuje w npm. Dzięki poleceniu &lt;code class=&quot;language-text&quot;&gt;yarn licences ls&lt;/code&gt; można wyświetlić listę wszystkich pakietów z ich licencjami. Drobnostka, a czasem może się przydać.&lt;/p&gt;
&lt;p&gt;Start z Yarn jest bardzo prosty. Instalujemy klienta zgodnie z wskazówkami na &lt;a href=&quot;https://yarnpkg.com/en/docs/install&quot;&gt;stronie&lt;/a&gt; i możemy zacząć korzystać.&lt;/p&gt;
&lt;p&gt;Poniżej lista najważniejszych komend npm i ich odpowiedników w Yarn:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;npm&lt;/th&gt;
&lt;th&gt;Yarn&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;npm install&lt;/td&gt;
&lt;td&gt;yarn&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;npm install --save react&lt;/td&gt;
&lt;td&gt;yarn add react&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;npm install --save-dev webpack&lt;/td&gt;
&lt;td&gt;yarn add --dev webpack&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;npm install --global yo&lt;/td&gt;
&lt;td&gt;yarn global add yo&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Większa lista jest dostępna w &lt;a href=&quot;https://yarnpkg.com/en/docs/migrating-from-npm&quot;&gt;dokumentacji Yarna&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Należy tutaj zauważyć, że z Yarn nie możemy zainstalować pakietu bez opcji &lt;code class=&quot;language-text&quot;&gt;--save&lt;/code&gt; lub &lt;code class=&quot;language-text&quot;&gt;--save-dev&lt;/code&gt;. Według mnie to duży plus, bo nigdy nie spotkamy się z sytuacją, że tworzymy projekt i instalujemy wszystkie zależności. Następnie dzielimy się projektem z kolegą, mówimy mu, żeby zrobił &lt;code class=&quot;language-text&quot;&gt;npm install&lt;/code&gt; i wszystko będzie działać. Tu natomiast dostajemy wiadomość, że coś nie działa i brakuje jakiegoś pakietu. Przez to, że w Yarn wszystko jest zawsze zapisywane w &lt;code class=&quot;language-text&quot;&gt;package.json&lt;/code&gt; unikamy tego powszechnego problemu.&lt;/p&gt;
&lt;p&gt;Yarn ma jeszcze parę fajnych funkcji i jeśli chcecie o nich poczytać, to wszystkie informacje znajdziecie na &lt;a href=&quot;https://yarnpkg.com/en/&quot;&gt;stronie Yarna&lt;/a&gt;. Wszystko jest bardzo przejrzyście wyjaśnione i całkowite przejście z npm na Yarn dla mnie nie stanowiło żadnego problemu dzięki tej dokumentacji. Zachęcam każdego do sprawdzenia Yarna, choćby tylko dla szybszych instalacji. Może akurat też się wam tak spodoba, że już nie wrócicie do klienta npm.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Redux - zapis stanu do lokalnej pamięci]]></title><description><![CDATA[Od ostatniego postu o projekcie dodałem do aplikacji możliwość ustawienia projektu do każdego zadania oraz usuwanie zadań. Podczas prac bardzo irytowało mnie to, że przy każdym odświeżeniu strony cały stan aplikacji był tracony. Aktualnie planuję rozwijać tylko część frontendową aplikacji, więc implementacja backendu nie wchodziła w grę. Z pomocą przychodzi lokalna pamięć przeglądarki.]]></description><link>https://blog.marlas.pl/redux-lokalny-zapis-stanu/</link><guid isPermaLink="false">https://blog.marlas.pl/redux-lokalny-zapis-stanu/</guid><pubDate>Sat, 18 Mar 2017 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Od ostatniego postu o projekcie dodałem do aplikacji możliwość ustawienia projektu do każdego zadania oraz usuwanie zadań. Podczas prac bardzo irytowało mnie to, że przy każdym odświeżeniu strony cały stan aplikacji był tracony. Aktualnie planuję rozwijać tylko część frontendową aplikacji, więc implementacja backendu nie wchodziła w grę. Z pomocą przychodzi lokalna pamięć przeglądarki.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;Przeglądarka oferuje kilka możliwości przechowywaniu stanu. Wsród nich są &lt;code class=&quot;language-text&quot;&gt;sessionStorage&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;localStorage&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;indexedDB&lt;/code&gt; i ciasteczka. Moim wymaganiem było trzymanie stanu przez cały czas development, a nie tylko na czas sesji. Z tego powodu &lt;code class=&quot;language-text&quot;&gt;sessionStorage&lt;/code&gt; odpada. IndexedDB lepiej nadaje się do tworzenia lokalnych baz danych, a moim celem jest zapisanie pojedynczego obiektu - przez to &lt;code class=&quot;language-text&quot;&gt;indexedDB&lt;/code&gt; również odpada. Stan aplikacji ma być dostępny tylko dla klienta i nie musi być wysyłany do serwera, więc ciasteczka też się nie nadają. Tak oto pozostał nam &lt;code class=&quot;language-text&quot;&gt;localStorage&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;LocalStorage ma bardzo proste API. Oferuje nam dwie metody: &lt;code class=&quot;language-text&quot;&gt;setItem(key, value)&lt;/code&gt; oraz &lt;code class=&quot;language-text&quot;&gt;getItem(key)&lt;/code&gt;.
Jak już znamy API, to możemy zabrać się do pracy. Naszym celem jest zapis przy każdej zmianie stanu aplikacji oraz odczyt stanu aplikacji przy ładowaniu strony.&lt;/p&gt;
&lt;p&gt;Stan aplikacji zapiszę pod kluczem &lt;code class=&quot;language-text&quot;&gt;reduxState&lt;/code&gt;.
Tak więc odczyt stanu możemy zrealizować w następujący sposób.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; persistedState &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; localStorage&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getItem&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;reduxState&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;JSON&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;localStorage&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getItem&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;reduxState&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Przy odczycie zserializowany stan muszę przypisać do obiektu. Do parsowania JSON używam funkcji &lt;code class=&quot;language-text&quot;&gt;JSON.parse()&lt;/code&gt;.
Poniżej kod do zapisu stanu.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;localStorage&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setItem&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;reduxState&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;JSON&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;stringify&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;store&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getState&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Analogicznie przy zapisie stanu do localStorage obiekt należy najpierw serializować funkcją &lt;code class=&quot;language-text&quot;&gt;JSON.stringify()&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Teraz zostaji mi tylko połączenie zapisu i odczytu do Redux. Zapis możemy wykonać korzystając z funkcji &lt;code class=&quot;language-text&quot;&gt;subscribe()&lt;/code&gt; na naszym stanie. Funkcja ta jest wywoływana przy każdej nowej akcji w Redux.&lt;/p&gt;
&lt;p&gt;Finalny kod do zapisu stanu wygląda następująco:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;store&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;subscribe&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    localStorage&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setItem&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;reduxState&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;JSON&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;stringify&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;store&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getState&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Stan aplikacji odczytujemy tylko raz, przed inicjowaniem naszego stanu Redux. Przy tworzeniu naszego kontenera stanu jako drugi parametr możemy przekazać stan początkowy i tu własnie przekazujemy odczytany z lokalnej pamięci stan. Tak oto wygląda kod odczytu stanu:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; persistedState &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; localStorage&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getItem&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;reduxState&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;JSON&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;localStorage&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getItem&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;reduxState&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; store &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;createStore&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;rootReducer&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; persistedState&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Taki krótki kod wystarczy, żeby nasz stan był zapisywany w lokalnej pamięci i usprawniał nam proces tworzenia aplikacji. W moim projekcie jest również zaimplementowane renderowanie po stronie serwera. Tu trzeba trochę uważać i używać localStorage tylko po stronie klienta. Żeby sprawdzić środowisko wykonywania skryptu przydaje się sprawdzenie, czy obiekt &lt;code class=&quot;language-text&quot;&gt;window&lt;/code&gt; jest dostępny: &lt;code class=&quot;language-text&quot;&gt;typeof window !== &apos;undefined&apos;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Jeśli wspieramy starsze przeglądarki, warto przed użyciem funkcji &lt;code class=&quot;language-text&quot;&gt;localStorage&lt;/code&gt; sprawdzić, czy to API jest dostępne za pomocą warunku: &lt;code class=&quot;language-text&quot;&gt;typeof(Storage) !== &apos;undefined&apos;&lt;/code&gt;. W ten sposób unikniemy błędów w starszych przeglądarkach i strona nadal będzie w nich użyteczna.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Tworzenie prostego bota do Messengera]]></title><description><![CDATA[W Internecie pojawia się coraz więcej artykułów o nowym interfejsie, który ma zrewolucjonizować nasz sposób komunikacji z maszynami. Mowa tutaj o botach w komunikatorach. Kolejny rodzaj interfejsu, który ma upodobnić naszą komunikację z urządzeniami i usługami do komunikacji międzyludzkiej.]]></description><link>https://blog.marlas.pl/tworzenie-prostego-messenger-bota/</link><guid isPermaLink="false">https://blog.marlas.pl/tworzenie-prostego-messenger-bota/</guid><pubDate>Wed, 15 Mar 2017 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;W Internecie pojawia się coraz więcej artykułów o nowym interfejsie, który ma zrewolucjonizować nasz sposób komunikacji z maszynami. Mowa tutaj o botach w komunikatorach. Kolejny rodzaj interfejsu, który ma upodobnić naszą komunikację z urządzeniami i usługami do komunikacji międzyludzkiej.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;Wiele popularnych komunikatorów internetowych (np. Messenger, Slack, Skype, Telegram) daje nam dostęp do API komunikatorów i otwiera nam nowe możliwości do komunikacji z naszymi użytkownikami. Dodatkowo ogromna popularność tych komunikatorów pozwala nam dotrzeć do dużej liczby odbiorców.&lt;/p&gt;
&lt;p&gt;Stworzenie dobrego bota jest bardzo trudnym wyzwaniem. Wiąże się to z koniecznością prztwarzania języka naturalnego, zrozumienia komunikatów użytkownika, które są przekazane w bardzo swobodnej formie i wysłania odpowiedniej wiadomości zależnej od poprzednich wiadomości. Mimo, że stworzenie dobrego bota jest ciężkie, to rozpoczęcie przygody z tworzeniem botów jest banalnie proste.&lt;/p&gt;
&lt;p&gt;Z pomocą przychodzi nam &lt;a href=&quot;https://github.com/claudiajs/claudia-bot-builder&quot;&gt;Claudia Bot Builder&lt;/a&gt;. Ja z pomocą tego narzędzia byłem w stanie zrobić swojego bota do messengera w ciągu 10 minut. Poniżej pokaże jakie kroki trzeba wykonać, żeby stworzyć swojego pierwszego chat bota na platformę messenger. Finalny rezultat można znaleźć na &lt;a href=&quot;https://github.com/marlass/wyjazd-bot&quot;&gt;githubie&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Na początku potrzebujemy zainstalować nasze zależności.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; claudia &lt;span class=&quot;token parameter variable&quot;&gt;-g&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; claudia-bot-builder &lt;span class=&quot;token parameter variable&quot;&gt;--save&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Kolejnym krokiem jest stworzenie kodu naszego bota. Tworzę plik &lt;code class=&quot;language-text&quot;&gt;bot.js&lt;/code&gt; z następującym kodem:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; botBuilder &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;claudia-bot-builder&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

module&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;exports &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;botBuilder&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;request&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Hello world!&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Tak oto stworzyliśmy cały kod dla naszego pierwszego bota. A teraz przejdźmy do najlepszej części Claudia Bot Builder, czyli łatwgo wrzucania i konfiguracji bota. Nie będę opisywał, jak konfiguruje się dane do konta AWS lokalnie. Wszystko jest dostępne &lt;a href=&quot;https://claudiajs.com/tutorials/installing.html&quot;&gt;tutaj&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Zaczynamy od wykonania polecenia:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;claudia create &lt;span class=&quot;token parameter variable&quot;&gt;--region&lt;/span&gt; eu-central-1 --api-module bot --configure-fb-bot&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Polecenie wrzuca naszą aplikacją na AWS Lambda (w tym przypadku na serwer eu-central-1, który znajduje się w  Frankfurcie) i pozwala nam skonfigurować ją z facebookiem. Pod koniec wrzucania w konsoli dostaniemy informację o adresie url bota, jego klucz oraz zostaniemy poproszeni o token strony naszej aplikacji FB i secret.&lt;/p&gt;
&lt;p&gt;Na stronie &lt;a href=&quot;https://developers.facebook.com&quot;&gt;developers.facebook.com&lt;/a&gt; tworzymy aplikację i wybieramy jej typ jako bot messenger. Następnie w panelu aplikacji w zakładce &lt;code class=&quot;language-text&quot;&gt;Products-&gt;Messenger&lt;/code&gt; tworzymy token dla wybranej strony oraz uzupełniamy dane w sekcji &lt;code class=&quot;language-text&quot;&gt;webhook&lt;/code&gt; informacjami, które zostały zwrócone w konsoli. W terminalu wprowadzamy wygenerowany token oraz secret dostępny w panelu aplikacji pod zakładką &lt;code class=&quot;language-text&quot;&gt;Settings&lt;/code&gt;. Po wykonaniu tych kroków nasz bot jest gotowy do działania.&lt;/p&gt;
&lt;p&gt;Wchodzimy na stronę, do której pdopięliśmy bota i piszemy wiadomość. Na każdą wiadomość nasz bot powinien odpowiedzieć &lt;code class=&quot;language-text&quot;&gt;Hello world!&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Jak już mamy działającego bota to dodajmy trochę funkcjonalności. Nasz bot ma proponować listę reczy, którą mamy spakować na wyjazdy o różnej długości. Poniżej zamieszczam cały kod bota i już wyjaśniam, co za dziwne elementy tu widzimy.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; botBuilder &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;claudia-bot-builder&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; fbTemplate &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; botBuilder&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;fbTemplate&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

module&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;exports &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;botBuilder&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;request&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;request&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;type &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;facebook&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;request&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;text &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Co zabrać na wyjazd?&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; newMsg &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;fbTemplate&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;Na jak długo wyjeżdżasz?&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
            
            &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; newMsg
            &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addQuickReply&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;1 dzień&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;1 dzień&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addQuickReply&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;3-4 dni&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;3-4 dni&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addQuickReply&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;tydzień&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;tydzień&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addQuickReply&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;2 tygodnie&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;2 tygodnie&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addQuickReply&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;miesiąc&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;miesiąc&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addQuickReply&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;&gt; niż miesiąc&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;&gt; niż miesiąc&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;request&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;text &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;1 dzień&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;przeżyjesz bez niczego :P&apos;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;request&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;text &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;3-4 dni&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;zabierz 4 koszulki,\nspodnie,\nładowarkę do telefonu,\nbieliznę,\nkosmetyczkę,\nbatony&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;request&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;text &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;tydzień&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;weź kilka koszulek,\n2 pary spodni,\nbieliznę,\nszampon,\nszczoteczkę,\npastę do zębów,\nżel pod prysznic,\nręczniki,\nsłodycze,\n 🐱&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;request&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;text &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;2 tygodnie&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;przykro mi, jak wyjeżdżasz na 2 tygodnie to sobie znajdź inne źródła wiadomości z informacjami co trzeba spakować. Hue hue.&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;request&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;text &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;miesiąc&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;fbTemplate&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Generic&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addBubble&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;Kompletna lista do spakowania&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Na tej stronie znajdziesz bardzo szczegółową listę rzeczy do spakowania.&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addButton&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;Kompletna lista&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;http://kropkinamapie.pl/zabrac-gory-morze-wakacje-wyjazd-check-lista.html&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addButton&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;Inna fajna lista&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;http://podrozniczo.pl/10-rzeczy-ktore-warto-zabrac-ze-soba-w-podroz/&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addButton&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;Dzięki&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Dzięki&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;request&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;text &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;&gt; niż miesiąc&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;kup tam mieszkanie,\nwszystko kup na miejscu,\nnie zapomnij wziąć pieniędzy,\nweź jeszcze więcej pieniędzy.\nTo wszystko.&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;request&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;text &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Dzięki&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt; request&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;text &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;dzięki&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt; request&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;text &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;thx&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt; request&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;text &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Dziękuję&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Proszę. Taka moja praca :)&apos;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Żeby rozpocząć zadaj mi pytanie: Co zabrać na wyjazd?&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Na samej górze funkcji owijam wszystko w warunek &lt;code class=&quot;language-text&quot;&gt;request.type === &apos;facebook&apos;&lt;/code&gt;. Jako, że Claudia pozwala nam tworzyć jeden kod na wiele różnych komunikatór jednocześnie musimy specjalne funkcjonalności chatów oferować tylko odpowiednim komunikatorom. Mój bot ma działać tylko na platformie messenger, przez co korzystam z bardziej zaawansowanych elementów, takich jak szybkie odpowiedzi, czy szablony. Kolejnym atrybutem zmiennej &lt;code class=&quot;language-text&quot;&gt;request&lt;/code&gt; jest &lt;code class=&quot;language-text&quot;&gt;text&lt;/code&gt; i to właśnie w tym atrybucie dostajemy wiadomość wysłaną nam przez użytkownika. Mój bot w przypadku pytania &apos;Co zabrać na wyjazd?&apos; zaoferuje kilka szybkich odpowiedzi, dla których zostały przygotowane listy.&lt;/p&gt;
&lt;p&gt;W moim przykładzie użyłem specjalnych funkcjonalności messengera, czyli szybkich odpowiedzi i szablonów. Dokładna specyfikacja tych funkcji jest dostępna na stronie &lt;a href=&quot;https://github.com/claudiajs/claudia-bot-builder/blob/master/docs/FB_TEMPLATE_MESSAGE_BUILDER.md#list-template&quot;&gt;dokumentacji claudia-bot-buildera&lt;/a&gt;. Te funkcjonalności pozwalają nam na większą kontrolę komunikacji z użytkownikiem. Oferując mu szybkie odpowiedzi możemy dostawać zdefiniowane przez nas komunikaty, a nie odpowiadać na literówki wiadomością &lt;code class=&quot;language-text&quot;&gt;Nie rozumiem. W czym mogę pomóc?&lt;/code&gt;. Szablony natomiast pozwalają nam przekazać dużo opcji użytkownikowi i pokazanie bardziej multimedialnych komunikatów. Możemy wysyłać załączniki, wiadomości audio, filmy, zdjęcia, linki, a nawet paragony. Bardzo polecam korzystanie z tych elementów, bo jest to jeden z prostszych sposobów, których możemy użyć, żeby nasz bot pomagał użytkowikowi wykonać zadanie, a nie go frustrować.&lt;/p&gt;
&lt;p&gt;Zapraszam wszystkich do eksperymentowania z chat botami, bo start naprawdę jest bardzo szybki i łatwy, a można znaleźć do nich kilka bardzo fajnych zastosowań.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Testowanie komponentów prezentacyjnych]]></title><description><![CDATA[Po skonfigurowaniu wszystkiego zaczynam dzisiaj właściwe prace nad projektem. Na początku zaczynam od prostego formularza do dodawania zadania i wyświetlania listy zadań. Następnym krokiem będzie możliwość edycji, usuwania zadań i filtrowania listy. Po skończeniu tego zajmę się trochę częścią serwerową, żeby nasze zadania były zapamiętywane na dłużej niż jedno wyświetlenie strony. Ale przejdźmy do dzisiejszego tematu - testowania.]]></description><link>https://blog.marlas.pl/testowanie-komponentow-prezentacyjnych/</link><guid isPermaLink="false">https://blog.marlas.pl/testowanie-komponentow-prezentacyjnych/</guid><pubDate>Sat, 11 Mar 2017 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Po skonfigurowaniu wszystkiego zaczynam dzisiaj właściwe prace nad projektem. Na początku zaczynam od prostego formularza do dodawania zadania i wyświetlania listy zadań. Następnym krokiem będzie możliwość edycji, usuwania zadań i filtrowania listy. Po skończeniu tego zajmę się trochę częścią serwerową, żeby nasze zadania były zapamiętywane na dłużej niż jedno wyświetlenie strony. Ale przejdźmy do dzisiejszego tematu - testowania.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;W momencie pisania tego posta w aplikacji są dwa kontenery (komponenty, które są powiązane z stanem aplikacji) i jeden bardzo prosty komponent prezentacyjny. Komponent prezentacyjny jest natomiast funkcją. Komponent prezentacyjny nie ma własnego stanu i korzysta jedynie z przekazanych atrybutów. Jako, że te komponenty są bardzo proste, to stwierdziłem, że są dobrym miejscem na start z pisaniem testów jednostkowych.&lt;/p&gt;
&lt;p&gt;W projekcie mam skonfigurowany framework do testów &lt;a href=&quot;https://mochajs.org/&quot;&gt;mocha&lt;/a&gt; i jest uruchamiany z pomocą &lt;a href=&quot;https://karma-runner.github.io/1.0/index.html&quot;&gt;Karmy&lt;/a&gt;. Odpalam polecenie &lt;code class=&quot;language-text&quot;&gt;npm run test:watch&lt;/code&gt; i wszystkie moje testy są odpalane za każdym razem, gdy zmieniamy kod aplikacji lub testy.&lt;/p&gt;
&lt;p&gt;Pliki testów przechowuję w folderze &lt;code class=&quot;language-text&quot;&gt;/app/tests&lt;/code&gt; z rozszerzeniem &lt;code class=&quot;language-text&quot;&gt;-test.jsx&lt;/code&gt;. Poniżej zamieszczam kod testu do komponentu wyświetlania pojedynczego todo.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; React &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;react&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; shallow &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;enzyme&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; expect &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;chai&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; TodoItem &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./../components/todo-item.jsx&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token function&quot;&gt;describe&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;&amp;lt;TodoItem/&gt;&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;should have an li with todo&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; wrapper &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;shallow&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;TodoItem&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;Hey&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;TodoItem&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;expect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;wrapper&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;find&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;li&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;to&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;have&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token function&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;should have an li with class todo-item&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; wrapper &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;shallow&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;TodoItem&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;Hej&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;TodoItem&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;expect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;wrapper&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;find&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;li&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;props&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;className&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;to&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;include&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;todo-item&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token function&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;should render a children&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; wrapper &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;shallow&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;TodoItem&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;span&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;Hey&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;span&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;TodoItem&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;expect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;wrapper&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;contains&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;span&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;Hey&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;span&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;to&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;equal&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Przy pisaniu testów oprócz frameworka Mocha i Karmy używam jeszcze biblioteki do asercji &lt;a href=&quot;http://chaijs.com/&quot;&gt;Chai&lt;/a&gt; oraz bibliotekę do testowania komponentów &lt;a href=&quot;http://airbnb.io/enzyme/&quot;&gt;enzyme&lt;/a&gt; stworzoną przez Airbnb.&lt;/p&gt;
&lt;p&gt;Mi bardzo odpowiada sposób asercji w stylu BDD, ale biblioteka Chai pozwala również na pisanie asercji w klasycznym sposobie (np. &lt;code class=&quot;language-text&quot;&gt;assert(&apos;foo&apos; !== &apos;bar&apos;, &apos;foo is not bar&apos;);&lt;/code&gt;). Styl BDD mnie przekonał, bo testy z takimi asercjami czyta się jak zwykłe zdania. Dla mnie właśnie takie asercje BDD są najbardziej zbliżonym kodem do języka naturalnego. Czyta się je bardzo szybko i nie trzeba się zastanawiać co otrzymujemy.&lt;/p&gt;
&lt;p&gt;Biblioteka enzyme natomiast bardzo pomaga testować pojedyńcze komponenty w izolacji. Do biblioteki React jest dodatkowa biblioteka wspomająca testowanie &lt;a href=&quot;https://facebook.github.io/react/docs/test-utils.html&quot;&gt;React Test Utilities&lt;/a&gt;, ale ze względu na łatwe użycie pozostałem przy enzyme. Biblioteka oferujemy nam 3 główne metody &lt;code class=&quot;language-text&quot;&gt;shallow&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;mount&lt;/code&gt; i &lt;code class=&quot;language-text&quot;&gt;render&lt;/code&gt;. W &lt;a href=&quot;http://airbnb.io/enzyme/docs/api/index.html&quot;&gt;dokumentacji&lt;/a&gt; metody są bardzo dobrze opisane i przedstawione są przypadki użycia każdej z nich. Do testowania komponentów prezentacyjnych najczęściej używa się funkcji &lt;code class=&quot;language-text&quot;&gt;shallow&lt;/code&gt; oraz &lt;code class=&quot;language-text&quot;&gt;render&lt;/code&gt;. Każda funkcja zwraca nam obiekty odpowiedniego typy. Dla metody &lt;code class=&quot;language-text&quot;&gt;shallow&lt;/code&gt; dostajemy objekty typu &lt;code class=&quot;language-text&quot;&gt;ShallowWrapper&lt;/code&gt;, które oferują nam mnóstwo przydatnych funkcji. W moich testach wykorzystywałem tylko metod &lt;code class=&quot;language-text&quot;&gt;find&lt;/code&gt; i &lt;code class=&quot;language-text&quot;&gt;contains&lt;/code&gt;, ale pewnie inne funkcje do moich przypadków testowych nadają się lepiej.&lt;/p&gt;
&lt;p&gt;Pisanie testów z wykorzystaniem tych dwóch bibliotek jest bardzo proste i przyjemne, ale to dopiero początek mojej drogi z pisaniem testów jednostkowych. Teraz zostało mi poznawanie innych funkcji tych bibliotek i znajdowanie odpowiednich zastosowań dla nich, by kod był jeszcze bardziej zrozumiały i prosty w utrzymaniu.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Serverless]]></title><description><![CDATA[Dzisiaj zamiast postu o projekcie opowiem trochę o czymś takim, co określa się jako "serverless". Od jakiegoś czasu natrafiam na to pojęcie w Internecie, a ostatnio miałem również okazję usłyszeć prezentację Michała Kurzeji na konferencji "Boiling Frogs". Opiszę dzisiaj moje spostrzeżenia na ten temat i jak wyglądało moje pierwsze starcie z "serverless".]]></description><link>https://blog.marlas.pl/serverless/</link><guid isPermaLink="false">https://blog.marlas.pl/serverless/</guid><pubDate>Wed, 08 Mar 2017 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Dzisiaj zamiast postu o projekcie opowiem trochę o czymś takim, co określa się jako &quot;serverless&quot;. Od jakiegoś czasu natrafiam na to pojęcie w Internecie, a ostatnio miałem również okazję usłyszeć prezentację Michała Kurzeji na konferencji &quot;Boiling Frogs&quot;. Opiszę dzisiaj moje spostrzeżenia na ten temat i jak wyglądało moje pierwsze starcie z &quot;serverless&quot;.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;Pierwszy raz spotkałem się z tym pojęciem w &lt;a href=&quot;https://www.smashingmagazine.com/2016/10/how-to-develop-a-chat-bot-with-node-js/&quot;&gt;artykule o pisaniu chat botów w node.js&lt;/a&gt; na Smashing Magazine. Pojawiło się pojęcie Lambdy - usługi Amazonu opierającej całe swoje działanie na wrzucaniu swojej aplikacji jako funkcji, która może być dynamicznie uruchamiana, gdy jej potrzebujemy. Wokół tego opiera się cały model płatności, gdzie płacimy tylko za wykonywanie funkcji, a czas bezczynności jest bezpłatny. Brzmi to bardzo dobrze, gdy tworzymy usługi, które czasem mogą być używane przez ogromną liczbę osób, a czasem stoją bezczynne(AWS Lambda odpowiada również za skalowanie, żeby funkcja była stanie obsłużyć duży ruch). Dla przykładu obsługa 2 mln wywołań funkcji kosztuje nas około 0.20$. Pierwszy 1mln wywołań w miesiącu jest za darmo. Dokładny cennik jest przedstawiony &lt;a href=&quot;https://aws.amazon.com/lambda/pricing/&quot;&gt;tutaj&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Przy prostych aplikacjach na własny użytek nie ma prawie szans, żeby wykorzystać bezpłatny limit. Po wstępnym entuzjaźmie co do tej usługi zacząłem się zastanawiać, a gdzie w takim razie mam przechować wszystkie dane, gdzie mam przechowywać pliki? Przez te wątpliwości przestałem się interesować tematem i widziałem zastosowanie tego tylko w prostych przypadkach, takich jak chat boty i proste bezstanowe usługi do przetwarzania danych.&lt;/p&gt;
&lt;p&gt;Po długiej przerwie temat powrócił na konferencji &quot;Boiling Frogs&quot;. Prezentacja odpowiedziała na moje poprzednie wątpliwości i teraz dopiero zrozumiałem, że &quot;serverless&quot; nie opiera się tylko i wyłącznie na AWS Lambda. Całe podejście &quot;serverless&quot; to nie korzystanie z jednej usługi, a całego ekosystemu usług przystosowanego do współpracy między sobą. Aktualnie najpopularniejszy taki ekosystem ma Amazon. Gdy potrzebujemy korzystać z bazy danych do Lambdy podpinamy DynamoDB, potrzebujemy przechowywać pliki - używamy Simple Storage Service, nazywanego S3. Nasze funkcje chcemy udostępnić jako API - korzystamy z API Gateway. Ekosystem jest tak rozbudowany, że każdy rzeczywisty przypadek, ktory powinien obsługiwać nasz serwer może być zrealizowany za pomocą odpowiedniego łączenia wszystkich narzędzi.&lt;/p&gt;
&lt;p&gt;Postanowiłem trochę pobawić się tym ekosystemem z wykorzystaniem frameworka &lt;a href=&quot;https://serverless.com/&quot;&gt;serverless&lt;/a&gt;. Pierwsze spotkanie było bardzo przyjemne. Po założeniu konta na AWS po 10 minutach byłem w stanie zobaczyć w przeglądarce &lt;code class=&quot;language-text&quot;&gt;Hello World&lt;/code&gt; wysłane z serwera w Frankfurcie. Dodanie kolejnych funkcji i podpięcie ich pod konkretne adresy url jest bardzo proste. Wszystko opiera się na zmianie konfiguracji w pliku &lt;code class=&quot;language-text&quot;&gt;serverless.yml&lt;/code&gt; i zrobieniu deploya. Przy zmianie konfiguracji deploy chwilkę trwa, ale jeśli tylko aktualizujemy konkretną funkcję, zmiana jest błyskawiczna. Korzystanie z API Gateway nie mogło być prostsze.&lt;/p&gt;
&lt;p&gt;Potem postanowiłem zrobić przykładowe API z zapisywaniem elementu do bazy i wyświetlaniem rekordów. Samo podpięcie dynamoDB nie jest ciężkie i API jest dostępne w przeglądarce, natomiast dostawałem błędy związane z uprawnieniami mojej funkcji do bazy danych. Walczyłem z tych 30 minut, ale bezskutecznie. Na tym zakończę opis moich dzisiejszych doświadczeń. Widzę duży potencjał w tym podejściu do budowania i hostowania aplikacji. Taka architektura wymaga na nas myślenie o usługach w bardziej granualny sposób i dobrze łączy się z mikro usługami. W najbliższym czasie będę jeszcze eksperymentował z &quot;serverless&quot; i postaram sie zintegrować z dynamoDB, S3 i zrobić jakąś użyteczną apkę.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Kilka słów o konfiguracji projektu]]></title><description><![CDATA[W pierwszym poście opisywałem trochę narzędzia z których będę korzystał przy robieniu tego projektu. Postaram się teraz trochę bardziej opisać cały stos technologiczny projektu.]]></description><link>https://blog.marlas.pl/kilka-slow-o-konfiguracji/</link><guid isPermaLink="false">https://blog.marlas.pl/kilka-slow-o-konfiguracji/</guid><pubDate>Sun, 05 Mar 2017 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;W pierwszym poście opisywałem trochę narzędzia z których będę korzystał przy robieniu tego projektu. Postaram się teraz trochę bardziej opisać cały stos technologiczny projektu.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;Chcąc uniknąć tworzenia całej konfiguracji od początku postanowiłem skorzystać z &lt;a href=&quot;http://andrewhfarmer.com/starter-project/&quot;&gt;wyszukiwarki projektów startowych&lt;/a&gt; React. Chciałem stworzyć sobie bardzo przyjemne środowisko do pracy. Wsród moich wymagań były: hot module replacement, możliwość korzystania z ES6, renderowanie po stronie serwera, przygotowany linter i framework do testów oraz już zintegrowany redux i react router. Szukając po tych wymaganiach znalazłem &lt;a href=&quot;https://github.com/reactGo/reactGo&quot;&gt;reactGo&lt;/a&gt;. Projekt ma ponad 2 tysiące gwiazdek na githubie, przez co zaufałem społeczności, że ten projekt będzie prosty do konfiguracji i będzie usprawniał pracę.&lt;/p&gt;
&lt;p&gt;Instalacja jest bardzo prosta. Po prostu sobie klonujemy projekt lub pobieramy archiwum. Potem już w folderze projektu wykonujemy &lt;code class=&quot;language-text&quot;&gt;npm install&lt;/code&gt; i wszystkie wymagane zależności są zainstalowane. W projekcie jest przygotowanych kilka skryptów do budowy, testów, lintowania i do pracy. Po odpaleniu &lt;code class=&quot;language-text&quot;&gt;npm run dev&lt;/code&gt; pod adresem &lt;code class=&quot;language-text&quot;&gt;localhost:3000&lt;/code&gt; widzimy już przykładowy projekt nad którym możemy pracować.&lt;/p&gt;
&lt;p&gt;Teraz zaczyna się trudniejsza część konfigurowania projektu. Usunięcie wszystkich rzeczy, których nie potrzebujemy, żeby móc zacząć budować właściwą aplikację. W projekcie jest już przygotowany routing, logowanie z użyciem Google i przykładowe komponenty z stylami. Postanowiłem wyrzucić to wszystko i rozpocząć od zrobienia prostego &lt;code class=&quot;language-text&quot;&gt;Hello world&lt;/code&gt;.  Po godzinie walki z częścią serwerową i frontową wyrzuciłem wszystkie nieistotne pliki i zakończyłem na prostej aplikacji z jedną stroną i napisem &lt;code class=&quot;language-text&quot;&gt;Hello world&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Początkowo planowałem skorzystać z SASS przy pisaniu CSS, natomiast projekt jest skonfigurowany do użycia modułów css i składni cssnext. Spróbuję zostać przy tej konfiguracji i nauczyć się przyszłościowej składni css i integrowania styli do komponentów zamiast pisania globalnych styli. Minusem może być flash strony bez styli przy renderowaniu serwerowym, ale może jeśli zostanie czasu to postaram się to naprawić.&lt;/p&gt;
&lt;p&gt;W następnym poście opiszę prace nad pierwszą funkcjonalnością, a w międzyczasie lista blogów znajomych do odwiedzenia:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://inkoguto.github.io/&quot;&gt;Andrzej Pawcenis&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/dravek99/daj-sie-poznac&quot;&gt;Filip Rakowski&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://iwona.giat.pl/&quot;&gt;Iwona Jóźwiak&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.lmarszalek.pl/blog/&quot;&gt;Łukasz Marszałek&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://maciej-danilowicz.pl/&quot;&gt;Maciej Daniłowicz&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://marcin-kwiatkowski.com/&quot;&gt;Marcin Kwiatkowski&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://rmakara.github.io/&quot;&gt;Rafał Makara&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Rozpoczynam "Daj się poznać 2017"]]></title><description><![CDATA[Rozpoczyna się miesiąc marzec i zaczynam wyzwanie "Daj się poznać 2017". Całe to wyzwanie polega na rozwijaniu projektu open source przez 10 tygodni i jednoczesne pisanie na blogu 2 postów tygodniowo. Przynajmniej jeden post w tygodniu musi być poświęcony rozwijanemu oprogramowaniu. Drugi post może dotyczyć dowolnych zagadnieć związanych z branżą IT.]]></description><link>https://blog.marlas.pl/rozpoczynam-daj-sie-poznac/</link><guid isPermaLink="false">https://blog.marlas.pl/rozpoczynam-daj-sie-poznac/</guid><pubDate>Wed, 01 Mar 2017 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Rozpoczyna się miesiąc marzec i zaczynam wyzwanie &quot;Daj się poznać 2017&quot;. Całe to wyzwanie polega na rozwijaniu projektu open source przez 10 tygodni i jednoczesne pisanie na blogu 2 postów tygodniowo. Przynajmniej jeden post w tygodniu musi być poświęcony rozwijanemu oprogramowaniu. Drugi post może dotyczyć dowolnych zagadnieć związanych z branżą IT.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;&lt;img src=&quot;/dsp2017-1@2x.png&quot; alt=&quot;Daj się poznać 2017&quot;&gt;&lt;/p&gt;
&lt;p&gt;O konkursie dowiedziałem się od kolegi z pracy, który też podjął wyzwanie. Informacja rozniosła się po firmie i tak do udziału zgłosiło się jeszcze kilka osób. W następnym poście wrzucę linki do blogów wszystkich pracowników &lt;a href=&quot;https://divante.pl/&quot;&gt;Divante&lt;/a&gt;, którzy również biorą udział w &quot;Daj się poznać 2017&quot;.&lt;/p&gt;
&lt;p&gt;Więcej o &lt;a href=&quot;http://devstyle.pl/daj-sie-poznac/&quot;&gt;Daj się poznać&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Motywacja&lt;/h2&gt;
&lt;p&gt;Od jakiegoś czasu chciałem wykonać aplikację, którą będę teraz realizować w ramach tego konkursu. Dodatkowo ostatnio interesuję się React.js i chciałem zrealizować projekt w tej technologii. Spodobała mi się idea tego konkursu i postanowiłem w końcu zabrać się za tę aplikację. Dodatkowe wymaganie pisania o projekcie na blogu pozwoli mi również podszlifować moje umiejętności pisarskie i jednocześnie &quot;Dam się poznać&quot; w Internecie. Liczę na to, że to wyzwanie będzie motywować mnie do regularnej pracy nad projektem i dotrwam do samego końca.&lt;/p&gt;
&lt;h2&gt;Projekt&lt;/h2&gt;
&lt;p&gt;Aplikacja ma wspomagać organizację życia i motywować do pracy nad sobą przez wykorzystywanie technik grywalizacji. Na początku zakładam możliwość organizacji wszystkich spraw, które wykonujemy codziennie. Zarządzanie swoją listą zajęć z uwzględeniem wag każdego zadania. Dla przykładu: za zrobienie zakupów dostaniemy 5 punktów, natomiast za oglądanie TV przez 2 godziny stracimy 12 punktów. Z czasem punkty mogą zostać rozbite na rodzaje (punkty za działania poprawiajace zdrowie fizyczne, inne punkty za rozwój kulturowy, intelektualny itp.). W planach jest również możliwość rejestracji czasu spędzanego na poszczególnych zadaniach, żeby stać się bardziej świadomymi tego, gdzie nam &quot;czas ucieka&quot;.&lt;/p&gt;
&lt;p&gt;Bazowym celem jest organizacja zadań i codziennych czynności, a po osiągnięciu tego celu będę dorzucać następne wymagania. Liczę na osiągnięcie głównego celu po około 6-7 tygodniach i wtedy będę miał jeszcze czas na dalsze usprawnienia projektu i zwiększaniu jego funkcjonalności.&lt;/p&gt;
&lt;h2&gt;Technologia&lt;/h2&gt;
&lt;p&gt;Projekt będzie realizowany w React.js i Redux po stronie frontu. Backend planuję wykonać na Node.js z frameworkiem Express.js z użyciem bazy MongoDB. Chciałem ten projekt szybko zacząć, przez co skorzystałem z &lt;a href=&quot;https://github.com/reactGo/reactGo&quot;&gt;reactGo&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Uwielbiam zawsze przy rozpoczynaniu projektu wybierać sobie stos technologiczny, konfigurować wszystkie narzędzia, ale w tym projekcie chcę jak najwięcej czasu spędzić na rzeczywistym programowaniu i pracy z React.js. Jestem trochę &quot;uzależniony&quot; od narzędzi i ten projekt będzie takim lekkim detoksem od konfiguracji. Może po zakończeniu wyzwania napiszę parę wpisów o konfiguracji webpack i docker, ale teraz zamierzam mieć działający pierwszy widok w przyszłym tygodniu.&lt;/p&gt;
&lt;p&gt;Przy tym projekcie chcę również podszlifować pisanie testów i spróbuję przekonać się do TDD. Zobaczę jak w moim przypadku działa te podejście, czy rzeczywiście oprogramowanie będzie miało lepszą architekturę i będzie bardziej stabilne.&lt;/p&gt;
&lt;p&gt;Plany są duże i zobaczymy, czy udaje się je zrealizować. W następnym poście myślę, że pojawi się już trochę kodu i opowiem trochę więcej o środowisku pracy.&lt;/p&gt;</content:encoded></item></channel></rss>