<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet href="/feed.xsl" type="text/xsl"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xml:base="https://zenzes.me/" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Daniel Zenzes Blog</title>
    <link>https://zenzes.me/</link>
    <atom:link href="https://zenzes.me/feed.xml" rel="self" type="application/rss+xml"/>
    <description>Daniel Zenzes on current topics from IT and his experiences as a software crafter.</description>
    <language>en</language>
      <item>
        <title>From Ghostty to Kitty: My Terminal Configuration</title>
        <link>https://zenzes.me/from-ghostty-to-kitty-my-terminal-configuration/</link>
        <description>&lt;p&gt;Last year I wrote about &lt;a href=&quot;https://zenzes.me/new-hardware-and-software-in-january/&quot;&gt;switching from iTerm2 to Ghostty&lt;/a&gt;. Ghostty worked well overall, but after a while I noticed it was draining my MacBook battery more than I&#39;d like — even when sitting idle. So I decided to evaluate &lt;a href=&quot;https://sw.kovidgoyal.net/kitty/&quot;&gt;Kitty&lt;/a&gt; as an alternative.&lt;/p&gt;
&lt;h2 id=&quot;installation&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://zenzes.me/from-ghostty-to-kitty-my-terminal-configuration/#installation&quot;&gt;Installation&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;There are a few ways to get Kitty on macOS.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Via curl&lt;/strong&gt; (the official installer):&lt;/p&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;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-L&lt;/span&gt; https://sw.kovidgoyal.net/kitty/installer.sh &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;sh&lt;/span&gt; /dev/stdin&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Via Homebrew&lt;/strong&gt;:&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;brew &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;--cask&lt;/span&gt; kitty&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I manage my system configuration with &lt;a href=&quot;https://github.com/LnL7/nix-darwin&quot;&gt;nix-darwin&lt;/a&gt; and &lt;a href=&quot;https://github.com/nix-community/home-manager&quot;&gt;Home Manager&lt;/a&gt;, so for me it was just a matter of enabling &lt;code&gt;programs.kitty&lt;/code&gt; in my Home Manager config. If you use nix-darwin, that&#39;s the path I&#39;d recommend.&lt;/p&gt;
&lt;h2 id=&quot;configuration&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://zenzes.me/from-ghostty-to-kitty-my-terminal-configuration/#configuration&quot;&gt;Configuration&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Kitty is configured via a plain text file at &lt;code&gt;~/.config/kitty/kitty.conf&lt;/code&gt;. Here is my complete config:&lt;/p&gt;
&lt;pre class=&quot;language-conf&quot;&gt;&lt;code class=&quot;language-conf&quot;&gt;font_family      JetBrainsMono Nerd Font
bold_font        JetBrainsMono Nerd Font Bold
italic_font      JetBrainsMono Nerd Font Italic
bold_italic_font JetBrainsMono Nerd Font Bold Italic
font_size        14.0

# Window
window_padding_width    12
background_opacity      0.95
hide_window_decorations no

# Cursor
cursor_shape          beam
cursor_blink_interval 0.5

# Tab bar
tab_bar_style       powerline
tab_bar_edge        bottom
tab_powerline_style round

# Scrollback
scrollback_lines              10000
scrollback_pager_history_size 100

# macOS
macos_option_as_alt right

# Catppuccin Mocha
background           #1e1e2e
foreground           #cdd6f4
selection_background #585b70
selection_foreground #cdd6f4
url_color            #f5e0dc
cursor               #f5e0dc
cursor_text_color    #1e1e2e

active_border_color   #b4befe
inactive_border_color #6c7086
bell_border_color     #f9e2af

wayland_titlebar_color #1e1e2e
macos_titlebar_color   #1e1e2e

active_tab_foreground   #11111b
active_tab_background   #cba6f7
inactive_tab_foreground #cdd6f4
inactive_tab_background #181825
tab_bar_background      #11111b
tab_bar_margin_color    #11111b

color0  #45475a
color1  #f38ba8
color2  #a6e3a1
color3  #f9e2af
color4  #89b4fa
color5  #f5c2e7
color6  #94e2d5
color7  #bac2de
color8  #585b70
color9  #f38ba8
color10 #a6e3a1
color11 #f9e2af
color12 #89b4fa
color13 #f5c2e7
color14 #94e2d5
color15 #a6adc8

# Keybindings
map super+left  previous_tab
map super+right next_tab
map super+1     goto_tab 1
map super+2     goto_tab 2
map super+3     goto_tab 3
map super+4     goto_tab 4
map super+5     goto_tab 5
map super+6     goto_tab 6
map super+7     goto_tab 7
map super+8     goto_tab 8
map super+9     goto_tab 9&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;what-each-section-does&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://zenzes.me/from-ghostty-to-kitty-my-terminal-configuration/#what-each-section-does&quot;&gt;What each section does&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Font&lt;/strong&gt; — I use &lt;a href=&quot;https://www.jetbrains.com/lp/mono/&quot;&gt;JetBrains Mono&lt;/a&gt; in the Nerd Font variant, which includes the icon glyphs needed for tools like Starship or NeoVim plugins. Explicitly setting the bold and italic variants avoids any font synthesis artifacts.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Window&lt;/strong&gt; — A &lt;code&gt;window_padding_width&lt;/code&gt; of 12 gives the terminal some breathing room. &lt;code&gt;background_opacity&lt;/code&gt; at 0.95 lets the desktop bleed through slightly, which I find easier on the eyes than a fully opaque window. &lt;code&gt;hide_window_decorations no&lt;/code&gt; keeps the standard macOS title bar so the window still behaves normally when tiling.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Cursor&lt;/strong&gt; — The &lt;code&gt;beam&lt;/code&gt; shape feels more precise than the default block cursor. A &lt;code&gt;cursor_blink_interval&lt;/code&gt; of 0.5 seconds is fast enough to stay visible without being distracting.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Tab bar&lt;/strong&gt; — &lt;code&gt;powerline&lt;/code&gt; style with &lt;code&gt;round&lt;/code&gt; separators at the bottom of the window. The tab bar sits below the content rather than above, which keeps it out of the way during normal use. The colors are driven entirely by the Catppuccin Mocha palette below, so active and inactive tabs are immediately distinguishable.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Scrollback&lt;/strong&gt; — 10,000 lines covers most debugging sessions. The &lt;code&gt;scrollback_pager_history_size&lt;/code&gt; (in MB) allows the pager to handle long outputs without truncating.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;macOS specifics&lt;/strong&gt; — &lt;code&gt;macos_option_as_alt right&lt;/code&gt; makes only the right Option key behave as Alt, which is essential for shell shortcuts like &lt;code&gt;alt+b&lt;/code&gt; / &lt;code&gt;alt+f&lt;/code&gt; for word-by-word cursor movement in zsh. The left Option key keeps its macOS behaviour, so you can still type special characters like &lt;code&gt;@&lt;/code&gt; or &lt;code&gt;€&lt;/code&gt; with it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Colors&lt;/strong&gt; — I use the &lt;a href=&quot;https://github.com/catppuccin/kitty&quot;&gt;Catppuccin Mocha&lt;/a&gt; theme. The dark &lt;code&gt;#1e1e2e&lt;/code&gt; background with the muted purple and teal accents is easy to look at for long sessions. Matching the title bar color (&lt;code&gt;macos_titlebar_color&lt;/code&gt;) to the terminal background makes the window feel cohesive rather than bolted together.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Keybindings&lt;/strong&gt; — &lt;code&gt;super+left&lt;/code&gt; / &lt;code&gt;super+right&lt;/code&gt; to cycle tabs, and &lt;code&gt;super+1&lt;/code&gt; through &lt;code&gt;super+9&lt;/code&gt; to jump directly to a numbered tab. This mirrors how most browsers handle tab navigation, so it feels natural.&lt;/p&gt;
&lt;h2 id=&quot;first-impressions&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://zenzes.me/from-ghostty-to-kitty-my-terminal-configuration/#first-impressions&quot;&gt;First impressions&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;So far the battery life looks noticeably better. The configuration format is more verbose than Ghostty&#39;s, but everything is clearly documented and the result is exactly what I was looking for. I&#39;ll report back once I&#39;ve spent more time with it.&lt;/p&gt;
</description>
        <pubDate>Mon, 18 May 2026 11:00:00 +0200</pubDate>
        <dc:creator>Daniel Zenzes</dc:creator>
        <guid>https://zenzes.me/from-ghostty-to-kitty-my-terminal-configuration/</guid>
      </item>
      <item>
        <title>On AI in coding</title>
        <link>https://zenzes.me/on-ai-in-coding/</link>
        <description>&lt;blockquote&gt;
&lt;p&gt;&amp;quot;But is the code correct?&amp;quot; He asked. And this, dear reader, is where the hard truth hit me. Jhey looked at the ChatGPT output. It had gifted me 5 lines of completely unnecessary code, and another bit was &amp;quot;fine&amp;quot; but not the most efficient way to write JavaScript. He made a few edits for me and left me to continue on with my CSS overhaul. -- &lt;cite&gt;&lt;a href=&quot;https://blog.stephaniestimac.com/posts/2025/02/thoughts-on-ai-slop-coding/#:~:text=%22But%20is%20the,my%20CSS%20overhaul.&quot;&gt;The Web Witch&#39;s Blog&lt;/a&gt;&lt;/cite&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;A few weeks ago, it took my colleague and me hours to find all the bugs that AI introduced into an application simply because someone had written code in a language and framework they were unfamiliar with.&lt;/p&gt;
&lt;p&gt;I often use AI for development tasks, and it can be very useful - for example, when you need to apply similar changes to multiple files or when you want to improve your code style (&amp;quot;Tell me how this code can be written in a more readable way...&amp;quot;). However, AI can also produce a mess when you use it for something with which you have no experience. It&#39;s like working with a a new colleague who can be brilliant at times but would rather say something than admit that they can’t solve a problem. If AI only supports you on a topic you are familiar with, it will improve your speed and perhaps even the quality of your work. Maybe you can even learn how to improve the structure of your code or write that one specific test. If you have no experience with the topic you&#39;re working on, it can produce bugs and poor code; in the end, just copying and pasting code you don&#39;t understand won&#39;t make you a better programmer.&lt;/p&gt;
&lt;p&gt;via &lt;a href=&quot;https://blog.stephaniestimac.com/posts/2025/02/thoughts-on-ai-slop-coding/&quot;&gt;Stephanie Stimac&lt;/a&gt;&lt;/p&gt;
</description>
        <pubDate>Mon, 10 Feb 2025 09:27:00 +0100</pubDate>
        <dc:creator>Daniel Zenzes</dc:creator>
        <guid>https://zenzes.me/on-ai-in-coding/</guid>
      </item>
      <item>
        <title>TIL: One file to rule them all: PEP-723 and uv</title>
        <link>https://zenzes.me/til-one-file-to-rule-them-all-pep-723-and-uv/</link>
        <description>&lt;p&gt;It&#39;s impressive what’s possible with Python nowadays! &lt;a href=&quot;https://peps.python.org/pep-0723/&quot;&gt;PEP-723&lt;/a&gt; introduces a way to define metadata directly inside a Python file — including dependencies.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;quot;This PEP specifies a metadata format that can be embedded in single-file Python scripts to assist launchers, IDEs and other external tools which may need to interact with such scripts.&amp;quot;&lt;br /&gt;
— &lt;a href=&quot;https://peps.python.org/pep-0723/&quot;&gt;PEP 723 – Inline script metadata&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;code&gt;uv&lt;/code&gt; takes this a step further by handling virtual environments and dependencies seamlessly when executing such scripts.&lt;/p&gt;
&lt;p&gt;For example, if you want to spin up a Flask server in &lt;strong&gt;one&lt;/strong&gt; file, it looks like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# /// script
# requires-python = &amp;quot;&amp;gt;=3.12&amp;quot;
# dependencies = [
#   &amp;quot;flask&amp;quot;,
# ]
# ///
from flask import Flask

app = Flask(__name__)

@app.route(&amp;quot;/&amp;quot;)
def home():
    return &amp;quot;Hello, World! 🚀&amp;quot;

if __name__ == &amp;quot;__main__&amp;quot;:
    app.run(debug=True)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Save this file as &lt;code&gt;server.py&lt;/code&gt; and run it with:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;uv run server.py
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Within seconds, the server is up and running. This makes it easy to execute Python scripts with external dependencies — without worrying about setting up a virtual environment manually.&lt;/p&gt;
&lt;p&gt;Even better, you can make it a standalone executable script by adding this shebang at the top:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#!/usr/bin/env -S uv run --script
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, the script will be executed using &lt;code&gt;uv&lt;/code&gt; whenever it’s run (just ensure it&#39;s executable with &lt;code&gt;chmod +x&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;This approach offers a useful way to define and run Python scripts while handling dependencies — all within a single file.&lt;/p&gt;
&lt;p&gt;Thanks to Rob Allen for &lt;a href=&quot;https://akrabat.com/defining-python-dependencies-at-the-top-of-the-file/&quot;&gt;writing about PEP-723&lt;/a&gt; and &lt;a href=&quot;https://akrabat.com/using-uv-as-your-shebang-line/&quot;&gt;how to use &lt;code&gt;uv&lt;/code&gt; as a shebang line&lt;/a&gt;.&lt;/p&gt;
</description>
        <pubDate>Thu, 30 Jan 2025 08:50:00 +0100</pubDate>
        <dc:creator>Daniel Zenzes</dc:creator>
        <guid>https://zenzes.me/til-one-file-to-rule-them-all-pep-723-and-uv/</guid>
      </item>
      <item>
        <title>Angular Migrations</title>
        <link>https://zenzes.me/angular-migrations/</link>
        <description>&lt;p&gt;In my current Angular projects, I strive to keep our growing application up-to-date with the latest stable features that Angular offers. The &lt;a href=&quot;https://angular.dev/reference/migrations&quot;&gt;official migrations&lt;/a&gt; have been instrumental in achieving this. While some manual adjustments were necessary post-migration, the majority of my code transitioned smoothly.&lt;/p&gt;
&lt;p&gt;Some migrations I highly recommend include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;inject() Functions&lt;/strong&gt;: Migrates your application to use &lt;code&gt;inject()&lt;/code&gt; for dependency injection.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Signal Inputs Migration&lt;/strong&gt;: Converts existing &lt;code&gt;@Input&lt;/code&gt; fields to the new signal-based &lt;code&gt;input()&lt;/code&gt; API.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Signal Outputs Migration&lt;/strong&gt;: Converts existing &lt;code&gt;@Output&lt;/code&gt; fields to the new signal-based &lt;code&gt;output()&lt;/code&gt; API.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Lazy-loaded Routes Migration&lt;/strong&gt;: Converts eagerly loaded component routes to lazy-loaded ones.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I believe that offering migrations like these is incredibly helpful. Slowly but surely, Angular and I are becoming friends after all.&lt;/p&gt;
</description>
        <pubDate>Tue, 21 Jan 2025 14:40:00 +0100</pubDate>
        <dc:creator>Daniel Zenzes</dc:creator>
        <guid>https://zenzes.me/angular-migrations/</guid>
      </item>
      <item>
        <title>New Hardware and Software in January</title>
        <link>https://zenzes.me/new-hardware-and-software-in-january/</link>
        <description>&lt;p&gt;In January, I began adjusting some of my long-standing software and hardware habits.&lt;/p&gt;
&lt;h3 id=&quot;%F0%9F%96%A5%EF%B8%8F-from-iterm2-to-ghostty&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://zenzes.me/new-hardware-and-software-in-january/#%F0%9F%96%A5%EF%B8%8F-from-iterm2-to-ghostty&quot;&gt;🖥️ From iTerm2 to Ghostty&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;I had been using &lt;a href=&quot;https://iterm2.com/&quot;&gt;iTerm2&lt;/a&gt; for years, and it consistently met my needs. Although they introduced some AI features, these were quickly made optional, and overall, I can still recommend the tool. Recently, I started exploring &lt;a href=&quot;https://ghostty.org/&quot;&gt;Ghostty&lt;/a&gt;, a terminal emulator developed by Mitchell Hashimoto. While it&#39;s still under development—e.g., settings must be edited in a file, though this is expected to change—it operates efficiently and integrates well with macOS. After configuring it, I decided to make it my new default terminal.&lt;/p&gt;
&lt;h3 id=&quot;%F0%9F%A4%96-monarch-as-a-spotlight-alternativ&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://zenzes.me/new-hardware-and-software-in-january/#%F0%9F%A4%96-monarch-as-a-spotlight-alternativ&quot;&gt;🤖 Monarch as a Spotlight Alternativ&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;For system searches and launching applications, I relied on Spotlight and never felt the need for more advanced tools like &lt;a href=&quot;https://www.alfredapp.com/&quot;&gt;Alfred&lt;/a&gt;. However, after reading &lt;a href=&quot;https://www.iphoneblog.de/2025/01/10/ipados-fehlt-hotkey-superpower/&quot;&gt;a recent post&lt;/a&gt; by Alexander Olma mentioning &lt;a href=&quot;https://www.monarchlauncher.com/&quot;&gt;Monarch&lt;/a&gt;, I decided to give it a try. While I&#39;m still evaluating it as my default launcher, I appreciate its enhanced capabilities, particularly the seamless initiation of web searches and integration with applications like Reminders. This experience has prompted me to explore alternatives beyond Spotlight.&lt;/p&gt;
&lt;h3 id=&quot;%F0%9F%94%8E-switching-from-google-to-kagi&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://zenzes.me/new-hardware-and-software-in-january/#%F0%9F%94%8E-switching-from-google-to-kagi&quot;&gt;🔎 Switching from Google to Kagi&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Last year, I transitioned most of my email communication from Google to &lt;a href=&quot;https://www.fastmail.com/&quot;&gt;Fastmail&lt;/a&gt;, using iCloud for personal correspondence. The next step was to find an alternative search engine, leading me to &lt;a href=&quot;https://www.kagi.com/&quot;&gt;Kagi&lt;/a&gt;. Although it requires a subscription fee, similar to Fastmail, I value my privacy and prefer not to exchange my data for free services. Kagi&#39;s integration with Safari is functional, and the search results have been satisfactory, making it a viable option for the foreseeable future.&lt;/p&gt;
&lt;h3 id=&quot;%E2%8C%A8%EF%B8%8F-adopting-logitech&#39;s-mx-keys-mini&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://zenzes.me/new-hardware-and-software-in-january/#%E2%8C%A8%EF%B8%8F-adopting-logitech&#39;s-mx-keys-mini&quot;&gt;⌨️ Adopting Logitech&#39;s MX Keys Mini&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;At my desk, I&#39;ve decided to change my keyboard setup. While I still appreciate my &lt;a href=&quot;https://nuphy.com/products/halo75&quot;&gt;NuPhy mechanical keyboard&lt;/a&gt;, its noise level isn&#39;t suitable for the office environment. I previously used Apple&#39;s Magic Keyboard but found myself favoring Logitech&#39;s &lt;a href=&quot;https://www.logitech.com/en-us/products/keyboards/mx-keys-mini.html&quot;&gt;MX Keys Mini&lt;/a&gt;, which I also use with my gaming PC. Seeking a quiet keyboard with a US layout, I chose Logitech&#39;s model as my new office standard.&lt;/p&gt;
&lt;h4 id=&quot;%F0%9F%96%B1%EF%B8%8F-experimenting-with-the-mx-master-mouse&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://zenzes.me/new-hardware-and-software-in-january/#%F0%9F%96%B1%EF%B8%8F-experimenting-with-the-mx-master-mouse&quot;&gt;🖱️ Experimenting with the MX Master Mouse&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;Having used a touchpad for years, I decided to experiment with a mouse to assess any potential benefits. Last week, I connected my &lt;a href=&quot;https://www.logitech.com/en-us/products/mice/mx-master-3s.html&quot;&gt;MX Master&lt;/a&gt; to my Mac. While I&#39;m not entirely certain about replacing my Magic Trackpad, I appreciate the touchpad&#39;s gestures for tasks like switching between screens or windows. I plan to spend more time adapting to the alternatives offered by the MX Master before making a final decision.&lt;/p&gt;
</description>
        <pubDate>Mon, 13 Jan 2025 11:40:00 +0100</pubDate>
        <dc:creator>Daniel Zenzes</dc:creator>
        <guid>https://zenzes.me/new-hardware-and-software-in-january/</guid>
      </item>
      <item>
        <title>TIL: Updating Python using uv</title>
        <link>https://zenzes.me/til-updating-python-using-uv/</link>
        <description>&lt;p&gt;Another link to &lt;a href=&quot;https://simonwillison.net/&quot;&gt;Simon Willison&#39;s blog&lt;/a&gt;: As you may already know, I&#39;ve been experimenting with Python more frequently and even &lt;a href=&quot;https://zenzes.me/python-rediscovered-uv-the-swiss-army-knife-for-tooling/&quot;&gt;discovered uv along the way&lt;/a&gt;. Naturally, I need to update my Python installation from time to time, and Simon has written a guide on how to do this.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;uv python install 3.13.X
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Be sure to read the &lt;a href=&quot;https://github.com/astral-sh/uv/pull/10377#issuecomment-2576353887&quot;&gt;caveat from Zanie Blue on Simon&#39;s pull request documenting this&lt;/a&gt; as well.&lt;/p&gt;
</description>
        <pubDate>Wed, 08 Jan 2025 11:14:00 +0100</pubDate>
        <dc:creator>Daniel Zenzes</dc:creator>
        <guid>https://zenzes.me/til-updating-python-using-uv/</guid>
      </item>
      <item>
        <title>htmx offers stability as a feature</title>
        <link>https://zenzes.me/htmx-offers-stability-as-a-feature/</link>
        <description>&lt;p&gt;At the moment, I&#39;m waiting to upgrade applications to the latest Angular version because breaking changes in the update are slowing down the development of one of the libraries we use. In this context, stability as a feature sounds very appealing.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;People shouldn’t feel pressure to upgrade htmx over time unless there are specific bugs that they want fixed, and they should feel comfortable that the htmx that they write in 2025 will look very similar to htmx they write in 2035 and beyond. -- &lt;cite&gt;&lt;a href=&quot;https://htmx.org/essays/future/#:~:text=People%20shouldn%E2%80%99t%20feel%20pressure%20to%20upgrade%20htmx%20over%20time%20unless%20there%20are%20specific%20bugs%20that%20they%20want%20fixed%2C%20and%20theyshould%20feel%20comfortable%20that%20the%20htmx%20that%20they%20write%20in%202025%20will%20look%20very%20similar%20to%20htmx%20they%20write%20in%202035%20andbeyond.&quot;&gt;htmx blog&lt;/a&gt;&lt;/cite&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In my perception, things have gone very quiet around htmx in the last few months after an initial wave of hype. I&#39;m curious to see if it will become a serious option for future projects.&lt;/p&gt;
&lt;p&gt;via &lt;a href=&quot;https://simonwillison.net/2025/Jan/6/the-future-of-htmx/&quot;&gt;Simon Willison&lt;/a&gt;&lt;/p&gt;
</description>
        <pubDate>Wed, 08 Jan 2025 07:15:00 +0100</pubDate>
        <dc:creator>Daniel Zenzes</dc:creator>
        <guid>https://zenzes.me/htmx-offers-stability-as-a-feature/</guid>
      </item>
      <item>
        <title>Basic NextDNS Configuration</title>
        <link>https://zenzes.me/basic-nextdns-configuration/</link>
        <description>&lt;p&gt;And here’s another useful tip if you’re using &lt;a href=&quot;https://nextdns.io/de&quot;&gt;NextDNS&lt;/a&gt; (which, along with &lt;a href=&quot;https://kaylees.site/wipr2.html&quot;&gt;Wipr 2&lt;/a&gt;, is the reason I see no ads and get tracked less): This &amp;quot; Hitchhiker’s NextDNS Guide&amp;quot; pretty much covers all the key information you need for configuration.&lt;/p&gt;
&lt;p&gt;I personally use NextDNS through the app, but Alex’s approach has its advantages:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Instead of directly applying the profile (on the router), I install the native apps for DNS relay and the firewall so I can quickly disable them (on individual devices). It&#39;s inevitable that you’ll occasionally need to load websites “without a content blocker” and without the DNS redirection — even if you’ve explicitly added domains to the general “allowlist.” -- &lt;cite&gt;&lt;a href=&quot;https://www.iphoneblog.de/2025/01/02/the-hitchhikers-nextdns-guide/#:~:text=Anstelle%20direkt%20das,Allowlist%E2%80%9C%20gesetzt%20hat.&quot;&gt;iPhoneBlog.de&lt;/a&gt;&lt;/cite&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;via &lt;a href=&quot;https://www.iphoneblog.de/2025/01/02/the-hitchhikers-nextdns-guide/&quot;&gt;iPhoneBlog.de&lt;/a&gt;&lt;/p&gt;
</description>
        <pubDate>Mon, 06 Jan 2025 16:30:00 +0100</pubDate>
        <dc:creator>Daniel Zenzes</dc:creator>
        <guid>https://zenzes.me/basic-nextdns-configuration/</guid>
      </item>
      <item>
        <title>Creating Biometric Passport Photos</title>
        <link>https://zenzes.me/creating-biometric-passport-photos/</link>
        <description>&lt;p&gt;More of a note to myself than actual news: You can create passport photos using your smartphone and then adjust them on &lt;a href=&quot;https://www.passfotogenerator.com/&quot;&gt;passfotogenerator.com&lt;/a&gt;. This can be particularly useful when dealing with small children. For instance, taking a passport photo of my one-year-old daughter was quite challenging with a professional photographer. Doing it in a familiar environment with more time would likely have been much easier.&lt;/p&gt;
&lt;p&gt;To create a biometric passport photo, the following requirements must be met:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Biometric passport photos must measure 3.5 x 4.5 cm&lt;/li&gt;
&lt;li&gt;The face height should occupy about 70–80% of the image&lt;/li&gt;
&lt;li&gt;The photo must be sharp, high-contrast, and evenly lit&lt;/li&gt;
&lt;li&gt;The image quality should be high with natural skin tones&lt;/li&gt;
&lt;li&gt;The background must be plain, light-colored, and pattern-free&lt;/li&gt;
&lt;li&gt;The head should be centered and positioned straight&lt;/li&gt;
&lt;li&gt;Eyes must be open and looking directly into the camera&lt;/li&gt;
&lt;li&gt;A neutral facial expression and closed mouth are mandatory&lt;/li&gt;
&lt;li&gt;Head coverings are only allowed for religious reasons&lt;/li&gt;
&lt;li&gt;Special rules apply for children and infants&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;via &lt;a href=&quot;https://vowe.net/2024/10/09/passfotos-leicht-gemacht/&quot;&gt;Volker Weber&lt;/a&gt;&lt;/p&gt;
</description>
        <pubDate>Mon, 06 Jan 2025 07:15:00 +0100</pubDate>
        <dc:creator>Daniel Zenzes</dc:creator>
        <guid>https://zenzes.me/creating-biometric-passport-photos/</guid>
      </item>
      <item>
        <title>2024 Wrapped: My Default Tools</title>
        <link>https://zenzes.me/2024-wrapped-my-default-tools/</link>
        <description>&lt;p&gt;As 2024 draws to a close, it’s time to reflect on the apps, tools, and platforms that shaped my daily life this year. Here’s a comprehensive look at my go-to choices for productivity, creativity, and beyond. Anything that has changed has a strike-through the previous tool:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;🌐 Browser: &lt;strong&gt;Safari&lt;/strong&gt;, &lt;strong&gt;&lt;a href=&quot;https://www.mozilla.org/en-US/firefox/new/&quot;&gt;Firefox&lt;/a&gt;&lt;/strong&gt;, &lt;strong&gt;&lt;a href=&quot;https://www.google.com/chrome/&quot;&gt;Chrome&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;⛔️ Ad-Blocking: &lt;strong&gt;&lt;a href=&quot;https://kaylees.site/wipr2.html&quot;&gt;Wipr 2&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;🔍 Search: &lt;strong&gt;&lt;a href=&quot;https://google.com/&quot;&gt;Google&lt;/a&gt;&lt;/strong&gt;, &lt;strong&gt;&lt;a href=&quot;https://kagi.com/&quot;&gt;Kagi&lt;/a&gt;&lt;/strong&gt; (in evaluation)&lt;/li&gt;
&lt;li&gt;📧 Mail Client: &lt;strong&gt;Apple Mail&lt;/strong&gt;. Mail Service: &lt;strong&gt;Google&lt;/strong&gt;, &lt;strong&gt;&lt;a href=&quot;https://www.icloud.com/&quot;&gt;iCloud&lt;/a&gt;&lt;/strong&gt;, &lt;strong&gt;&lt;a href=&quot;https://www.fastmail.com/&quot;&gt;Fastmail&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;✍️ Notes: &lt;strong&gt;Apple Notes&lt;/strong&gt;, &lt;strong&gt;&lt;a href=&quot;https://www.moleskine.com/&quot;&gt;Moleskine notebook&lt;/a&gt;&lt;/strong&gt; with &lt;strong&gt;&lt;a href=&quot;https://www.kaweco-pen.com/&quot;&gt;Kaweco fountain pen&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;🌍 Cloud File Storage: &lt;strong&gt;&lt;a href=&quot;https://www.icloud.com/&quot;&gt;iCloud&lt;/a&gt;&lt;/strong&gt;, &lt;strong&gt;&lt;a href=&quot;https://nextcloud.com/&quot;&gt;Nextcloud&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;💬 Chat: &lt;strong&gt;&lt;a href=&quot;https://signal.org/&quot;&gt;Signal&lt;/a&gt;&lt;/strong&gt;, &lt;strong&gt;iMessage&lt;/strong&gt;, &lt;strong&gt;WhatsApp&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;🗓 Calendar: &lt;strong&gt;Apple Calendar&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;✅ To-Do: &lt;strong&gt;Apple Reminders&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;📞 Video Calls: &lt;strong&gt;FaceTime&lt;/strong&gt;, &lt;strong&gt;Slack&lt;/strong&gt;, &lt;strong&gt;Microsoft Teams&lt;/strong&gt;, &lt;strong&gt;Zoom&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;📰 RSS: &lt;strong&gt;&lt;a href=&quot;https://reederapp.com/&quot;&gt;Reeder&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;🎶 Music: &lt;strong&gt;&lt;a href=&quot;https://music.apple.com/&quot;&gt;Apple Music&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;🎧 Podcasts: &lt;s&gt;Overcast&lt;/s&gt; → &lt;strong&gt;&lt;a href=&quot;https://castro.fm/&quot;&gt;Castro&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;📖 Reading: &lt;strong&gt;&lt;a href=&quot;https://pocketbook.de/&quot;&gt;PocketBook&lt;/a&gt;&lt;/strong&gt;, &lt;strong&gt;Apple Books&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;🔑 Password Management: &lt;s&gt;1Password&lt;/s&gt; → &lt;strong&gt;Apple Passwords&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;🔧 Code Editor: &lt;strong&gt;&lt;a href=&quot;https://www.jetbrains.com/idea&quot;&gt;IntelliJ&lt;/a&gt;&lt;/strong&gt;, &lt;strong&gt;&lt;a href=&quot;https://code.visualstudio.com/&quot;&gt;VS Code&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;🖥️ Terminal: &lt;strong&gt;&lt;a href=&quot;https://iterm2.com/&quot;&gt;iTerm2&lt;/a&gt;&lt;/strong&gt;, &lt;strong&gt;&lt;a href=&quot;https://ghostty.org/&quot;&gt;Ghostty&lt;/a&gt;&lt;/strong&gt; (in evaluation). Shell: &lt;s&gt;zsh&lt;/s&gt; → &lt;strong&gt;&lt;a href=&quot;https://fishshell.com/&quot;&gt;Fish Shell&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;⛅️ Weather: &lt;strong&gt;&lt;a href=&quot;https://carrotweather.com/&quot;&gt;Carrot Weather&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;⚙️ Automation: &lt;strong&gt;&lt;a href=&quot;https://www.noodlesoft.com/&quot;&gt;Hazel&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;That’s my 2024 wrapped! What were your favorite tools this year? &lt;a href=&quot;https://chaos.social/@danielzenzes&quot;&gt;Let me know&lt;/a&gt;!&lt;/p&gt;
</description>
        <pubDate>Tue, 31 Dec 2024 21:00:00 +0100</pubDate>
        <dc:creator>Daniel Zenzes</dc:creator>
        <guid>https://zenzes.me/2024-wrapped-my-default-tools/</guid>
      </item>
      <item>
        <title>Python Rediscovered: uv – The Swiss Army Knife for Tooling</title>
        <link>https://zenzes.me/python-rediscovered-uv-the-swiss-army-knife-for-tooling/</link>
        <description>&lt;p&gt;As a developer who works extensively with JavaScript and Java, exploring Python anew has been an exciting journey. Back in university, I had already worked with Python, but at that time, I didn’t give much thought to tooling — it just worked, or so it seemed. Today, I understand that tools for dependency management and virtual environments are fundamental for modern software development.&lt;/p&gt;
&lt;p&gt;However, much like in the JavaScript ecosystem, I encountered a vast array of options in Python: &lt;code&gt;pip&lt;/code&gt;, &lt;code&gt;poetry&lt;/code&gt;, &lt;code&gt;virtualenv&lt;/code&gt;, and many more. The sheer variety, combined with tutorials often relying on different tools, can feel overwhelming when starting out.&lt;/p&gt;
&lt;p&gt;To find a clear entry point, I reached out to my friend &lt;a href=&quot;https://andrich.me/&quot;&gt;Oliver&lt;/a&gt; for advice. His response was concise:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Yes. Only uv. It replaces pip, venv, poetry, twine, setuptools, pdm, hatch, and everything else out there.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This recommendation felt like a practical solution to what could otherwise have been a daunting setup process.&lt;/p&gt;
&lt;h2 id=&quot;&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://zenzes.me/python-rediscovered-uv-the-swiss-army-knife-for-tooling/#&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;h2 id=&quot;what-is-uv%3F&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://zenzes.me/python-rediscovered-uv-the-swiss-army-knife-for-tooling/#what-is-uv%3F&quot;&gt;What is &lt;code&gt;uv&lt;/code&gt;?&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;uv&lt;/code&gt; is a Rust-based tool for Python that brings together the functionality of many popular tools. It manages dependencies (&lt;code&gt;pip&lt;/code&gt;), virtual environments (&lt;code&gt;venv&lt;/code&gt;), build processes (&lt;code&gt;poetry&lt;/code&gt;), and more through a unified interface. For someone familiar with JavaScript workflows, it feels similar to &lt;code&gt;npm&lt;/code&gt; or &lt;code&gt;yarn&lt;/code&gt;—but adapted to Python’s ecosystem.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2 id=&quot;a-project-with-flask&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://zenzes.me/python-rediscovered-uv-the-swiss-army-knife-for-tooling/#a-project-with-flask&quot;&gt;A Project with Flask&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To explore what &lt;code&gt;uv&lt;/code&gt; offers, I decided to build a basic “Hello World” application using Flask. It provided a hands-on way to assess the tool’s capabilities.&lt;/p&gt;
&lt;h3 id=&quot;initializing-the-project&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://zenzes.me/python-rediscovered-uv-the-swiss-army-knife-for-tooling/#initializing-the-project&quot;&gt;Initializing the Project&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;With &lt;code&gt;uv&lt;/code&gt;, you can initialize a project and create a directory in one step:&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;uv init my_flask_project
&lt;span class=&quot;token builtin class-name&quot;&gt;cd&lt;/span&gt; my_flask_project&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This command sets up the directory &lt;code&gt;my_flask_project&lt;/code&gt; and generates a &lt;code&gt;pyproject.toml&lt;/code&gt; file, which serves as the configuration for your project.&lt;/p&gt;
&lt;h3 id=&quot;creating-a-virtual-environment&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://zenzes.me/python-rediscovered-uv-the-swiss-army-knife-for-tooling/#creating-a-virtual-environment&quot;&gt;Creating a Virtual Environment&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;A key part of Python development is isolating project dependencies. With &lt;code&gt;uv&lt;/code&gt;, setting up a virtual environment is straightforward:&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;uv venv&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This creates a virtual environment within the project directory and activates it automatically. You’ll notice your shell prompt changes, indicating the environment is active. To deactivate it, use:&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;deactivate&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Later, you can reactivate the environment with:&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;source&lt;/span&gt; .venv/bin/activate&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Using a virtual environment ensures that dependencies for one project do not interfere with others or your global Python setup.&lt;/p&gt;
&lt;h3 id=&quot;adding-flask-as-a-dependency&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://zenzes.me/python-rediscovered-uv-the-swiss-army-knife-for-tooling/#adding-flask-as-a-dependency&quot;&gt;Adding Flask as a Dependency&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;To include Flask in the project, run:&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;uv &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; flask&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This command installs Flask, updates the &lt;code&gt;pyproject.toml&lt;/code&gt; file to reflect the dependency, and creates or updates the &lt;code&gt;uv.lock&lt;/code&gt; file. The lock file is particularly valuable because it ensures reproducible builds by pinning specific versions of dependencies.&lt;/p&gt;
&lt;h3 id=&quot;writing-a-%E2%80%9Chello-world%E2%80%9D-application&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://zenzes.me/python-rediscovered-uv-the-swiss-army-knife-for-tooling/#writing-a-%E2%80%9Chello-world%E2%80%9D-application&quot;&gt;Writing a “Hello World” Application&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;In the &lt;code&gt;app.py&lt;/code&gt; file, I added the following code:&lt;/p&gt;
&lt;pre class=&quot;language-python&quot;&gt;&lt;code class=&quot;language-python&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; flask &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; Flask

app &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Flask&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 decorator annotation punctuation&quot;&gt;@app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;route&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;/&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;hello_world&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 string&quot;&gt;&#39;Hello World!&#39;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;running-the-application&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://zenzes.me/python-rediscovered-uv-the-swiss-army-knife-for-tooling/#running-the-application&quot;&gt;Running the Application&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;With the virtual environment activated, I started the Flask application:&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;flask run&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The Flask server started at &lt;code&gt;http://127.0.0.1:5000/&lt;/code&gt;, and navigating to this URL displayed the expected “Hello World!” message.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2 id=&quot;additional-resources&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://zenzes.me/python-rediscovered-uv-the-swiss-army-knife-for-tooling/#additional-resources&quot;&gt;Additional Resources&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;For those interested in learning more about &lt;code&gt;uv&lt;/code&gt;, Oliver has written insightful articles that provide further context:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://andrich.me/2024/09/uv-i-am-somewhat-sold/&quot;&gt;uv: I am somewhat sold&lt;/a&gt;&lt;br /&gt;
Oliver shares his initial impressions of &lt;code&gt;uv&lt;/code&gt;, including its strengths and why it stands out as a tool.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://web.archive.org/web/20241014063005/https://andrich.me/2024/09/my-ideal-uv-based-dockerfile/&quot;&gt;My ideal uv-based Dockerfile&lt;/a&gt; (Web Archive)&lt;br /&gt;
A detailed guide to creating an optimized Dockerfile using &lt;code&gt;uv&lt;/code&gt;, demonstrating how it can simplify containerized Python environments.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://andrich.me/2024/10/two-weeks-with-uv/&quot;&gt;Two weeks with uv&lt;/a&gt;&lt;br /&gt;
After two weeks of using &lt;code&gt;uv&lt;/code&gt;, Oliver reflects on his experience, highlighting both its benefits and potential limitations.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr /&gt;
&lt;h2 id=&quot;conclusion&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://zenzes.me/python-rediscovered-uv-the-swiss-army-knife-for-tooling/#conclusion&quot;&gt;Conclusion&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Working with &lt;code&gt;uv&lt;/code&gt; has made my return to Python development much smoother. It combines essential features like dependency management, virtual environments, and a clear project structure into a single tool. For me, it provides a solid foundation for starting new projects without feeling overwhelmed by the tooling landscape.&lt;/p&gt;
&lt;p&gt;If you’re looking to (re)discover Python, &lt;code&gt;uv&lt;/code&gt; might be the Swiss Army knife you need. Oliver’s recommendation was spot on — it truly replaces a lot of tools.&lt;/p&gt;
</description>
        <pubDate>Thu, 12 Dec 2024 14:45:00 +0100</pubDate>
        <dc:creator>Daniel Zenzes</dc:creator>
        <guid>https://zenzes.me/python-rediscovered-uv-the-swiss-army-knife-for-tooling/</guid>
      </item>
      <item>
        <title>Stepping into Other Bubbles</title>
        <link>https://zenzes.me/stepping-into-other-bubbles/</link>
        <description>&lt;p&gt;Every year, I dedicate some of my free time to &lt;a href=&quot;https://adventofcode.com/&quot; title=&quot;Homepage of Advent of Code&quot;&gt;Advent of Code&lt;/a&gt;, and each year I try to tackle it with a different programming language. It doesn’t have to be anything overly exotic, and I often end up using Go. But this year, I want to give Python another chance.&lt;/p&gt;
&lt;p&gt;And what can I say: I can totally understand how other developers feel when they transition into the JavaScript ecosystem. You&#39;re practically overwhelmed by tools and opinions, leaving you afraid to even get started for fear of doing it wrong. Back when I first started programming (often with Python, among other things), it was simpler. I didn’t know what I needed to pay attention to (testing, build systems, dependency management), and somehow, it was more chaotic back then—but it also felt faster.&lt;/p&gt;
</description>
        <pubDate>Thu, 28 Nov 2024 08:45:00 +0100</pubDate>
        <dc:creator>Daniel Zenzes</dc:creator>
        <guid>https://zenzes.me/stepping-into-other-bubbles/</guid>
      </item>
      <item>
        <title>TIL: Efficient Sorting of Git Branches</title>
        <link>https://zenzes.me/til-efficient-sorting-of-git-branches/</link>
        <description>&lt;p&gt;In Git, branches are sorted alphabetically by default. This is convenient when you remember the branch name, but it&#39;s not always the most practical approach. Fortunately, the sorting order can be customized to display branches with the latest changes first:&lt;/p&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;git&lt;/span&gt; branch &lt;span class=&quot;token parameter variable&quot;&gt;--sort&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;-committerdate&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Optionally, &lt;code&gt;-r&lt;/code&gt; can be added to search for a remote branch. This is particularly useful when looking for a branch previously worked on with a teammate.&lt;/p&gt;
&lt;p&gt;I have set this as the default in my personal &lt;code&gt;.gitconfig&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;branch&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 operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-committerdate&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
</description>
        <pubDate>Tue, 30 Jan 2024 08:02:00 +0100</pubDate>
        <dc:creator>Daniel Zenzes</dc:creator>
        <guid>https://zenzes.me/til-efficient-sorting-of-git-branches/</guid>
      </item>
      <item>
        <title>Cleaning Up Local Git Branches</title>
        <link>https://zenzes.me/cleaning-up-local-git-branches/</link>
        <description>&lt;p&gt;Over time, I accumulate several local Git branches in various projects. To maintain clarity, I regularly delete all branches except the main branch.&lt;/p&gt;
&lt;p&gt;To avoid having to constantly search for the command, I&#39;d like to share it with you here:&lt;/p&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;git&lt;/span&gt; branch &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;grep&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-v&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;main&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;xargs&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; branch &lt;span class=&quot;token parameter variable&quot;&gt;-d&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;git branch&lt;/code&gt; lists all local branches. &lt;code&gt;grep -v &amp;quot;main&amp;quot;&lt;/code&gt; filters out the &lt;code&gt;main&lt;/code&gt; branch from this list, as I don&#39;t want to delete it. &lt;code&gt;xargs git branch -d&lt;/code&gt; executes the &lt;code&gt;git branch -d&lt;/code&gt; command on the remaining branches.&lt;/p&gt;
&lt;p&gt;If you want to keep multiple branches, you can extend the command:&lt;/p&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;git&lt;/span&gt; branch &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;grep&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-v&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;main&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;grep&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-v&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;develop&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;xargs&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; branch &lt;span class=&quot;token parameter variable&quot;&gt;-d&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here, two branches, &lt;code&gt;main&lt;/code&gt; and &lt;code&gt;develop&lt;/code&gt;, are filtered out from the list and thus not deleted.&lt;/p&gt;
&lt;p&gt;I hope this tip helps you keep your system as tidy as it helps me.&lt;/p&gt;
</description>
        <pubDate>Sat, 27 Jan 2024 15:02:00 +0100</pubDate>
        <dc:creator>Daniel Zenzes</dc:creator>
        <guid>https://zenzes.me/cleaning-up-local-git-branches/</guid>
      </item>
      <item>
        <title>SoftwerkerCast: Frontend for Backend Developers</title>
        <link>https://zenzes.me/softwerkercast-frontend-for-backend-developers/</link>
        <description>&lt;p&gt;My former colleague Marco invited me to codecentric&#39;s &lt;a href=&quot;https://www.codecentric.de/wissens-hub/softwerker/softwerkercast&quot;&gt;SoftwerkerCast&lt;/a&gt; to talk about frontend development and how backend developers can get started here.&lt;/p&gt;
&lt;p&gt;I can recommend the SoftwerkerCast. Marco is doing a great job as host here and there are many interesting topics the podcast covered. You should find it on the platform of your choice.&lt;/p&gt;
&lt;p&gt;Link: &lt;a href=&quot;https://podcasters.spotify.com/pod/show/softwerkercast/episodes/Frontend-fr-Backend-Developer-e28ppqp&quot; title=&quot;SoftwerkerCast: Frontend für Backend Developer on Spotify&quot;&gt;Episode on Spotify&lt;/a&gt;&lt;/p&gt;
</description>
        <pubDate>Fri, 29 Sep 2023 08:14:00 +0200</pubDate>
        <dc:creator>Daniel Zenzes</dc:creator>
        <guid>https://zenzes.me/softwerkercast-frontend-for-backend-developers/</guid>
      </item>
      <item>
        <title>TIL: Smaller PDFs</title>
        <link>https://zenzes.me/til-smaller-pdfs/</link>
        <description>&lt;p&gt;Now and then I want to create PDFs and optimize the file size. I&#39;m not necessarily in the mood to add another PDF software to my computer, and, depending on the content of the document, I don&#39;t want to complete the task online. In this situation, you can do well with Ghostscript.&lt;/p&gt;
&lt;p&gt;The first thing you have to do is install Ghostscript on your computer. On a Mac with Homebrew, you can accomplish this with the following command:&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;brew &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; ghostscript&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To optimize a PDF, I use the following command.&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;gs &lt;span class=&quot;token parameter variable&quot;&gt;-sDEVICE&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;pdfwrite &lt;span class=&quot;token parameter variable&quot;&gt;-dPDFSETTINGS&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;/ebook &lt;span class=&quot;token parameter variable&quot;&gt;-dNOPAUSE&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-dQUIET&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-dBATCH&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-sOutputFile&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;output.pdf&quot;&lt;/span&gt; input.pdf&lt;/code&gt;&lt;/pre&gt;
</description>
        <pubDate>Tue, 13 Jun 2023 09:02:00 +0200</pubDate>
        <dc:creator>Daniel Zenzes</dc:creator>
        <guid>https://zenzes.me/til-smaller-pdfs/</guid>
      </item>
      <item>
        <title>Deep Work - Cal Newport</title>
        <link>https://zenzes.me/deep-work-cal-newport/</link>
        <description>&lt;p&gt;Following &amp;quot;&lt;a href=&quot;https://zenzes.me/digital-minimalism-cal-newport/&quot; title=&quot;Blogpost about the book Digital Minimalism&quot;&gt;Digital Minimalism&lt;/a&gt;,&amp;quot; &amp;quot;Deep Work&amp;quot; was the second book by &lt;a href=&quot;https://calnewport.com/&quot; title=&quot;Permalink: Personal website of Cal Newport&quot;&gt;Cal Newport&lt;/a&gt; that I immersed myself into. The former had an overemphasis on &amp;quot;success stories&amp;quot; which seemed disruptive to me, but in &amp;quot;Deep Work,&amp;quot; Newport strikes the right balance, in my opinion.&lt;/p&gt;
&lt;p&gt;But what exactly is Deep Work? Essentially, Cal Newport differentiates between Shallow Work (simpler tasks) and &amp;quot;Deep Work,&amp;quot; which refers to focused work on a specific task or subject. The author provides several reasons why we often fail to work with concentration, the benefits of doing so, and how one can integrate Deep Work into their everyday work routine.&lt;/p&gt;
&lt;p&gt;The book lays the groundwork for several themes later elaborated in &amp;quot;Digital Minimalism&amp;quot; and advocates for incorporating periods of focused work on a single subject into the daily work routine. I am personally familiar with this concept from software development, where, aided by the right playlist, I quickly find myself &amp;quot;in the flow.&amp;quot; However, in roles influenced by appointments and coordination, I find it more challenging to work focused on individual topics.&lt;/p&gt;
&lt;p&gt;This review was originally written in 2020 and was previously published on my old website.&lt;/p&gt;
</description>
        <pubDate>Fri, 02 Jun 2023 09:40:00 +0200</pubDate>
        <dc:creator>Daniel Zenzes</dc:creator>
        <guid>https://zenzes.me/deep-work-cal-newport/</guid>
      </item>
      <item>
        <title>Digital Minimalism - Cal Newport</title>
        <link>https://zenzes.me/digital-minimalism-cal-newport/</link>
        <description>&lt;p&gt;In early 2020, I discovered &lt;a href=&quot;https://calnewport.com/&quot; title=&quot;Permalink: Personal website of Cal Newport&quot;&gt;Cal Newport&#39;s&lt;/a&gt; book &amp;quot;&lt;a href=&quot;https://www.goodreads.com/book/show/40672036-digital-minimalism&quot; title=&quot;Permalink: Digitial Minimalis on Goodreads&quot;&gt;Digital Minimalism&lt;/a&gt;&amp;quot;, a discovery inspired in part by &lt;a href=&quot;https://uarrr.org/2020/02/26/digitaler-minimalismus/&quot; title=&quot;Blogpost about digitalem Minimalism by Marcel&quot;&gt;Marcel&#39;s insightful blog post on the subject&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The book piqued my interest and remains an influential resource. Its emphasis on successful anecdotes initially required some adjustment, and I found myself questioning the idea that career advancements could be solely attributed to following an author&#39;s guidelines. However, I came to appreciate the book not only for its rule-setting but also for the in-depth rationale provided behind these rules, enabling their integration into personal routines.&lt;/p&gt;
&lt;p&gt;In late 2020, I made a significant decision: I considerably reduced the notifications on my devices, recognizing them as primary distractions. My approach to news sources also underwent a shift from a heavy reliance on Google News to a more streamlined selection. Inspired by Newport&#39;s book, I removed certain apps from my iPhone, generally confined its use to my home office, and, thanks to the &amp;quot;Screen Time&amp;quot; feature, limited its functionalities to those of a basic phone after 8 PM. As a result, I now primarily use my devices for work or task-specific purposes.&lt;/p&gt;
&lt;p&gt;These changes, first implemented in 2020, have greatly helped me in distinguishing between work and leisure time. Platforms like Mastodon, initially mere distractions, have transformed into effective tools for task completion. This shift is something I have adapted well to over time.&lt;/p&gt;
&lt;p&gt;Throughout this journey, I have maintained a firm stance on limiting notifications. For each app, I continuously question whether I truly require its notifications, a query that usually garners a &amp;quot;no.&amp;quot; In terms of reducing usage of certain social media apps, my transition towards using Mastodon more selectively has proven to be a successful adjustment.&lt;/p&gt;
</description>
        <pubDate>Tue, 30 May 2023 09:45:00 +0200</pubDate>
        <dc:creator>Daniel Zenzes</dc:creator>
        <guid>https://zenzes.me/digital-minimalism-cal-newport/</guid>
      </item>
      <item>
        <title>What if? - Randall Munroe</title>
        <link>https://zenzes.me/what-if-randall-munroe/</link>
        <description>&lt;p&gt;Sicherlich kein Insider-Tipp und doch möchte ich Euch &lt;a href=&quot;https://www.amazon.de/What-w%C3%A4re-wenn-wissenschaftliche-hypothetische/dp/3328106901&quot; title=&quot;What if? Von Randall Munroe auf amazon&quot;&gt;&amp;quot;What if&amp;quot;&lt;/a&gt; von &lt;a href=&quot;https://xkcd.com/&quot; title=&quot;xkcd - Der Webcomic von Randall Munroe&quot;&gt;Randall Munroe&lt;/a&gt; wärmstens ans Herz legen.&lt;/p&gt;
&lt;p&gt;Wahrscheinlich kennt jeder, der etwas länger im Internet bewusst oder unbewusst unterwegs ist, die Comics von Randall Munroe. Weniger bekannt ist wahrscheinlich das er als Physiker früher für die NASA gearbeitet hat bevor er sich entschied sein Geld mit Webcomics zu verdienen.&lt;/p&gt;
&lt;p&gt;Ich musste bei diesem Buch (Spoiler auch bei seinem Buch &amp;quot;How to&amp;quot;) mehrmals laut lachen da sein Stil und sein Humor grandios sind. Es führt mir mal wieder vor Augen das ich damals Physik nicht hätte abwählen sollen und es schön gewesen wäre, wenn ich hier mehr Hintergrundwissen hätte (vielen Dank nochmals an meinen Physiklehrer. Ein wahrlich begnadeter Pädagoge). Dies bedeutet für jeden, der sich überlegt das Buch zu kaufen das man auch ohne tiefe Physikkenntnisse Spaß mit diesem Buch haben kann. Die Formeln akzeptiere ich einfach und konzentriere mich mehr auf den Text. Selbst wenn lesen nicht Euer Ding ist, gibt es zahlreiche Comics.&lt;/p&gt;
&lt;p&gt;Mehr ähnliche Beispiele wie im Buch findet man auch auf &lt;a href=&quot;https://what-if.xkcd.com/&quot; title=&quot;Mehr Beiträge passend zum Buch auf xkcd&quot;&gt;seiner Webseite&lt;/a&gt;. Dort kann man ihm auch Fragen zusenden.&lt;/p&gt;
&lt;p&gt;&amp;quot;What if?&amp;quot; hat bei mir schon jetzt bewirkt das ich meine Physikkenntnisse auffrischen werde. Vielleicht auch ein Thema für den Blog hier.&lt;/p&gt;
</description>
        <pubDate>Mon, 29 May 2023 14:20:00 +0200</pubDate>
        <dc:creator>Daniel Zenzes</dc:creator>
        <guid>https://zenzes.me/what-if-randall-munroe/</guid>
      </item>
      <item>
        <title>How to - Randall Munroe</title>
        <link>https://zenzes.me/how-to-randall-munroe/</link>
        <description>&lt;p&gt;Nach &amp;quot;&lt;a href=&quot;https://mies.me/blog/2020/06/06/what-if-randall-munroe/&quot; title=&quot;Mein Review zu What if von Randall Munroe&quot;&gt;What if&lt;/a&gt;&amp;quot; folgt also &amp;quot;&lt;a href=&quot;https://www.amazon.de/gp/product/B07NDF461Q&quot; title=&quot;How to auf amazon&quot;&gt;How to&lt;/a&gt;&amp;quot;, welches auf den ersten Blick die logische Fortsetzung des vorherigen Buchs von &lt;a href=&quot;https://xkcd.com/&quot; title=&quot;xkcd - Der Webcomic von Randall Munroe&quot;&gt;Randall Munroe&lt;/a&gt; ist. An vielen Stellen gelingt das gut, jetzt, wo ich das Buch abgeschlossen habe, frage ich mich, ob ich zwischen den Büchern mehr Zeit hätte lassen sollen.&lt;/p&gt;
&lt;p&gt;Während es in &amp;quot;What if&amp;quot; darum geht zu beschreiben, was uns erwartet, wenn ein bestimmtes Ereignis eintritt, geht es in &amp;quot;How to&amp;quot; zunächst um ganz banale Anleitungen. Wie springe ich weit, wie werfe ich einen Gegenstand oder wie ziehe ich um. Jedem Kapitel fängt hier mit einem alltäglichen Problem an, welches dann möglichst simpel angegangen wird. Danach geht es dann darum, den vorherigen Ansatz weiterzutreiben und somit das eigentliche Problem immer absurder zu lösen.&lt;/p&gt;
&lt;p&gt;&amp;quot;How to&amp;quot; ist keine ernstzunehmende Anleitung, weckte aber bei mir, ähnlich wie der Vorgänger die Lust, meine Physik-Kenntnisse aufzufrischen (bzw überhaupt aufzubauen).&lt;/p&gt;
&lt;p&gt;Da ich beide Bücher Bücher direkt hintereinander gelesen habe, stellte sich aber eine gewisse Sättigung ein. Beide Bücher sind lustig (auch wenn ich den Vorgänger unterhaltsamer fand), ähneln sich aber dann doch zu stark. Das nächste Buch des Autors (der &amp;quot;Thing Explainer&amp;quot; steht noch im Bücherregal) werde ich erst in ein paar Wochen angehen.&lt;/p&gt;
</description>
        <pubDate>Mon, 29 May 2023 14:20:00 +0200</pubDate>
        <dc:creator>Daniel Zenzes</dc:creator>
        <guid>https://zenzes.me/how-to-randall-munroe/</guid>
      </item>
      <item>
        <title>Owning my podcast again</title>
        <link>https://zenzes.me/owning-my-podcast-again/</link>
        <description>&lt;p&gt;A few weeks ago, I decided to reactivate my podcast, &amp;quot;Herr Zenzes wills wissen&amp;quot;. For the last few years, I hosted it with Podigee, but it became too expensive for my use case. I don&#39;t produce enough content to take full advantage of the smallest package, so I can save some money by hosting the podcast myself again.&lt;/p&gt;
&lt;p&gt;To host the podcast myself, I needed to migrate it from Podigee without breaking my RSS feed. I followed these steps to achieve this:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Create a script to import the podcast from Podigee. I want to manage the content with Markdown because I use 11ty, which works well with Markdown.&lt;/li&gt;
&lt;li&gt;Customize my page: I needed an RSS feed that has no changes to the current feed, and I had to include my podcast on my page as well.&lt;/li&gt;
&lt;li&gt;Create a script to add new episodes to the podcast.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;my-podcast-importer&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://zenzes.me/owning-my-podcast-again/#my-podcast-importer&quot;&gt;My Podcast Importer&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I needed a script to import a podcast and asked ChatGPT to generate one that fit my requirements. The generated script worked well, but I had to make a few adjustments.&lt;/p&gt;
&lt;p&gt;Here are the steps the script follows:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Parse the RSS feed of the podcast.&lt;/li&gt;
&lt;li&gt;Download the MP3 file for each episode.&lt;/li&gt;
&lt;li&gt;For each episode, extract metadata from the MP3 file and the RSS feed and save it in a markdown file.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I utilized the &lt;code&gt;rss-parser&lt;/code&gt; library to convert the RSS feed into JSON. This library only requires the feed&#39;s URL to function. I then extracted the MP3 download URL from this JSON and saved the file to my local disk. Using &lt;code&gt;music-metadata&lt;/code&gt;, I determined the duration and file size of the MP3 file, and combined this information with the data from the RSS feed. Finally, I used &lt;code&gt;js-yaml&lt;/code&gt; and &lt;code&gt;turndown&lt;/code&gt; to save this metadata as Front Matter in the Markdown file. The MP3 files are stored in an S3 bucket which I created manually.&lt;/p&gt;
&lt;p&gt;The tool is &lt;a href=&quot;https://github.com/dzenzes/podcast-processor&quot;&gt;available on GitHub&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;website-and-rss-feed&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://zenzes.me/owning-my-podcast-again/#website-and-rss-feed&quot;&gt;Website and RSS Feed&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To create the RSS feed, I followed &lt;a href=&quot;https://www.marclittlemore.com/create-an-eleventy-podcast-feed/&quot;&gt;this tutorial from Marc Littlemore&lt;/a&gt;. To avoid problems, I ensured that the new feed is identical to the old one.&lt;/p&gt;
&lt;p&gt;My final template looks like this:&lt;/p&gt;
&lt;pre class=&quot;language-xml&quot;&gt;&lt;code class=&quot;language-xml&quot;&gt;---
permalink: podcast/feed.xml
eleventyExcludeFromCollections: true
---
&lt;span class=&quot;token prolog&quot;&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;rss&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;&lt;span class=&quot;token namespace&quot;&gt;xmlns:&lt;/span&gt;itunes&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;http://www.itunes.com/dtds/podcast-1.0.dtd&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;&lt;span class=&quot;token namespace&quot;&gt;xmlns:&lt;/span&gt;media&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;http://search.yahoo.com/mrss/&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;&lt;span class=&quot;token namespace&quot;&gt;xmlns:&lt;/span&gt;atom&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;http://www.w3.org/2005/Atom&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;&lt;span class=&quot;token namespace&quot;&gt;xmlns:&lt;/span&gt;content&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;http://purl.org/rss/1.0/modules/content/&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;&lt;span class=&quot;token namespace&quot;&gt;xmlns:&lt;/span&gt;googleplay&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;http://www.google.com/schemas/play-podcasts/1.0&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;version&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;2.0&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;channel&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token namespace&quot;&gt;atom:&lt;/span&gt;link&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;href&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;https://pubsubhubbub.appspot.com/&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;rel&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;hub&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token namespace&quot;&gt;atom:&lt;/span&gt;link&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;href&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;{{metadata.url}}{{podcast.feedPath}}&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;rel&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token namespace&quot;&gt;atom:&lt;/span&gt;link&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;href&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;{{metadata.url}}{{podcast.feedPath}}&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;rel&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;first&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token namespace&quot;&gt;atom:&lt;/span&gt;link&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;href&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;{{metadata.url}}{{podcast.feedPath}}?page=1&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;rel&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;last&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;title&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;{{podcast.title}}&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;title&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;language&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;de&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;language&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;pubDate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;{{now}}&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;pubDate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;lastBuildDate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;{{collections.podcast | collectionLastUpdatedDate}}&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;lastBuildDate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;generator&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Eleventy&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;generator&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;description&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;{{podcast.description | xmlEscape}}&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;description&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;link&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;{{metadata.url}}&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;link&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token namespace&quot;&gt;itunes:&lt;/span&gt;type&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;episodic&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;token namespace&quot;&gt;itunes:&lt;/span&gt;type&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token namespace&quot;&gt;itunes:&lt;/span&gt;new-feed-url&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;{{metadata.url}}{{podcast.feedPath}}&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;token namespace&quot;&gt;itunes:&lt;/span&gt;new-feed-url&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;image&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
            &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;url&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;{{podcast.cover}}&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;url&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
            &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;title&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;{{podcast.title}}&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;title&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
            &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;link&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;{{metadata.url}}&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;link&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;image&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token namespace&quot;&gt;itunes:&lt;/span&gt;image&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;href&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;{{podcast.cover}}&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token namespace&quot;&gt;itunes:&lt;/span&gt;subtitle&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;token namespace&quot;&gt;itunes:&lt;/span&gt;subtitle&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token namespace&quot;&gt;itunes:&lt;/span&gt;author&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;{{metadata.author.name}}&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;token namespace&quot;&gt;itunes:&lt;/span&gt;author&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token namespace&quot;&gt;itunes:&lt;/span&gt;explicit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;no&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;token namespace&quot;&gt;itunes:&lt;/span&gt;explicit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token namespace&quot;&gt;itunes:&lt;/span&gt;keywords&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;token namespace&quot;&gt;itunes:&lt;/span&gt;keywords&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token namespace&quot;&gt;itunes:&lt;/span&gt;category&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;Technology&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token namespace&quot;&gt;itunes:&lt;/span&gt;category&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;Education&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
            &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token namespace&quot;&gt;itunes:&lt;/span&gt;category&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;How To&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;token namespace&quot;&gt;itunes:&lt;/span&gt;category&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token namespace&quot;&gt;itunes:&lt;/span&gt;summary&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;{{podcast.description}}&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;token namespace&quot;&gt;itunes:&lt;/span&gt;summary&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token namespace&quot;&gt;itunes:&lt;/span&gt;owner&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
            &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token namespace&quot;&gt;itunes:&lt;/span&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;{{metadata.author.name}}&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;token namespace&quot;&gt;itunes:&lt;/span&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
            &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token namespace&quot;&gt;itunes:&lt;/span&gt;email&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;{{metadata.author.email}}&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;token namespace&quot;&gt;itunes:&lt;/span&gt;email&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;token namespace&quot;&gt;itunes:&lt;/span&gt;owner&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
        {%- for post in collections.podcast | reverse %}
            {%- set absolutePostUrl = post.url | absoluteUrl(metadata.url) %}
            &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;item&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
                &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;title&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;{{ post.data.title }}&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;title&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
                &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token namespace&quot;&gt;itunes:&lt;/span&gt;title&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;{{ post.data.title }}&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;token namespace&quot;&gt;itunes:&lt;/span&gt;title&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
                &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;description&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;{{post.data.summary}}&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;description&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
                &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;pubDate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;{{ post.data.date | toRfc822Date }}&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;pubDate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
                &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;link&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;{{ absolutePostUrl }}&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;link&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
                &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;guid&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;isPermaLink&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;false&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;{{post.data.guid}}&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;guid&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
                &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token namespace&quot;&gt;content:&lt;/span&gt;encoded&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
                    &lt;span class=&quot;token cdata&quot;&gt;&amp;lt;![CDATA[{{post.content | htmlToAbsoluteUrls(absolutePostUrl)| safe}}]]&gt;&lt;/span&gt;
                &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;token namespace&quot;&gt;content:&lt;/span&gt;encoded&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
                &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token namespace&quot;&gt;itunes:&lt;/span&gt;episode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;{{post.data.episode}}&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;token namespace&quot;&gt;itunes:&lt;/span&gt;episode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
                &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token namespace&quot;&gt;itunes:&lt;/span&gt;episodeType&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;full&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;token namespace&quot;&gt;itunes:&lt;/span&gt;episodeType&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
                &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token namespace&quot;&gt;itunes:&lt;/span&gt;subtitle&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;{{post.data.subtitle}}&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;token namespace&quot;&gt;itunes:&lt;/span&gt;subtitle&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
                &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token namespace&quot;&gt;itunes:&lt;/span&gt;summary&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;{{post.data.summary}}&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;token namespace&quot;&gt;itunes:&lt;/span&gt;summary&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
                &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token namespace&quot;&gt;itunes:&lt;/span&gt;season&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;{{post.data.season}}&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;token namespace&quot;&gt;itunes:&lt;/span&gt;season&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
                &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token namespace&quot;&gt;itunes:&lt;/span&gt;explicit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;no&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;token namespace&quot;&gt;itunes:&lt;/span&gt;explicit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
                &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token namespace&quot;&gt;itunes:&lt;/span&gt;keywords&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;{{post.data.tags}}&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;token namespace&quot;&gt;itunes:&lt;/span&gt;keywords&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
                &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token namespace&quot;&gt;itunes:&lt;/span&gt;author&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;{{metadata.author.name}}&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;token namespace&quot;&gt;itunes:&lt;/span&gt;author&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
                &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;enclosure&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;{{podcast.cdn}}/{{post.data.mp3}}&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;audio/mpeg&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;{{post.data.fileSize}}&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;
                &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token namespace&quot;&gt;itunes:&lt;/span&gt;duration&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;{{post.data.duration}}&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;token namespace&quot;&gt;itunes:&lt;/span&gt;duration&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
            &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;item&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
        {%- endfor %}
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;channel&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;rss&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Since there is a Markdown file for each episode, I can also generate HTML from them using 11ty.&lt;/p&gt;
&lt;h2 id=&quot;creating-new-episodes&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://zenzes.me/owning-my-podcast-again/#creating-new-episodes&quot;&gt;Creating New Episodes&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;My editing process hasn&#39;t changed much: I prepare the MP3 files using Reaper/Ultrasound. I use a second script (similar to the one mentioned above) to generate the metadata and save it in a Markdown file. The episode is then uploaded to S3. Finally, I write the show notes, and everything is ready to be released.&lt;/p&gt;
&lt;h2 id=&quot;what-went-wrong&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://zenzes.me/owning-my-podcast-again/#what-went-wrong&quot;&gt;What Went Wrong&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Most things worked right away, and exporting from Podigee was straightforward. I updated the settings on iTunes and Spotify myself to be on the safe side, and everything was working. The only time I had problems was when I deleted my Podigee podcast after a week. For some reason, Podigee then deleted my old podcast from Spotify as well. I was able to undo this by adding my podcast to Spotify again. All the stats and URLs seem to be the same as before.&lt;/p&gt;
&lt;h2 id=&quot;conclusion&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://zenzes.me/owning-my-podcast-again/#conclusion&quot;&gt;Conclusion&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The export process was easier than anticipated and went smoothly. The new release process is actually better than the previous one. In the past, I had to share the MP3 file with my guests via file sharing and send them my show notes via email. Now, I can create a merge request on GitHub, and Netlify generates a preview that I can share with my guests for review.&lt;/p&gt;
&lt;p&gt;The next step is to create my own statistics to track how the podcast is developing. The current costs are reasonable, and the additional effort is manageable.&lt;/p&gt;
&lt;p&gt;Overall, I still believe that Podigee is a good tool to host your own podcast. However, it was an interesting experience to host the podcast myself again and adjust my process. I&#39;m happy with the current state of the podcast and the simplified release process.&lt;/p&gt;
</description>
        <pubDate>Thu, 20 Apr 2023 08:35:00 +0200</pubDate>
        <dc:creator>Daniel Zenzes</dc:creator>
        <guid>https://zenzes.me/owning-my-podcast-again/</guid>
      </item>
      <item>
        <title>Some updates for April 2023</title>
        <link>https://zenzes.me/some-updates-for-april-2023/</link>
        <description>&lt;p&gt;April has started with a few minor updates that I&#39;d like to share here on the blog.&lt;/p&gt;
&lt;h2 id=&quot;new-ready-for-review-episodes&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://zenzes.me/some-updates-for-april-2023/#new-ready-for-review-episodes&quot;&gt;New Ready for Review episodes&lt;/a&gt;&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https://ready-for-review.dev/2023/04/01/rfr044-devops-gibts-nicht/&quot;&gt;&amp;quot;Rfr044 - DevOps? Gibts nicht!&amp;quot;&lt;/a&gt; - Here we talked about two articles from this blog. &lt;a href=&quot;https://zenzes.me/strategy-vs-tactics-in-software-development/&quot;&gt;Strategy vs Tactics in Software Development&lt;/a&gt; and &lt;a href=&quot;https://zenzes.me/unlocking-productivity-understanding-the-importance-of-developer-experience/&quot;&gt;Unlocking Productivity: Understanding the Importance of Developer Experience&lt;/a&gt;. This episode complements both articles.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://ready-for-review.dev/2023/04/12/rfr045-engelsklang-und-teufelszeug/&quot;&gt;&amp;quot;Rfr045 - Engelsklang und Teufelszeug&amp;quot;&lt;/a&gt; - In this episode Sandra and I have some news and links to share. I gave an overview of build tools in the JavaScript ecosystem there and talked a bit about the history of them. I plan to post something about this on this blog as well.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;herr-zenzes-wills-wissen&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://zenzes.me/some-updates-for-april-2023/#herr-zenzes-wills-wissen&quot;&gt;Herr Zenzes wills wissen&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I released a new episode for &lt;a href=&quot;https://zenzes.me/podcast/&quot;&gt;Herr Zenzes wills wissen&lt;/a&gt; and &lt;a href=&quot;https://zenzes.me/podcast/hzww47-reboot/&quot;&gt;announced a reboot&lt;/a&gt;. The first recordings will follow here in the coming weeks, and I&#39;m looking forward to filling the podcast with life again.&lt;/p&gt;
&lt;p&gt;In parallel, I migrated the podcast from my old provider Podigee to my own solution. While Podigee makes sense for &amp;quot;Ready for Review&amp;quot;, it&#39;s rather overkill for &amp;quot;Herr Zenzes wills wissen&amp;quot;. I plan to describe how I did the migration here on the blog as well.&lt;/p&gt;
&lt;h2 id=&quot;and-what-else%3F&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://zenzes.me/some-updates-for-april-2023/#and-what-else%3F&quot;&gt;And what else?&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Over Easter, I was sick, which is why I didn&#39;t get to do much. In the following days and weeks there will be more content on this blog.&lt;/p&gt;
</description>
        <pubDate>Fri, 14 Apr 2023 07:58:00 +0200</pubDate>
        <dc:creator>Daniel Zenzes</dc:creator>
        <guid>https://zenzes.me/some-updates-for-april-2023/</guid>
      </item>
      <item>
        <title>Making Estimates Work for Your Development Team</title>
        <link>https://zenzes.me/making-estimates-work-for-your-development-team/</link>
        <description>&lt;p&gt;There are topics in the IT world that divide opinions: what needs to be tested, test-driven development, do we work alone, in pairs or even in a mob? Do we need estimates for tickets?&lt;/p&gt;
&lt;p&gt;Today I want to discuss estimates and why I think they are essential in a dev team. I realize many developers see it differently because estimates have an awful reputation. Critics say that they don&#39;t bring much to the team, take a lot of time in meetings and at the end &amp;quot;management&amp;quot; gets a statement when which feature is (guaranteed) available. In the sprint, people are then also quick to talk about why a supposedly small task is taking a long time. So, we have something that costs us a lot of time as developers and makes life difficult afterward because someone converts story points into time. And sure, if that&#39;s how estimates are lived in team, then I would question them in that form as well. But estimates can also be useful, help the team and help to plan things.&lt;/p&gt;
&lt;p&gt;For me, estimates are always good when they help to understand a problem. To achieve that, you need a stable team, some time and the following techniques:&lt;/p&gt;
&lt;h2 id=&quot;reference-stories&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://zenzes.me/making-estimates-work-for-your-development-team/#reference-stories&quot;&gt;Reference Stories&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;No matter how a team estimates, they should have a reference story for each story size. That is, a story that the team knows and ideally the scope of the task. Then, when a story is estimated, the reference stories should be used as a comparison. This leads to better discussions because we are comparing a task to something we already know. If the team then differs on the estimate, then you can compare the new story to the reference story. By the way, reference stories should always be questioned by the team and replaced with better ones if necessary. It is important that everybody within the team knows the story. Alternatively, you can use other stories that the team has appreciated.&lt;/p&gt;
&lt;h3 id=&quot;identify-reference-stories&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://zenzes.me/making-estimates-work-for-your-development-team/#identify-reference-stories&quot;&gt;Identify reference stories&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;When I started a new team, I always tried to identify reference stories in the first sprints. To accomplish this, we first estimated stories &amp;quot;by gut feeling&amp;quot; and then corrected the story points again after the sprint. After a few sprints, we had a good set of stories. If the team changes, then it could make sense to talk about new reference stories, too. If the team identifies a story as a good reference story after the sprint (maybe for a different estimate), then you can use it as such.&lt;/p&gt;
&lt;h2 id=&quot;don&#39;t-estimate-for-others&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://zenzes.me/making-estimates-work-for-your-development-team/#don&#39;t-estimate-for-others&quot;&gt;Don&#39;t estimate for others&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;When it comes to estimating, first someone presents the story (it doesn&#39;t have to be the product owner) and then everyone gives their own estimate. Three rules are important:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;everyone estimates based on the reference stories.&lt;/li&gt;
&lt;li&gt;it is not about time (more about that later). It&#39;s about which reference story fits the new story in terms of complexity.&lt;/li&gt;
&lt;li&gt;everybody estimates for themselves personally and not the team or the developer, who would do it very fast.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;It&#39;s okay if the backend developer estimates a task with more story points for the frontend story or the new team member picks a higher number because they don&#39;t know everything. This shows that there is a certain risk because some people see this task as more complex than others. This still helps in estimating the task.&lt;/p&gt;
&lt;p&gt;Sometimes, story points are very close and you can agree on a number. This is a good indicator that everybody has a similar understanding of the task and there is no need to talk about the complexity. Sometimes, you see significant differences and this is, when it comes to the most important part of the session: talking about estimates.&lt;/p&gt;
&lt;h2 id=&quot;talking-about-estimates&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://zenzes.me/making-estimates-work-for-your-development-team/#talking-about-estimates&quot;&gt;Talking about estimates&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Usually, this starts with the people with the biggest and lowest estimate sharing their reasons for picking the story points. Now the team can talk about complexity and what are the important things for the story (or, if there is no big difference, agree on a number and go on).&lt;/p&gt;
&lt;p&gt;After all, this is where it often becomes clear if someone perceives a problem as too complex or someone didn&#39;t fully understand a story. The team can then discuss the scope of the story, ask clarifying questions, and add to the story accordingly. Often, the person presenting the story can also make minor adjustments here to ensure that a topic is implemented as envisioned.&lt;/p&gt;
&lt;p&gt;After that, you can estimate one more time, and maybe you already have a similar estimate. If only certain people in the team can implement a story (that&#39;s a topic for another article), then you can pragmatically note that for now (as long as not every story is directly assigned ... but yes, other topic). If there is still a big difference, there are open questions, and you should clarify those.&lt;/p&gt;
&lt;p&gt;Sometimes, you cannot find a common size. In this case, maybe the person who introduced the story can change it in a way that allows you to work on it in the next sprint (perhaps you want to do a Spike on the topic, might be you can start with a small subset of the original planned features...). The important learning is, that you identified some problems and now is the perfect time to address them.&lt;/p&gt;
&lt;p&gt;For me as a developer, estimates then already served their purpose. Maybe it would be best to lock the numbers away now because we still have the problem with the time that can be derived from story points. But perhaps, we can improve this, too?&lt;/p&gt;
&lt;h2 id=&quot;1-story-point-can&#39;t-be-converted-to-time%2C-30-possibly-can.&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://zenzes.me/making-estimates-work-for-your-development-team/#1-story-point-can&#39;t-be-converted-to-time%2C-30-possibly-can.&quot;&gt;1 story point can&#39;t be converted to time, 30 possibly can.&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;One thing first: it is totally nonsensical in my opinion, in a new team or after adjusting the way the team estimates, to derive any times from estimates. A story point can represent a straight-forward but time-consuming task. If a team has a velocity of 30, it may manage 40 stories that are one story point in size, but only one story with 20 story points.&lt;/p&gt;
&lt;p&gt;When we discuss timing, the first requirement is that the stories are not too big and not too small. If you look at the story points of a story and when they were solved during the sprint, you can quickly see if they were done evenly over the sprint (optimal) or before the review (not so good) (burn down diagram). In my opinion, it is the task of the product owner to find the right mix with the team so that, ideally, value is delivered continuously.&lt;/p&gt;
&lt;p&gt;After a few sprints, the velocity of the team becomes apparent. In my previous teams, this was the case after about 6 sprints of 2 weeks, but it can also take a little longer. If I know the velocity, the product owner can also make predictions when (estimated) future stories can be delivered. This is some mathematics coupled with a certain buffer, so that a deviating sprint (vacation, illness or a bad sprint) does not immediately throw the entire planning over the heap.&lt;/p&gt;
&lt;h2 id=&quot;bonus-content%3A-quick-to-a-rough-estimate.&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://zenzes.me/making-estimates-work-for-your-development-team/#bonus-content%3A-quick-to-a-rough-estimate.&quot;&gt;Bonus content: quick to a rough estimate.&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;When I need to estimate in a new team, I use a formula for a rough estimate: &amp;quot;number of areas I need to adjust&amp;quot; * 2. An &amp;quot;area&amp;quot; is something like frontend, backend or infrastructure. So an area where changes are needed. A pure frontend story is more like 2 story points, if I also have to do something on the backend and on the infrastructure, I pick something around 6 story points. If an area is particularly complex, I count it twice. This is a milkmaid calculation that only serves as a first rough estimate. I ignore the factor time and focus on complexity here.&lt;/p&gt;
&lt;h2 id=&quot;it-is-all-about-your-environment-and-context&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://zenzes.me/making-estimates-work-for-your-development-team/#it-is-all-about-your-environment-and-context&quot;&gt;It is all about your environment and context&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The approach I describe here only works in a trusting environment where everyone is interested in delivering value and the pressure to plan everything to the minute is manageable. I find estimates good to have a basis for discussion so that we have the same understanding in the team and can avoid misunderstandings early on. In environments where estimation makes your own work more complicated, I would think about doing a slimmed down form of estimation in the dev team: talk about the complexity of the next stories and which stories you know that were comparable.&lt;/p&gt;
&lt;p&gt;How do you handle estimates in your team? If you don&#39;t estimate, how do you ensure that, the important discussions are held? Feel free to sent me a message &lt;a href=&quot;https://chaos.social/@danielzenzes&quot; title=&quot;Daniel Zenzes on Mastodon&quot;&gt;on Mastodon&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;PS: I use the terms Sprint and Product Owner here, but the whole thing is not limited to Scrum.&lt;/p&gt;
</description>
        <pubDate>Tue, 28 Mar 2023 14:34:00 +0200</pubDate>
        <dc:creator>Daniel Zenzes</dc:creator>
        <guid>https://zenzes.me/making-estimates-work-for-your-development-team/</guid>
      </item>
      <item>
        <title>Mastering your Zsh configuration with Antigen and Oh-My-Zsh</title>
        <link>https://zenzes.me/mastering-your-zsh-configuration-with-antigen-and-oh-my-zsh/</link>
        <description>&lt;p&gt;&lt;a href=&quot;https://www.zsh.org/&quot; title=&quot;Official Zsh website&quot;&gt;Zsh&lt;/a&gt; (default on macOS) and &lt;a href=&quot;https://ohmyz.sh/&quot; title=&quot;Official &#39;Oh my Zsh&#39; website&quot;&gt;Oh My Zsh&lt;/a&gt; are among the tools I set up first on every machine. Yesterday I took a look at &lt;a href=&quot;https://antigen.sharats.me/&quot; title=&quot;Official Antigen website&quot;&gt;Antigen&lt;/a&gt;, a plugin manager for Zsh, and I was impressed with how well it simplified my previous configuration.&lt;/p&gt;
&lt;p&gt;So far, I have always installed Oh My Zsh manually. To do this, you run the following command, and you are actually ready to go:&lt;/p&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;sh&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-c&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token variable&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-fsSL&lt;/span&gt; https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh&lt;span class=&quot;token variable&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;installing-plugins-manually&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://zenzes.me/mastering-your-zsh-configuration-with-antigen-and-oh-my-zsh/#installing-plugins-manually&quot;&gt;Installing Plugins manually&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Well I still have a few plugins that I would like to use. For example I use &lt;a href=&quot;https://github.com/zsh-users/zsh-autosuggestions&quot; title=&quot;GitHub repository of zsh-autosuggestions&quot;&gt;zsh-autosuggestions&lt;/a&gt; and the installation is relatively straightforward:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;clone the repository into &lt;code&gt;$ZSH_CUSTOM/plugins&lt;/code&gt;&lt;/li&gt;
&lt;/ol&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;git&lt;/span&gt; clone https://github.com/zsh-users/zsh-autosuggestions &lt;span class=&quot;token variable&quot;&gt;${ZSH_CUSTOM&lt;span class=&quot;token operator&quot;&gt;:-&lt;/span&gt;~&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;.oh-my-zsh&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;custom}&lt;/span&gt;/plugins/zsh-autosuggestions&lt;/code&gt;&lt;/pre&gt;
&lt;ol start=&quot;2&quot;&gt;
&lt;li&gt;Add the plugin to the list of plugins for Oh My Zsh to load (inside &lt;code&gt;~/.zshrc&lt;/code&gt;):&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;plugins=(
    # other plugins...
    zsh-autosuggestions
)
&lt;/code&gt;&lt;/pre&gt;
&lt;ol start=&quot;3&quot;&gt;
&lt;li&gt;start a new terminal session&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This is not particularly difficult at all, and I have worked successfully with this procedure for many years. However, the whole approach has a few disadvantages:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;the installation is always manual work&lt;/li&gt;
&lt;li&gt;the whole setup is complicated to port (I don&#39;t like to back up my &lt;code&gt;.oh-my-zsh&lt;/code&gt; folder somewhere)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Yesterday I came across Antigen, a plugin manager for Zsh that makes working with plugins easier.&lt;/p&gt;
&lt;h2 id=&quot;setting-up-zsh-and-%22oh-my-zsh%22-with-antigen&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://zenzes.me/mastering-your-zsh-configuration-with-antigen-and-oh-my-zsh/#setting-up-zsh-and-%22oh-my-zsh%22-with-antigen&quot;&gt;Setting up Zsh and &amp;quot;Oh my Zsh&amp;quot; with Antigen&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I can save the Oh my Zsh installation and also everything else for now (I only need Zsh). You can install antigen by hand (&lt;code&gt;curl -L git.io/antigen &amp;gt; antigen.zsh&lt;/code&gt;) or you can use homebrew like me (&lt;code&gt;brew install antigen&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;After that, you can work directly in &lt;code&gt;.zshrc&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# antigen path when using Homebrew:
source $(brew --prefix)/share/antigen/antigen.zsh

# if you installed antigen using curl:
# source /path-to-antigen/antigen.zsh

# Load the oh-my-zsh&#39;s library.
antigen use oh-my-zsh

# load plugins
antigen bundle git
antigen bundle node
antigen bundle npm
antigen bundle zsh-users/zsh-autosuggestions
antigen bundle zdharma-continuum/fast-syntax-highlighting
antigen bundle djui/alias-tips

# Load the theme.
# my personal theme
antigen theme dzenzes/danielzenzes.zsh-theme --branch=main
# something more popular:
# antigen theme robbyrussell

# Tell Antigen that you&#39;re done
antigen apply

# more configuration
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It&#39;s important to add the &lt;code&gt;antigen apply&lt;/code&gt; at the end. For most plugins, you can find instructions on how to install them with antigen in their GitHub repository.&lt;/p&gt;
&lt;h2 id=&quot;themes&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://zenzes.me/mastering-your-zsh-configuration-with-antigen-and-oh-my-zsh/#themes&quot;&gt;Themes&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;It took me a bit longer to install my theme: So far I used a customized copy of Stefan Judis&#39; theme (&lt;a href=&quot;https://www.stefanjudis.com/blog/declutter-emojify-and-prettify-your-iterm2-terminal/&quot; title=&quot;Post: Settings to emojify and prettify your terminal (iTerm2 &amp;amp; ZSH)&quot;&gt;Blogpost&lt;/a&gt;). I copied the theme manually into my &lt;code&gt;.oh-my-zsh&lt;/code&gt; folder. 🙈&lt;/p&gt;
&lt;p&gt;As part of my switch to Antigen, I uploaded the theme to a &lt;a href=&quot;https://github.com/dzenzes/danielzenzes.zsh-theme&quot; title=&quot;My Zsh Theme on GitHub&quot;&gt;repository&lt;/a&gt; and can now install it by referencing the repository in my configuration. The whole thing only works for me if I explicitly include the branch.&lt;/p&gt;
&lt;p&gt;All in all, I am very happy with the setup right now. The only manual step at the moment is to run &lt;code&gt;antigen update&lt;/code&gt; in the terminal occasionally to keep the plugins up to date (which should be possible to automate).&lt;/p&gt;
&lt;p&gt;How do you use Zsh and what plugins can you recommend? Feel free to sent me a message &lt;a href=&quot;https://chaos.social/@danielzenzes&quot; title=&quot;Daniel Zenzes on Mastodon&quot;&gt;on Mastodon&lt;/a&gt;&lt;/p&gt;
</description>
        <pubDate>Thu, 23 Mar 2023 07:37:00 +0100</pubDate>
        <dc:creator>Daniel Zenzes</dc:creator>
        <guid>https://zenzes.me/mastering-your-zsh-configuration-with-antigen-and-oh-my-zsh/</guid>
      </item>
      <item>
        <title>Generating _redirects in 11ty</title>
        <link>https://zenzes.me/generating-redirects-in-11ty/</link>
        <description>&lt;p&gt;Today I updated an article that is about &lt;a href=&quot;https://zenzes.me/how-to-automate-switching-nodejs-versions-with-nvm-and-zsh/&quot; title=&quot;Permalink: Article How to automate switching Node.js versions with nvm and zsh&quot;&gt;automatically switching Node.js version with nvm&lt;/a&gt;. In the course of this I wanted to delete two old articles and bring them to the current article via an HTTP redirect.&lt;/p&gt;
&lt;p&gt;As I host my blog on Netlify, &lt;a href=&quot;https://docs.netlify.com/routing/redirects/&quot; title=&quot;Netlify documentation on redirects&quot;&gt;all I need is a &lt;code&gt;_redirects&lt;/code&gt; file with the redirects&lt;/a&gt;:&lt;/p&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;
/old-url/    /new-url/
/old-url-2/    /new-url/&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;At first I wanted to create this by hand, but then I came across &lt;a href=&quot;https://www.aleksandrhovhannisyan.com/blog/eleventy-netlify-redirects/&quot; title=&quot;Article: Automate Netlify Redirects in 11ty&quot;&gt;an article by Aleksandr&lt;/a&gt; and now I generate the file automatically. The great thing is: I can specify in my articles, which pages should link to the respective article.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;_redirects&lt;/code&gt; file is generated out of my template file &lt;code&gt;redirects.njk&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;---
permalink: /_redirects
eleventyExcludeFromCollections: true
---
{%- for page in collections.all -%}
    {%- if page.url and page.data.redirectFrom -%}
        {%- for oldUrl in page.data.redirectFrom %}
{{ oldUrl }}    {{ page.url }}
        {%- endfor -%}
    {%- endif -%}
{%- endfor -%}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To get the &lt;code&gt;_redirects&lt;/code&gt; file mentioned above I define &lt;code&gt;redirectFrom&lt;/code&gt; in the front matter of my new article&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;redirectFrom:
  - /old-url/
  - /old-url-2/
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I enjoy using &lt;a href=&quot;https://www.11ty.dev/&quot; title=&quot;11ty homepage&quot;&gt;11ty&lt;/a&gt; and it is great how far you can get with it.&lt;/p&gt;
</description>
        <pubDate>Wed, 15 Mar 2023 10:50:00 +0100</pubDate>
        <dc:creator>Daniel Zenzes</dc:creator>
        <guid>https://zenzes.me/generating-redirects-in-11ty/</guid>
      </item>
      <item>
        <title>How to automate switching Node.js versions with nvm and zsh</title>
        <link>https://zenzes.me/how-to-automate-switching-nodejs-versions-with-nvm-and-zsh/</link>
        <description>&lt;p&gt;As a frontend developer, you may find yourself working on projects that require different versions of Node.js. Manually switching between versions can be tedious and easy to forget, especially if you&#39;re working on multiple projects simultaneously. Fortunately, there&#39;s a way to automate switching to the correct Node.js version whenever you enter the project directory. In this post, I&#39;ll show you how to set up auto-switching using nvm and zsh.&lt;/p&gt;
&lt;h2 id=&quot;prerequisites&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://zenzes.me/how-to-automate-switching-nodejs-versions-with-nvm-and-zsh/#prerequisites&quot;&gt;Prerequisites&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Before we dive in, you&#39;ll need to have the following installed on your machine:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;zsh&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://zenzes.me/how-to-automate-switching-nodejs-versions-with-nvm-and-zsh/%22https://github.com/nvm-sh/nvm%22&quot; title=&quot;Permalink: nvm GitHub Page&quot;&gt;nvm&lt;/a&gt; (Node Version Manager)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you don&#39;t have nvm installed, you can find instructions on the &lt;a href=&quot;https://zenzes.me/how-to-automate-switching-nodejs-versions-with-nvm-and-zsh/%22https://github.com/nvm-sh/nvm%22&quot; title=&quot;Permalink: nvm GitHub Page&quot;&gt;nvm GitHub page&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;setting-up-auto-switching&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://zenzes.me/how-to-automate-switching-nodejs-versions-with-nvm-and-zsh/#setting-up-auto-switching&quot;&gt;Setting up auto-switching&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Assuming you have nvm and Zsh installed, here&#39;s how to set up auto-switching:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;In the root directory of your project, create a &lt;code&gt;.nvmrc&lt;/code&gt; file and add the version of Node.js you want to use. For example, if your project requires Node.js version 18.15.0, add 18.15.0 to the &lt;code&gt;.nvmrc&lt;/code&gt; file.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Open your &lt;code&gt;.zshrc&lt;/code&gt; file in your favorite text editor (e.g. &lt;code&gt;vim ~/.zshrc&lt;/code&gt;).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Add the following lines at the end of the &lt;code&gt;.zshrc&lt;/code&gt; file:&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;autoload &lt;span class=&quot;token parameter variable&quot;&gt;-U&lt;/span&gt; add-zsh-hook
&lt;span class=&quot;token function-name function&quot;&gt;load-nvmrc&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 builtin class-name&quot;&gt;local&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;node_version&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token variable&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$(&lt;/span&gt;nvm version&lt;span class=&quot;token variable&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;
  &lt;span class=&quot;token builtin class-name&quot;&gt;local&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;nvmrc_path&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token variable&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$(&lt;/span&gt;nvm_find_nvmrc&lt;span class=&quot;token variable&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&quot;&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 parameter variable&quot;&gt;-n&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token variable&quot;&gt;$nvmrc_path&lt;/span&gt;&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 keyword&quot;&gt;then&lt;/span&gt;
    &lt;span class=&quot;token builtin class-name&quot;&gt;local&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;nvmrc_node_version&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$(&lt;/span&gt;nvm version &lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token variable&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;cat&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token variable&quot;&gt;${nvmrc_path}&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;)&lt;/span&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 string&quot;&gt;&quot;&lt;span class=&quot;token variable&quot;&gt;$nvmrc_node_version&lt;/span&gt;&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;N/A&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 keyword&quot;&gt;then&lt;/span&gt;
      nvm &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;elif&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token variable&quot;&gt;$nvmrc_node_version&lt;/span&gt;&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token variable&quot;&gt;$node_version&lt;/span&gt;&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 keyword&quot;&gt;then&lt;/span&gt;
      nvm use
    &lt;span class=&quot;token keyword&quot;&gt;fi&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;elif&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token variable&quot;&gt;$node_version&lt;/span&gt;&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token variable&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$(&lt;/span&gt;nvm version default&lt;span class=&quot;token variable&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&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 keyword&quot;&gt;then&lt;/span&gt;
    &lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Reverting to nvm default version&quot;&lt;/span&gt;
    nvm use default
  &lt;span class=&quot;token keyword&quot;&gt;fi&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
add-zsh-hook chpwd load-nvmrc
load-nvmrc
&lt;/code&gt;&lt;/pre&gt;
&lt;ol start=&quot;4&quot;&gt;
&lt;li&gt;
&lt;p&gt;Save and close the &lt;code&gt;.zshrc&lt;/code&gt; file.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Restart your terminal or run source &lt;code&gt;~/.zshrc&lt;/code&gt; for the changes to take effect.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;That&#39;s it! Now, whenever you enter your project&#39;s directory, the zsh-hook we defined in your &lt;code&gt;~/.zshrc&lt;/code&gt; file will automatically switch to the Node.js version specified in the project&#39;s &lt;code&gt;.nvmrc&lt;/code&gt; file. This ensures that you are always using the correct version of Node.js for your project without needing to manually switch versions every time you enter the directory. In every other directory this will switch to your default Node.js version.&lt;/p&gt;
&lt;p&gt;I hope this post has been helpful. If you know a better alternative, please reach out to me on &lt;a href=&quot;https://chaos.social/@danielzenzes&quot;&gt;Mastodon&lt;/a&gt;. Happy coding!&lt;/p&gt;
</description>
        <pubDate>Wed, 15 Mar 2023 09:50:00 +0100</pubDate>
        <dc:creator>Daniel Zenzes</dc:creator>
        <guid>https://zenzes.me/how-to-automate-switching-nodejs-versions-with-nvm-and-zsh/</guid>
      </item>
      <item>
        <title>Choosing your next framework</title>
        <link>https://zenzes.me/choosing-your-next-framework/</link>
        <description>&lt;p&gt;In one of my previous articles I described the &lt;a href=&quot;https://zenzes.me/strategy-vs-tactics-in-software-development/&quot; title=&quot;Permalink: Strategy vs Tactics in Software Development&quot;&gt;difference between strategy and tactics in software development&lt;/a&gt;. In this post I want to describe, what can go wrong, if you focus on tactics and ignore the overall strategy. Lets take a situation I have seen at many companies: a new project is born and some people can create something from scratch. Most of the times this means that technology decisions that have been made before, can be questioned and the new scope maybe allows to try out something new. Maybe something that is easier to use or faster to setup. This can have both positive and negative consequences:&lt;/p&gt;
&lt;p&gt;On the positive side, this approach could lead to increased productivity and faster development times. If the new technology allows you to work more efficiently and effectively, it may be easier for you to deliver features and functionality quickly, which can be a significant benefit for the organization. Additionally, by exploring new technologies and frameworks, you may bring fresh ideas and perspectives to the project, which can contribute to innovation and improve the overall quality of the software. I love exploring new languages and frameworks because they help me to get a new view on some problems and learning the concepts here makes me a better developer.&lt;/p&gt;
&lt;p&gt;However, there are also potential negative consequences of this approach. Firstly, if you choose to use a different technology from the rest of your company, it could create a fragmentation of knowledge and skills within the organization. This could lead to communication problems, knowledge silos, and even conflicts between team members who may have different ideas and opinions on which framework is better. Additionally, it may also result in additional costs for the company to maintain multiple frameworks and provide support for different development teams.&lt;/p&gt;
&lt;p&gt;Secondly, if you choose a new framework without involving the rest of the team, you may be creating additional technical debt. Technical debt is the cost of fixing or reworking code in the future due to shortcuts taken during development. If you choose a new framework without considering the long-term implications or how it fits into the larger technical architecture of the company, you may end up creating technical debt that will need to be addressed later.&lt;/p&gt;
&lt;p&gt;Finally, you have to learn it. There will be new challenges that come with the new technology and maybe easy solutions that worked before, will not. So, somehow you start from scratch, which can be a cool experience, but it can be some hard work, too. Please keep in mind that not only you have to do it, everybody in your team or company needs to learn it. This can be a great opportunity to work together, or super frustrating for your colleagues and maybe even your company if feature development slows down.&lt;/p&gt;
&lt;p&gt;In summary, while exploring new technologies and frameworks can lead to innovation and productivity gains, it is important to consider the implications of choosing a different technology from the rest of the team. To avoid potential negative consequences, it may be beneficial to involve the rest of the team in the decision-making process, evaluate the long-term implications, and ensure that the chosen technology fits into the overall technical architecture of the company.&lt;/p&gt;
&lt;p&gt;My best experience with the introduction of new technologies has been when they have been supported by as many people as possible. Ideally, there are some colleagues in the team or the company who are happy to get to grips with something new and then actively support the decision, even if there are problems at the beginning.&lt;/p&gt;
</description>
        <pubDate>Fri, 10 Mar 2023 09:07:00 +0100</pubDate>
        <dc:creator>Daniel Zenzes</dc:creator>
        <guid>https://zenzes.me/choosing-your-next-framework/</guid>
      </item>
      <item>
        <title>Redefining Developer Experience</title>
        <link>https://zenzes.me/redefining-developer-experience/</link>
        <description>&lt;p&gt;Cole Peters (&lt;a href=&quot;https://mastodon.online/@colepeters&quot; title=&quot;Cole Peters on Mastodon&quot;&gt;@colepeters@mastodon.online&lt;/a&gt;) on &lt;a href=&quot;https://begin.com/blog/posts/2023-02-28-redefining-developer-experience&quot;&gt;begin.com&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;For years now, the most popular JS frameworks have carried out intense marketing initiatives based on the premise of improving DX&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The whole thing goes, however, as in other ecosystems that developers categorically exclude other frameworks as &amp;quot;bad&amp;quot; and some now and then only see the next nail they can hammer.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;My toolchain consisted of HTML (version 4), CSS (version 2), and a sprinkling of jQuery on those rare occasions when I could understand how to use it.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Those were the days. I still fondly remember one of my first jobs, where we uploaded our .jars (built by Jenkins, after all) to the production server via FTP. Don&#39;t worry, I&#39;m not suggesting that now as the better alternative to a CI/CD pipeline. However, I did learn a few things about Java and application servers there that still help me today.&lt;/p&gt;
&lt;p&gt;The same goes for jQuery and co: HTML and CSS I learned from books, and jQuery was at that time™ &lt;em&gt;finally&lt;/em&gt; a way to use JavaScript sensibly. AJAX was a phenomenon... but back to the actual topic.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I’d learned to wield several major versions of React with substantial expertise (starting with class components, then function components, then hooks…), along with the wider React ecosystem. React Router, Redux, Redux Select, Redux Saga, the Context API, XState, React Query, Styled Components, Styled System, Radix, React Spring, Framer Motion, React DND, DNDKit, Jest, Enzyme, React Testing Library, NextJS, and others were all under my belt, and in most cases my experience in using them tended toward the skilled end of the spectrum. And this was just to render and test UI!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Deeper under the hood, I was working with NPM, Babel and Webpack to manage packages and builds (having previously worked with tools like Bower, Grunt, and Gulp), and deployment providers like Heroku and Vercel. Of course, all of this was managed through GitHub version control, with some of the pipeline instrumented with GitHub Packages and Actions, and with everything running through ESLint and Prettier to catch formatting inconsistencies, opportunities for optimization, and potential bugs. Underlying all of this were my ongoing efforts to stay on top of developments in HTML, CSS, and JS/ES-What-Year-Is-This, including aspects like accessibility and performance, but also with respect to concepts like functional programming and frontend architecture in general.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Web development is often &lt;s&gt;too&lt;/s&gt; more complicated than necessary. Look at the amount of libraries and frameworks you need today, regardless of ecosystem, to build a simple single page application. The trend to move this to the server now (looking at you, Next, Nuxt, Remix and friends) may make the whole thing incredibly fast but may inflate it unnecessarily. There is an alternative, which we should perhaps seriously consider as an option more often.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;It’s true that many modern JavaScript frameworks began as attempts to fill in some gaps in web standards, but in 2023, many of those gaps have been filled by the web standards themselves. HTML now has templates and custom elements, CSS has an incredible range of APIs for animation and complex, dynamic, and responsive layouts, and JavaScript itself has evolved to become a powerful programming language without the need for supersets or frameworks.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Browsers, meanwhile, have become better at converging on implementations (for the most part, anyway… WebKit has some catching up to do) and at offering built in optimizations like back/forward caching, and they automatically update so that end users have access to the best new features. Cloud based deployment solutions and general increases in global internet speeds have done much to mitigate slow response times (providing you’re not shipping megabytes of JavaScript over the wire), allowing multi-page applications to become just as fast (if not faster overall) than single page applications.&lt;/p&gt;
&lt;/blockquote&gt;
</description>
        <pubDate>Thu, 09 Mar 2023 08:10:00 +0100</pubDate>
        <dc:creator>Daniel Zenzes</dc:creator>
        <guid>https://zenzes.me/redefining-developer-experience/</guid>
      </item>
      <item>
        <title>Unlocking Productivity: Understanding the Importance of Developer Experience</title>
        <link>https://zenzes.me/unlocking-productivity-understanding-the-importance-of-developer-experience/</link>
        <description>&lt;p&gt;As a member of a developer experience team, I often get asked what I do, and why it is important for a company. The truth is that developer experience (DX) is a critical aspect of software development that impacts the productivity, efficiency, and satisfaction of developers. In this blog post, I want to shed some light on what DX is, why it matters, and some of the benefits as well as negative aspects of having a DX team in place.&lt;/p&gt;
&lt;h2 id=&quot;what-does-developer-experience-mean-and-what-does-it-provide%3F&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://zenzes.me/unlocking-productivity-understanding-the-importance-of-developer-experience/#what-does-developer-experience-mean-and-what-does-it-provide%3F&quot;&gt;What does Developer Experience mean and what does it provide?&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Developer Experience, commonly abbreviated as &lt;em&gt;DX&lt;/em&gt;, refers to the overall experience a developer has while working on a software project, from initial setup and configuration to ongoing maintenance and support. The term is often used to describe the quality of the tools, processes, and resources that are available to developers, as well as the ease with which they can use them to accomplish their tasks.&lt;/p&gt;
&lt;p&gt;In daily business a DX team can provide the following things:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;📗 Clear and concise documentation: DX teams can create and maintain documentation that is easy to read, organized, and up-to-date, making it easier for developers to understand how to use tooling and technologies. This helps developers a lot to get started and learn about new tooling. We are currently accompanying a migration project and an important task here is to document our learnings on the migration strategy and evaluated tools, that can support us.&lt;/li&gt;
&lt;li&gt;🛠️ Developer tools and resources: DX teams can create and maintain development tools and resources that make it easier for developers to write, test, and deploy code, such as integrated development environments (IDEs), debuggers, and test frameworks. While we leave the decision, which IDE our developers use to them, we provide documentation for the most common IDEs. We are currently providing a monitoring solution for our developers and try to make the usage as easy as possible, e.g., we are integrating it into our company chat and offer some trainings for developers to get started with it. However, we are not the platform or infrastructure team that provides the software, but rather our role is to configure and integrate the solutions and support the developers in their use.&lt;/li&gt;
&lt;li&gt;⚙️ Workflow automation: DX teams can identify tasks that are repetitive or manual and automate them to streamline the development process and reduce the risk of errors. So we are providing blueprints for pipelines, so developers can start with new projects easily. For some tooling, we provide some basic configuration, which can be used in existing and new projects. The important thing here is that we offer something, that can be used, but nobody is forced to use it. And if we don&#39;t offer something, we are happy to support our developers to create something new which later can become a blueprint, too.&lt;/li&gt;
&lt;li&gt;🧑‍🏫 Training and support: DX teams can provide training and support resources to help developers learn new tools and workflows and troubleshoot issues. Like already described for the monitoring solution, we always try to support our developers with tooling.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;benefits-of-having-a-dx-team&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://zenzes.me/unlocking-productivity-understanding-the-importance-of-developer-experience/#benefits-of-having-a-dx-team&quot;&gt;Benefits of having a DX team&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;I think having a DX team can give a lot of benefits to the company and to all developers:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;🧭 Improved productivity: By providing a seamless and efficient development experience, developers can spend more time on actual coding and less time on setting up their development environment or troubleshooting issues.&lt;/li&gt;
&lt;li&gt;🕘 Faster time-to-market: Developers can quickly build, test, and deploy code with minimal friction and delays, allowing organizations to release products faster and stay ahead of competitors.&lt;/li&gt;
&lt;li&gt;💎 Better code quality: When developers have access to clear and concise documentation, useful development tools and good workflow automation, they can create higher-quality code that is easier to maintain and scale.&lt;/li&gt;
&lt;li&gt;🤗 Increased collaboration: By fostering a culture of collaboration and knowledge-sharing among developers, organizations can create a more cohesive and productive development team.&lt;/li&gt;
&lt;li&gt;👀 Talent attraction and retention: Offering a positive developer experience can help companies to attract and retain new developers.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;negative-aspects&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://zenzes.me/unlocking-productivity-understanding-the-importance-of-developer-experience/#negative-aspects&quot;&gt;Negative aspects&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;But there are some potential downsides, that should be mentioned as well:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;📉 Increased costs: Creating and maintaining high-quality developer tools and resources can require significant investment in terms of time, money, and personnel.&lt;/li&gt;
&lt;li&gt;🤷 Potential overemphasis on developer experience: While it&#39;s important to create a positive developer experience, organizations should also ensure that they are balancing this with other important considerations such as security, compliance, and user experience.&lt;/li&gt;
&lt;li&gt;🤪 Lack of focus on end-users: In some cases, a focus on developer experience can come at the expense of end-user experience, which could negatively impact adoption and retention of the product.&lt;/li&gt;
&lt;li&gt;🙅 Possible resistance to change: If developers are used to working with certain tools and processes, introducing new tools or workflows can be met with resistance or pushback.&lt;/li&gt;
&lt;li&gt;💔 If the DX team is too involved in the development process, it could lead to a situation where developers do not take ownership of the entire application because they are relying too heavily on the resources and support provided by the DX team.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;working-in-a-dx-team&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://zenzes.me/unlocking-productivity-understanding-the-importance-of-developer-experience/#working-in-a-dx-team&quot;&gt;Working in a DX team&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;For me, working in a DX team means a lot of fun. The biggest advantage for me is to learn a lot. Sometimes there are some tricky topics I get into, but it is great to be able to improve the DX of my colleagues. Another benefit is that I can collaborate with many colleagues regularly. When helping them in their daily business, I get a lot of inspiration for my daily work. And of course, this blog benefits of it because I get more ideas for content.&lt;/p&gt;
&lt;p&gt;Overall, I can only recommend introducing a dedicated DX team in a company. The benefits outweigh the negative aspects, and it is a good idea to have some people who focus on providing the tools, documentation and support to enable the other developers to deliver more value.&lt;/p&gt;
</description>
        <pubDate>Tue, 07 Mar 2023 11:57:00 +0100</pubDate>
        <dc:creator>Daniel Zenzes</dc:creator>
        <guid>https://zenzes.me/unlocking-productivity-understanding-the-importance-of-developer-experience/</guid>
      </item>
      <item>
        <title>Today I learned: Utilizing pnpm packageExtensions to fix broken dependencies</title>
        <link>https://zenzes.me/today-i-learned-utilizing-pnpm-packageextensions-to-fix-broken-dependencies/</link>
        <description>&lt;p&gt;I&#39;m working on the migration of a monorepo from Vue.js 2 to Vue.js 3 right now. As we are in a monorepo we can migrate our applications stepwise but got into a situation where suddenly our Vue.js 2 tests failed with the following error:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Vue packages version mismatch:

- vue@3.2.40 (...)
- vue-template-compiler@2.7.8 (...)

This may cause things to work incorrectly. Make sure to use the same version for both.
If you are using vue-loader@&amp;gt;=10.0, simply update vue-template-compiler.
If you are using vue-loader@&amp;lt;10.0 or vueify, re-installing vue-loader/vueify should bump `vue-template-compiler` to the latest.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This didn&#39;t make sense to me at first because we don&#39;t have any project that uses &lt;code&gt;vue-template-compiler&lt;/code&gt; &lt;strong&gt;and&lt;/strong&gt; Vue.js in version 3. So, why do we see this conflict?&lt;/p&gt;
&lt;h2 id=&quot;cause-1%3A-hoisting&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://zenzes.me/today-i-learned-utilizing-pnpm-packageextensions-to-fix-broken-dependencies/#cause-1%3A-hoisting&quot;&gt;Cause 1: Hoisting&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Hoisting in node package managers refers to the behavior where dependencies that are required by multiple packages in a project are installed only once, at the highest level possible in the package tree. This reduces duplication and helps conserve disk space, since each dependency only needs to be installed once. In our case, our package manager moved Vue.js and the &lt;code&gt;vue-template-compiler&lt;/code&gt; into the root &lt;code&gt;node_modules&lt;/code&gt; folder. So, we ended with Vue.js 2 and Vue.js 3 in our root &lt;code&gt;node_modules&lt;/code&gt; folder.&lt;/p&gt;
&lt;h2 id=&quot;cause-2%3A-vue-template-compiler-is-designed-with-only-one-vue.js-version-in-the-project&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://zenzes.me/today-i-learned-utilizing-pnpm-packageextensions-to-fix-broken-dependencies/#cause-2%3A-vue-template-compiler-is-designed-with-only-one-vue.js-version-in-the-project&quot;&gt;Cause 2: &lt;code&gt;vue-template-compiler&lt;/code&gt; is designed with only one Vue.js version in the project&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;vue-template-compiler&lt;/code&gt; defines its dependency on Vue.js with the &amp;quot;version&amp;quot; &amp;quot;&lt;code&gt;file:../..&lt;/code&gt;&amp;quot; so it assumes that the Vue.js library is in the same &lt;code&gt;node_modules&lt;/code&gt; folder as the &lt;code&gt;vue-template-compiler&lt;/code&gt; and can refer it via a local path (&lt;a href=&quot;https://docs.npmjs.com/cli/v9/configuring-npm/package-json#local-paths&quot; title=&quot;npm on local paths as version in a package.json&quot;&gt;valid in a &lt;code&gt;package.json&lt;/code&gt;&lt;/a&gt;).&lt;/p&gt;
&lt;pre class=&quot;language-json&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;    &lt;span class=&quot;token comment&quot;&gt;// vue-template-compiler doesn&#39;t specify a Vue.js version&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;devDependencies&quot;&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 property&quot;&gt;&quot;vue&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;file:../..&quot;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This sounds strange, but it makes somehow sense: When &lt;code&gt;vue-template-compiler&lt;/code&gt; is installed as a dependency of a Vue.js 2 project, it needs to use the same version of Vue.js as the project itself, to ensure compatibility between the compiled templates and the runtime Vue.js library.&lt;/p&gt;
&lt;p&gt;To achieve this, &lt;code&gt;vue-template-compiler&lt;/code&gt; uses a local path to the Vue.js package that is installed in the project&#39;s &lt;code&gt;node_modules&lt;/code&gt; directory, rather than relying on a global or external version of vue.&lt;/p&gt;
&lt;p&gt;So, the problem was, that my package manager moves both dependencies to the root &lt;code&gt;node_modules&lt;/code&gt; folder of my project and the &lt;code&gt;vue-template-compiler&lt;/code&gt; tries to work with the wrong Vue.js version.&lt;/p&gt;
&lt;h2 id=&quot;pnpm-to-the-rescue&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://zenzes.me/today-i-learned-utilizing-pnpm-packageextensions-to-fix-broken-dependencies/#pnpm-to-the-rescue&quot;&gt;PNPM to the rescue&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Now there are two ways to fix this with pnpm (&lt;a href=&quot;https://stackoverflow.com/questions/72351035/building-for-vue2-and-vue3-in-monorepo-version-mismatch-error-from-vue-template&quot;&gt;thanks StackOverflow&lt;/a&gt;):&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;you can use pnpm to disable hoisting, which was not possible in our project&lt;/li&gt;
&lt;li&gt;you can use &lt;a href=&quot;https://pnpm.io/package_json#pnpmpackageextensions&quot;&gt;pnpm packageExtensions&lt;/a&gt; to &amp;quot;fix&amp;quot; the dependencies&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;In your root &lt;code&gt;package.json&lt;/code&gt; this is possible by adding the following code:&lt;/p&gt;
&lt;pre class=&quot;language-json&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// ...&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;pnpm&quot;&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 property&quot;&gt;&quot;packageExtensions&quot;&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 property&quot;&gt;&quot;vue-template-compiler&quot;&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 property&quot;&gt;&quot;peerDependencies&quot;&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 property&quot;&gt;&quot;vue&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&amp;lt;your Vue.js version&gt;&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;/code&gt;&lt;/pre&gt;
&lt;p&gt;Please note that you can do similar stuff with other package managers, too. I use pnpm a lot, so this did the trick for me. So if you are on a different package manager, maybe this helps you to find a good solution.&lt;/p&gt;
&lt;p&gt;Basically, this fixed my setup, and it can be helpful if you need to adjust some libraries dependencies to work in your specific environment.&lt;/p&gt;
</description>
        <pubDate>Fri, 03 Mar 2023 09:04:00 +0100</pubDate>
        <dc:creator>Daniel Zenzes</dc:creator>
        <guid>https://zenzes.me/today-i-learned-utilizing-pnpm-packageextensions-to-fix-broken-dependencies/</guid>
      </item>
      <item>
        <title>Strategy vs Tactics in Software Development</title>
        <link>https://zenzes.me/strategy-vs-tactics-in-software-development/</link>
        <description>&lt;p&gt;Software development teams often face the challenge of making decisions on what tools, technologies, and approaches to use when building software products. To make these decisions, it&#39;s crucial to understand the difference between strategy and tactics, as they have distinct meanings and implications.&lt;/p&gt;
&lt;p&gt;In general, strategy refers to a high-level plan or approach to achieve a particular goal or objective, while tactics refer to specific actions or steps taken to execute that plan. In the context of software development, strategy and tactics can be thought of as follows:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Strategy: The overall approach to achieving the project&#39;s goals, such as choosing the programming language, architecture, and development methodology. It usually involves identifying the most significant challenges and defining a long-term plan to overcome them.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Tactics: The specific actions or steps taken to implement the strategy, such as selecting the appropriate libraries or frameworks, defining coding standards, conducting code reviews, and testing. Tactics usually focus on the short-term and aim to support the overall strategy.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For example a strategy might be to develop a mobile application that meets the needs of a particular target audience. The tactics used to achieve this strategy might include selecting a cross-platform framework like React Native or Flutter, defining coding standards and code review processes to ensure consistency and quality, and conducting user testing to validate the application&#39;s usability.&lt;/p&gt;
&lt;p&gt;While the two concepts are related, they serve different purposes in the software development process. Strategy is the foundation that guides the development team towards a common goal, while tactics are the individual steps taken to achieve that goal. A good strategy sets the stage for effective tactics and ensures that the development team is working towards a common goal.&lt;/p&gt;
&lt;p&gt;However, it&#39;s essential to strike a balance between strategy and tactics. Focusing solely on strategy without considering the tactics needed to achieve the goals can result in an overly theoretical approach that is not actionable. Conversely, focusing solely on tactics without a clear strategy can lead to ad-hoc decision making that can result in wasted time and resources.&lt;/p&gt;
&lt;p&gt;To strike a balance between strategy and tactics, it&#39;s important to involve the entire development team in the planning process. By working collaboratively to define the software development strategy, the team can understand the big picture and how each tactic fits into the larger plan. This approach can also encourage creativity and innovation in the tactics used to achieve the goals.&lt;/p&gt;
&lt;p&gt;In conclusion, strategy and tactics are critical concepts in software development. By understanding the difference between the two and striking a balance, development teams can effectively plan and execute software projects that meet the needs of the business and end-users. A clear strategy provides the foundation for effective tactics, and a collaborative approach ensures that the entire team is aligned and working towards a common goal. With this approach, software development teams can deliver high-quality software products that meet the needs of the organization and its users.&lt;/p&gt;
</description>
        <pubDate>Tue, 28 Feb 2023 12:57:00 +0100</pubDate>
        <dc:creator>Daniel Zenzes</dc:creator>
        <guid>https://zenzes.me/strategy-vs-tactics-in-software-development/</guid>
      </item>
      <item>
        <title>Today I learned: tslib is not a devDependency</title>
        <link>https://zenzes.me/today-i-learned-tslib-is-not-a-devdependency/</link>
        <description>&lt;p&gt;There are some dependencies that I automatically add as &lt;code&gt;devDependency&lt;/code&gt; if they are needed. This includes &lt;a href=&quot;https://github.com/Microsoft/tslib&quot;&gt;tslib&lt;/a&gt;, since it obviously belongs to TypeScript and therefore should not play a role at runtime.&lt;/p&gt;
&lt;p&gt;That&#39;s where I was wrong. As my colleague Paul and I found out yesterday, you need &lt;code&gt;tslib&lt;/code&gt; at runtime if you set &lt;code&gt;importHelpers&lt;/code&gt; to &lt;code&gt;true&lt;/code&gt; in &lt;code&gt;tsconfig&lt;/code&gt;. Since this avoids duplicate code, it should be worth adding an additional dependency, especially for large projects.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;For certain downleveling operations, TypeScript uses some helper code for operations like extending class, spreading arrays or objects, and async operations. By default, these helpers are inserted into files which use them. This can result in code duplication if the same helper is used in many different modules.&lt;/p&gt;
&lt;p&gt;If the importHelpers flag is on, these helper functions are instead imported from the tslib module. You will need to ensure that the tslib module is able to be imported at runtime. This only affects modules; global script files will not attempt to import modules.&lt;/p&gt;
&lt;p&gt;-- &lt;cite&gt;&lt;a href=&quot;https://www.typescriptlang.org/tsconfig#importHelpers&quot;&gt;TSConfig Documentation&lt;/a&gt;&lt;/cite&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;By the way, the documentation at GitHub gets it right. I should have taken a closer look there, for sure. Unfortunately, there are also enough examples where the documentation is inaccurate.&lt;/p&gt;
</description>
        <pubDate>Thu, 23 Feb 2023 08:00:00 +0100</pubDate>
        <dc:creator>Daniel Zenzes</dc:creator>
        <guid>https://zenzes.me/today-i-learned-tslib-is-not-a-devdependency/</guid>
      </item>
      <item>
        <title>Eleventy: Integrate PostCSS and Tailwind CSS</title>
        <link>https://zenzes.me/eleventy-integrate-postcss-and-tailwind-css/</link>
        <description>&lt;p&gt;In my Eleventy tutorial I already showed how to set up a blog with Eleventy and also &lt;a href=&quot;https://zenzes.me/an-easy-entry-into-eleventy/#css-integrate&quot; title=&quot;Blogpost: Ein einfacher Einstieg in Eleventy. Link to section on CSS.&quot;&gt;how to integrate CSS into an Eleventy website&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Since I like to work with Tailwind CSS, I naturally want to use it in my private projects as well and have tried a few setups here. Most of them use PostCSS and TailwindCSS &amp;quot;classically&amp;quot; and then adjust the scripts in the package.json so that the Eleventy page is built first and then the appropriate CSS is generated. You can do it that way, but in my eyes it made the setup in package.json more complicated.&lt;/p&gt;
&lt;p&gt;My alternative uses Eleventy on-board resources to generate the CSS and fits into the existing configuration with just a few lines of code.&lt;/p&gt;
&lt;p&gt;You can see the whole thing in &lt;a href=&quot;https://github.com/dzenzes/11ty-start&quot; title=&quot;GitHub: 11ty start project&quot;&gt;my tutorial project&lt;/a&gt; in the &lt;a href=&quot;https://github.com/dzenzes/11ty-start/tree/tailwind&quot; title=&quot;GitHub: 11ty-start project. tailwind branch&quot;&gt;tailwind branch&lt;/a&gt; (&lt;a href=&quot;https://github.com/dzenzes/11ty-start/commit/b24ce9bdde1a2315bcc15814308416531a00608a&quot; title=&quot;Commit with changes from this blogpost&quot;&gt;commit&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;The idea behind it: Instead of a downstream process, we use PostCSS during the build via an asynchronous filter and thus generate our CSS directly via Eleventy as well.&lt;/p&gt;
&lt;p&gt;In order to use PostCSS and Tailwind CSS, we need to install it in the first step:&lt;/p&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; i &lt;span class=&quot;token parameter variable&quot;&gt;-D&lt;/span&gt; tailwindcss postcss autoprefixer cssnano&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In our Eleventy configuration we now need an asynchronous filter:&lt;/p&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; tailwind &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;&#39;tailwindcss&#39;&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; postCss &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;&#39;postcss&#39;&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; autoprefixer &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;&#39;autoprefixer&#39;&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; cssnano &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;&#39;cssnano&#39;&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; &lt;span class=&quot;token function-variable function&quot;&gt;postcssFilter&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;cssCode&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; done&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 comment&quot;&gt;// we call PostCSS here.&lt;/span&gt;
	&lt;span class=&quot;token function&quot;&gt;postCss&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;tailwind&lt;/span&gt;&lt;span class=&quot;token punctuation&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;&#39;./tailwind.config&#39;&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;autoprefixer&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;cssnano&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;preset&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;default&#39;&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;process&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;cssCode&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;// path to our CSS file&lt;/span&gt;
			&lt;span class=&quot;token literal-property property&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;./src/_includes/styles/tailwind.css&#39;&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;then&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 parameter&quot;&gt;r&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 function&quot;&gt;done&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; r&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;css&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 parameter&quot;&gt;e&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 function&quot;&gt;done&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;e&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&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;p&gt;Of course, you can also use only PostCSS with a few adjustments. Just leave the Tailwind CSS specific code out.&lt;/p&gt;
&lt;p&gt;We now add the filter to the configuration, along with a watch target&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;module&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function-variable function&quot;&gt;exports&lt;/span&gt; &lt;span class=&quot;token operator&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 parameter&quot;&gt;config&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;// ...&lt;/span&gt;
	config&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addWatchTarget&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;./src/_includes/styles/tailwind.css&#39;&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;
	config&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addNunjucksAsyncFilter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;postcss&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; postcssFilter&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;// ...&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;p&gt;Via &lt;code&gt;addWatchTarget&lt;/code&gt; we tell Eleventy that changes to this file should trigger a rebuild if we are currently running the application locally with &lt;code&gt;--serve&lt;/code&gt;. The asynchronous filter ensures that we can convert our CSS.&lt;/p&gt;
&lt;p&gt;Now we only need the CSS, which we add to &lt;code&gt;./src/_includes/styles/tailwind.css&lt;/code&gt; in the project. There we can of course work with Tailwind CSS as normal:&lt;/p&gt;
&lt;pre class=&quot;language-css&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token atrule&quot;&gt;&lt;span class=&quot;token rule&quot;&gt;@tailwind&lt;/span&gt; base&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token atrule&quot;&gt;&lt;span class=&quot;token rule&quot;&gt;@tailwind&lt;/span&gt; components&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token atrule&quot;&gt;&lt;span class=&quot;token rule&quot;&gt;@tailwind&lt;/span&gt; utilities&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If we now want to add our CSS to the page, we have two options:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;as inline style anywhere in our template&lt;/li&gt;
&lt;li&gt;as own CSS file&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Which variant is the right one here, depends strongly on the project and is probably worth a separate blogpost. I will quickly show both variants here:&lt;/p&gt;
&lt;p&gt;In the &lt;code&gt;head&lt;/code&gt; of the page (in our example in the file &lt;code&gt;src/_includes/layout.njk&lt;/code&gt;):&lt;/p&gt;
&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;style&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token style&quot;&gt;&lt;span class=&quot;token language-css&quot;&gt;
	&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;% set css %&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
	&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;% include &lt;span class=&quot;token string&quot;&gt;&quot;styles/tailwind.css&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;% endset %&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;css | postcss | safe&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;style&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here we first set the &lt;code&gt;css&lt;/code&gt; value in the template and then use the &lt;code&gt;postcss&lt;/code&gt; filter. The &lt;code&gt;safe&lt;/code&gt; filter is then used to insert the whole thing into our template. For me this is the right solution, if I have only little CSS and the generated HTML file is not too big.&lt;/p&gt;
&lt;p&gt;If you prefer to create your own CSS file, you can do this with your own template (e.g. &lt;code&gt;src/style.njk&lt;/code&gt;)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;---
## permalink: style.css

{% set css %}
{% include &amp;quot;styles/tailwind.css&amp;quot; %}
{% endset %}
{{css | postcss | safe}}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Thanks to the &lt;code&gt;permalink&lt;/code&gt; in the FrontMatter, this file is generated as &lt;code&gt;style.css&lt;/code&gt; and can then be embedded in our template (&lt;code&gt;src/_includes/layout.njk&lt;/code&gt;).&lt;/p&gt;
&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;link&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;rel&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;stylesheet&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;href&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;/style.css&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Do you know a better way to create and integrate CSS in Eleventy? Do you have more questions about Eleventy? Feel free to write me on &lt;a href=&quot;https://chaos.social/@danielzenzes&quot;&gt;Mastodon&lt;/a&gt;.&lt;/p&gt;
</description>
        <pubDate>Fri, 25 Nov 2022 14:00:00 +0100</pubDate>
        <dc:creator>Daniel Zenzes</dc:creator>
        <guid>https://zenzes.me/eleventy-integrate-postcss-and-tailwind-css/</guid>
      </item>
      <item>
        <title>Twitter (2007-2022)</title>
        <link>https://zenzes.me/twitter-2007-2022/</link>
        <description>&lt;p&gt;Twitter has been a great tool for me and has also brought me a lot in the last 15 years: I&#39;ve been able to meet many wonderful people, exchange ideas with them and have learned an enormous amount that has helped me a lot in my career so far.&lt;/p&gt;
&lt;p&gt;I&#39;m sure that without Twitter I wouldn&#39;t have written a book, and I&#39;m sure that my career and, of course, my private life would have looked completely different. Even though I became more and more passive there in the last years, Twitter was something I opened several times a day and enjoyed using.&lt;/p&gt;
&lt;p&gt;Unfortunately, Twitter has changed so much in recent weeks and months that I no longer want to support and use it. &lt;a href=&quot;https://chaos.social/@danielzenzes&quot; title=&quot;My profile on chaos.social&quot;&gt;So now you can only find me on Mastodon&lt;/a&gt;. At the moment I&#39;m much more active there, which is surely due to the mood. Feel free to come over! I would be happy if we would network there.&lt;/p&gt;
</description>
        <pubDate>Thu, 24 Nov 2022 08:11:00 +0100</pubDate>
        <dc:creator>Daniel Zenzes</dc:creator>
        <guid>https://zenzes.me/twitter-2007-2022/</guid>
      </item>
      <item>
        <title>Was steht so in der package.json </title>
        <link>https://zenzes.me/was-steht-so-in-der-packagejson/</link>
        <description>&lt;p&gt;&lt;a href=&quot;https://zenzes.me/frontend-1x1-fur-backend-devs/&quot; title=&quot;Blogbeitrag: Frontend 1x1 für Backend Devs&quot;&gt;Vor einiger Zeit&lt;/a&gt; habe ich eine Einführung in ein Standard-Frontend-Projekt gegeben und dabei mit Blick auf die &lt;code&gt;package.json&lt;/code&gt; einige Dinge etwas vereinfacht. In diesem Beitrag möchte ich daher einige dieser Details genauer zeigen. Übrigens: zu diesem Thema habe ich vor ein paar Jahren auch etwas &lt;a href=&quot;https://dz.ms/npm-cc-de&quot; title=&quot;codecentric Blog: Ein Blick auf npm und package.json&quot;&gt;im Blog der codecentric&lt;/a&gt; geschrieben. Der Artikel ist größtenteils noch aktuell und wird durch diesen Beitrag ergänzt.&lt;/p&gt;
&lt;p&gt;Fangen wir mit der &lt;code&gt;package.json&lt;/code&gt; an: Ich finde ziemlich gut, dass man hier in der JavaScript-Welt einen Quasi-Standard hat und somit einen zentralen Einstiegspunkt. Es ist an vielen Stellen egal, mit welchem Tool man hier arbeitet, da alle die &lt;code&gt;package.json&lt;/code&gt; unterstützen.&lt;/p&gt;
&lt;p&gt;Hintergrund hier ist, dass &lt;a href=&quot;https://www.npmjs.com/&quot; title=&quot;Webseite zu npm&quot;&gt;npm&lt;/a&gt; das wahrscheinlich größte Repository im JavaScript Ökosystem anbietet und am Ende alle Tools damit interagieren müssen.&lt;/p&gt;
&lt;p&gt;In diesem Artikel nutze ich npm, die Dinge, die ich hier beschreibe, sind aber auch mit den anderen Tools möglich.&lt;/p&gt;
&lt;h2 id=&quot;erstellung-einer-package.json&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://zenzes.me/was-steht-so-in-der-packagejson/#erstellung-einer-package.json&quot;&gt;Erstellung einer package.json&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Wer eine &lt;code&gt;package.json&lt;/code&gt; anlegen möchte, kann dies über das Terminal tun:&lt;/p&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;mkdir&lt;/span&gt; my-app
&lt;span class=&quot;token builtin class-name&quot;&gt;cd&lt;/span&gt; my-app
&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; init &lt;span class=&quot;token parameter variable&quot;&gt;-y&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Ich erspare mir hier in der Regel den Wizard, den man über &lt;code&gt;npm init&lt;/code&gt; starten kann und erzeuge die ganze Datei direkt (Option &lt;code&gt;-y&lt;/code&gt;). Diese beinhaltet dann einige Meta-Informationen, die ich im Anschluss im Editor anpasse (Lizenz und Skripte):&lt;/p&gt;
&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;token string-property property&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;my-app&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
	&lt;span class=&quot;token string-property property&quot;&gt;&quot;version&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;1.0.0&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
	&lt;span class=&quot;token string-property property&quot;&gt;&quot;description&quot;&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 string-property property&quot;&gt;&quot;main&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;index.js&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
	&lt;span class=&quot;token string-property property&quot;&gt;&quot;scripts&quot;&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 string-property property&quot;&gt;&quot;test&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;echo &#92;&quot;Error: no test specified&#92;&quot; &amp;amp;&amp;amp; exit 1&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 string-property property&quot;&gt;&quot;keywords&quot;&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 string-property property&quot;&gt;&quot;author&quot;&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 string-property property&quot;&gt;&quot;license&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;ISC&quot;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;version&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://zenzes.me/was-steht-so-in-der-packagejson/#version&quot;&gt;version&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Die Version des Moduls, die gerade dann wichtig ist, wenn andere das Modul als Dependency verwenden sollen. Bei so mancher Anwendung bleibt sie aus diesem Grund stabil bei &lt;code&gt;1.0.0&lt;/code&gt;, ich selber finde es aber auch ganz gut, diese aktuell zu halten. Über &lt;code&gt;npm version&lt;/code&gt; (&lt;a href=&quot;https://docs.npmjs.com/cli/v8/commands/npm-version&quot; title=&quot;npm Dokumentation zu npm version&quot;&gt;Dokumentation&lt;/a&gt;) kann man diese übrigens bequem aktualisieren (und gleich einen Tag mit erzeugen).&lt;/p&gt;
&lt;p&gt;Syntax:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;npm version [&amp;lt;newversion&amp;gt; | major | minor | patch | premajor | preminor | prepatch | prerelease | from-git]
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;main&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://zenzes.me/was-steht-so-in-der-packagejson/#main&quot;&gt;main&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Besonders bei Bibliotheken ist der Einstiegspunkt des Moduls wichtig, der beim Import durch ein anderes Modul verwendet wird. Dieser wird im Feld &lt;code&gt;main&lt;/code&gt; festgelegt und hat als Wert den Pfad zu einer JavaScript Datei, die die Funktionalität des Moduls bereitstellt.&lt;/p&gt;
&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token string-property property&quot;&gt;&quot;main&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;./src/index.js&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;The &amp;quot;main&amp;quot; field is a module ID that is the primary entry point to your program. That is, if your package is named foo, and a user installs it, and then does require(&amp;quot;foo&amp;quot;), then your &amp;quot;main&amp;quot; module&#39;s exports object will be returned.&lt;br /&gt;
This should be a module relative to the root of your package folder.&lt;br /&gt;
For most modules, it makes the most sense to have a &amp;quot;main&amp;quot; script and often not much else.&lt;br /&gt;
If &amp;quot;main&amp;quot; is not set, it defaults to index.js in the packages root folder.&lt;/p&gt;
&lt;p&gt;-- &lt;cite&gt;&lt;a href=&quot;https://docs.npmjs.com/cli/v7/configuring-npm/package-json#main&quot; title=&quot;npm Dokumentation&quot;&gt;npm Dokumentation&lt;/a&gt;&lt;/cite&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;skripte&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://zenzes.me/was-steht-so-in-der-packagejson/#skripte&quot;&gt;Skripte&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Ein weiterer wichtiger Block ist der &lt;code&gt;scripts&lt;/code&gt; Block, da sich dort in der Regel alle Skripte finden lassen, mit denen die Anwendung gestartet, getestet und gebaut wird. Der scripts Block ist ein Objekt wobei jeweils der &lt;code&gt;key&lt;/code&gt; den Namen des Scripts festlegt und der jeweilige Wert wird entsprechend ausgeführt.&lt;/p&gt;
&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token string-property property&quot;&gt;&quot;scripts&quot;&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 string-property property&quot;&gt;&quot;build&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;webpack&quot;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In diesem Beispiel kann dann mit &lt;code&gt;npm run build&lt;/code&gt; webpack gestartet werden.&lt;/p&gt;
&lt;p&gt;Hier unterschiden wir zwischen eigenen Skripten und &lt;strong&gt;Lifecycle Events&lt;/strong&gt;, die npm von Hause aus unterstützt (und wo wir uns das &lt;code&gt;run&lt;/code&gt; im Aufruf sparen können):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;publish&lt;/li&gt;
&lt;li&gt;install&lt;/li&gt;
&lt;li&gt;uninstall&lt;/li&gt;
&lt;li&gt;version&lt;/li&gt;
&lt;li&gt;test&lt;/li&gt;
&lt;li&gt;stop&lt;/li&gt;
&lt;li&gt;start&lt;/li&gt;
&lt;li&gt;restart&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So kann sich in einer &lt;code&gt;package.json&lt;/code&gt; also unter anderem ein Skript &lt;code&gt;test&lt;/code&gt; befinden, welches dann das Testframework (hier &lt;code&gt;jest&lt;/code&gt;) ausführt.&lt;/p&gt;
&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token string-property property&quot;&gt;&quot;scripts&quot;&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 string-property property&quot;&gt;&quot;test&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;jest&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;/code&gt;&lt;/pre&gt;
&lt;p&gt;Soweit also kein wesentlicher Unterschied zu den eigenen Skripten, bei den Lifecycle Events können aber auch noch “pre” und “post” vorangestellt werden. Ebenso ist es möglich, npm-Skripte in anderen Skripten wiederzuverwenden.&lt;/p&gt;
&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token string-property property&quot;&gt;&quot;scripts&quot;&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 string-property property&quot;&gt;&quot;preversion&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;npm test&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
	&lt;span class=&quot;token string-property property&quot;&gt;&quot;version&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;npm run build &amp;amp;&amp;amp; git add -A dist&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
	&lt;span class=&quot;token string-property property&quot;&gt;&quot;postversion&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;git push &amp;amp;&amp;amp; git push --tags &amp;amp;&amp;amp; rm -rf build/temp&quot;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Die Bibliotheken in meinen Skripten kann ich verwenden, wenn sie in den Dependencies vorhanden sind, da npm diese automatisch zum &lt;code&gt;PATH&lt;/code&gt; hinzufügt, wenn es aufgerufen wird.&lt;/p&gt;
&lt;p&gt;Daher sollten auch alle Tools, die zum Bauen des Projekts benötigt werden, in den Dependencies verwaltet werden.&lt;/p&gt;
&lt;h2 id=&quot;dependencies&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://zenzes.me/was-steht-so-in-der-packagejson/#dependencies&quot;&gt;Dependencies&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Und natürlich gibt es mehrere Möglichkeiten &lt;a href=&quot;https://docs.npmjs.com/cli/v8/configuring-npm/package-json#dependencies&quot; title=&quot;Erklärung zu Dependencies in der npm Dokumentation&quot;&gt;Dependencies&lt;/a&gt; in der &lt;code&gt;package.json&lt;/code&gt; zu definieren:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;dependencies&lt;/li&gt;
&lt;li&gt;devDependencies&lt;/li&gt;
&lt;li&gt;peerDependencies&lt;/li&gt;
&lt;li&gt;peerDependenciesMeta&lt;/li&gt;
&lt;li&gt;bundledDependencies&lt;/li&gt;
&lt;li&gt;optionalDependencies&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In den meisten Projekten, die ich kenne, werden &lt;em&gt;dependencies&lt;/em&gt;, &lt;em&gt;devDependencies&lt;/em&gt; und vereinzelt &lt;em&gt;peerDependencies&lt;/em&gt; eingesetzt.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Dependencies&lt;/strong&gt; sind die Abhängigkeiten, die das Projekt zur Laufzeit benötigt ([&lt;a href=&quot;https://docs.npmjs.com/cli/v7/configuring-npm/package-json#dependencies&quot;&gt;https://docs.npmjs.com/cli/v7/configuring-npm/package-json#dependencies&lt;/a&gt;]).&lt;/p&gt;
&lt;p&gt;Bei &lt;strong&gt;devDependencies&lt;/strong&gt; handelt es sich um alle Abhängigkeiten, die während der Entwicklung, aber nicht während der Laufzeit, benötigt werden (z. B. Tools für das Testing oder den Build).&lt;/p&gt;
&lt;p&gt;Bei &lt;strong&gt;peerDependencies&lt;/strong&gt; handelt es sich um Abhängigkeiten, die das Modul benötigt, um genutzt zu werden, aber nicht selbst zur Verfügung stellt. Das sieht man oft bei Plug-ins für andere Bibliotheken, die die eigentliche Bibliothek voraussetzen, sie aber nicht mitliefern.&lt;/p&gt;
&lt;h3 id=&quot;definition-von-dependencies&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://zenzes.me/was-steht-so-in-der-packagejson/#definition-von-dependencies&quot;&gt;Definition von dependencies&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;In den meisten Fällen installiert man Dependencies mit &lt;code&gt;npm install &amp;lt;dependency&amp;gt;&lt;/code&gt;. Dies installiert die Dependency im aktuellen Projekt und ergänzt sie in der package.json. Wenn man eine devDependency installieren möchte, geht dies über &lt;code&gt;npm install &amp;lt;dependency&amp;gt; --save-dev&lt;/code&gt; oder, kürzer, &lt;code&gt;npm install &amp;lt;dependency&amp;gt; -D&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Sollte man eine Abhängigkeit global benötigen, geht dies analog mit &lt;code&gt;--global&lt;/code&gt; oder &lt;code&gt;-g&lt;/code&gt;. Diese liegen dann im &lt;code&gt;PATH&lt;/code&gt; und können dann überall verwendet werden.&lt;/p&gt;
&lt;p&gt;In den meisten Fällen wird eine Dependency mit ihrer Version (dazu gleich mehr) in die &lt;code&gt;package.json&lt;/code&gt; geschrieben.&lt;/p&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;devDepedencies&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 string-property property&quot;&gt;&quot;@11ty/eleventy&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;1.0.2&quot;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Es gibt allerdings auch ein paar Alternativen, die möglich sind:&lt;/p&gt;
&lt;h4 id=&quot;git-urls&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://zenzes.me/was-steht-so-in-der-packagejson/#git-urls&quot;&gt;Git URLs&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;Die offizielle Doku verweist auf folgendes Pattern, wenn man eine Dependency über eine git URL installieren möchte: &lt;code&gt;&amp;lt;protocol&amp;gt;://[&amp;lt;user&amp;gt;[:&amp;lt;password&amp;gt;]@]&amp;lt;hostname&amp;gt;[:&amp;lt;port&amp;gt;][:][/]&amp;lt;path&amp;gt;[#&amp;lt;commit-ish&amp;gt; | #semver:&amp;lt;semver&amp;gt;]&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Im Hintergrund versucht npm dann dieses Projekt auszuchecken und das &lt;code&gt;build&lt;/code&gt;-Skript zu starten. Auch wenn das cool aussieht, habe ich das bisher noch nie in einer produktiven Anwendung gesehen.&lt;/p&gt;
&lt;p&gt;Bei GitHub URLs ist das sogar etwas einfacher gelöst da man einfach &lt;code&gt;user/project&lt;/code&gt; angeben kann:&lt;/p&gt;
&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token string-property property&quot;&gt;&quot;devDependencies&quot;&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 string-property property&quot;&gt;&quot;@11ty/eleventy&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;11ty/eleventy&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;/code&gt;&lt;/pre&gt;
&lt;p&gt;Auch dies ist mir in freier Wildbahn noch nie begegnet und es sollte sehr bewusst eingesetzt werden, da man in diesem Beispiel dann die aktuellste, womöglich noch nicht veröffentlichte, Version der Dependency bekommt. Außerdem dauert, dass ganze natürlich auch etwas länger, da im Hintergrund das Projekt gebaut werden muss.&lt;/p&gt;
&lt;h3 id=&quot;pfade&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://zenzes.me/was-steht-so-in-der-packagejson/#pfade&quot;&gt;Pfade&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Statt einer Version kann man auch einen Pfad zu einem Projekt angeben.&lt;/p&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;dependencies&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 string-property property&quot;&gt;&quot;foo&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;../foo&quot;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Das ist für Testzwecke manchmal ganz nützlich, würde ich in größeren Projekten allerdings nicht machen. Hier bietet sich dann eher eine Lösung à la &lt;a href=&quot;https://docs.npmjs.com/cli/v7/using-npm/workspaces&quot; title=&quot;npm Dokumentation zu Workspaces&quot;&gt;Workspaces&lt;/a&gt; an.&lt;/p&gt;
&lt;p&gt;Wenn es nur darum geht, eine lokal entwickelte Bibliothek in einem Projekt zu testen, ist &lt;code&gt;npm link&lt;/code&gt; (&lt;a href=&quot;https://docs.npmjs.com/cli/v8/commands/npm-link&quot; title=&quot;Dokumentation zu npm link&quot;&gt;Dokumentation&lt;/a&gt;) meiner Meinung nach die bessere Wahl.&lt;/p&gt;
&lt;h3 id=&quot;versionen&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://zenzes.me/was-steht-so-in-der-packagejson/#versionen&quot;&gt;Versionen&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Glücklicherweise verstehen die meisten Projekte im npm Kosmos inzwischen &lt;a href=&quot;https://docs.npmjs.com/about-semantic-versioning&quot; title=&quot;npm Dokumentation zu Semantic Versioning&quot;&gt;Semantic Versioning&lt;/a&gt; und daher kann man sich oft darauf verlassen. Dies liegt sicher auch daran, dass npm dies von Hause aus aktiv durch Skripte (&lt;code&gt;npm version&lt;/code&gt;) unterstützt.&lt;/p&gt;
&lt;p&gt;Wie immer gilt: sicher ist man nur, wenn man die Version fix, also auch ohne Zirkumflex (^) vor der Version, angibt.&lt;/p&gt;
&lt;p&gt;Versionen kann man in seiner &lt;code&gt;package.json&lt;/code&gt; auf folgende Weisen definieren:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Fixe Versionen&lt;/strong&gt;, wie 1.0.0. In diesem Fall installiert npm auch nur exakt diese Version&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Versionsbereiche&lt;/strong&gt; wie &amp;gt;1.0.0. Womit sich größere Versionsbereiche abdecken lassen. Die möglichen Vergleichsoperatoren sind “&amp;lt;”, “&amp;lt;=”, “&amp;gt;”, “&amp;gt;=” und “=”.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Tags&lt;/strong&gt; wie -beta oder -alpha-3 erlauben es Versionen zu definieren, die noch nicht stabil sind.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Patchversionen&lt;/strong&gt; wie &lt;code&gt;~1.0.0&lt;/code&gt;. In diesem Fall nimmt npm immer die aktuellste minor Version.&lt;/li&gt;
&lt;li&gt;Bei der Definition mit &lt;strong&gt;Zirkumflex&lt;/strong&gt; (^) bleibt die erste Zahl, die keine 0 in der Version ist, stabil. Mit ^1.0.0 ist also jede Version &amp;gt;= 1.0.0 und &amp;lt; 2.0.0 abgedeckt. Bei ^0.0.1 bleibt die Version stabil, da es hier keine andere passende Version gibt.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;tools-in-der-package.json&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://zenzes.me/was-steht-so-in-der-packagejson/#tools-in-der-package.json&quot;&gt;Tools in der package.json&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Viele Tools erlauben es ihre Konfiguration in der &lt;code&gt;package.json&lt;/code&gt; abzulegen oder in einer separaten Datei im Projekt. Ich bevorzuge hier den zweiten Weg, damit meine &lt;code&gt;package.json&lt;/code&gt; nicht so überfüllt ist und man bei einem Blick auf den root Ordner des Projekts schon sehen kann, welches Tooling verwendet wird.&lt;/p&gt;
&lt;p&gt;Und natürlich gibt es hier noch mehr zu entdecken und einige Dinge hängen auch sehr vom jeweiligen Projekt ab. Ich hoffe, der Einblick macht die Orientierung in der &lt;code&gt;package.json&lt;/code&gt; etwas einfacher. Fehlt Euch hier noch etwas oder habt ihr weitere Fragen? Schreibt mir gerne auf &lt;a href=&quot;https://chaos.social/@danielzenzes&quot;&gt;Mastodon&lt;/a&gt;.&lt;/p&gt;
</description>
        <pubDate>Wed, 31 Aug 2022 15:00:00 +0200</pubDate>
        <dc:creator>Daniel Zenzes</dc:creator>
        <guid>https://zenzes.me/was-steht-so-in-der-packagejson/</guid>
      </item>
      <item>
        <title>Was sind eigentlich Prototypen in JavaScript und TypeScript?</title>
        <link>https://zenzes.me/was-sind-eigentlich-prototypen-in-javascript-und-typescript/</link>
        <description>&lt;p&gt;Für diesen Blog möchte ich ein paar Dinge aus dem JavaScript Umfeld zusammenfassen, die mir immer wieder begegnen und stellenweise auch mal für Probleme sorgen. Prototypen sind etwas, dass immer mal wieder für Verwirrung sorgt und hier möchte ich versuchen, dass ganze verständlich zu erklären.&lt;/p&gt;
&lt;p&gt;JavaScript ist eine &lt;a href=&quot;https://de.wikipedia.org/wiki/Prototypenbasierte_Programmierung&quot; title=&quot;Wikipedia Artikel zu prototypenbasierter Programmierung&quot;&gt;prototypenbasierte Programmiersprache&lt;/a&gt;. Das bedeutet also zunächst, dass JavaScript Objektorientierung unterstützt. Laut Definition allerdings eine &amp;quot;ohne Klassen&amp;quot; (was nicht stimmt, mehr dazu später im Artikel).&lt;/p&gt;
&lt;p&gt;Während in anderen Programmiersprachen Objekte durch die Instanziierung einer Klasse erzeugt werden (&lt;code&gt;x = new Foo(&amp;quot;bar&amp;quot;)&lt;/code&gt;), wird in prototypenbasierten ein Objekt durch das Klonen eines bereits existierenden Objekts instanziiert. Klonen bedeutet, dass der Klon alle Eigenschaften des Originals hat und nutzen kann.&lt;/p&gt;
&lt;p&gt;Um zu verstehen, was dies für JavaScript bedeutet, lohnt sich ein Blick auf den ECMA Standard zum Begriff &lt;em&gt;prototype&lt;/em&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;object that provides shared properties for other objects&lt;br /&gt;
&lt;cite&gt;&lt;a href=&quot;https://262.ecma-international.org/5.1/#sec-4.3.5&quot; title=&quot;Beschreibung von prototype im ECMA Standard&quot;&gt;ECMA Standard&lt;/a&gt;&lt;/cite&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Ein Prototyp ist also erst mal ein &lt;em&gt;Objekt&lt;/em&gt; in JavaScript und dieses hat &lt;em&gt;Properties&lt;/em&gt;, also Werte und Funktionen, die es mit anderen Objekten teilen kann.&lt;/p&gt;
&lt;p&gt;Unter der Erklärung steht auch noch eine Anmerkung:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;When a constructor creates an object, that object implicitly references the constructor’s “prototype” property for the purpose of resolving property references. The constructor’s “prototype” property can be referenced by the program expression &lt;code&gt;constructor.prototype&lt;/code&gt;, and properties added to an object’s prototype are shared, through inheritance, by all objects sharing the prototype. Alternatively, a new object may be created with an explicitly specified prototype by using the Object.create built-in function.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;JavaScript kennt also &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/constructor&quot; title=&quot;MDN zu Konstruktoren&quot;&gt;Konstruktoren&lt;/a&gt;. Im &amp;quot;klassischen&amp;quot; JavaScript (besonders vor ES6) war es daher üblich, dass man mit Konstruktor Funktionen, Prototypen definieren und diese dann auch instanziieren kann.&lt;/p&gt;
&lt;p&gt;Sehen wir uns hierzu mal ein klassisches Beispiel an:&lt;/p&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;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;Person&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;firstName&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; lastName&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;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;firstName &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; firstName&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;lastName &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; lastName&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; person1 &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;Person&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;John&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;Doe&#39;&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;h3 id=&quot;instanziierung&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://zenzes.me/was-sind-eigentlich-prototypen-in-javascript-und-typescript/#instanziierung&quot;&gt;Instanziierung&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Das Objekt &lt;code&gt;person1&lt;/code&gt; wird mithilfe der Konstruktor Funktion instanziiert und hat fortan alle Funktionen, die der Prototyp kennt.&lt;/p&gt;
&lt;p&gt;Die Instanziierung klappt auch noch mit der Funktion &lt;a href=&quot;https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Global_Objects/Object/create&quot; title=&quot;MDN: Definition von Object.create&quot;&gt;&lt;code&gt;Object.create&lt;/code&gt;&lt;/a&gt;, es sollte aber schnell ersichtlich werden, warum man das heute eher selten so macht:&lt;/p&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; person2 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Object&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Person&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;prototype&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;firstName&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;value&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;Jane&#39;&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;lastName&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;value&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;Doe&#39;&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;p&gt;Trotzdem hat diese Methode natürlich auch ihre Berechtigung, da ich hier noch recht feingranular, die Eigenschaften der Objekte konfigurieren kann (bspw. read-only).&lt;/p&gt;
&lt;h3 id=&quot;erweiterung-von-prototypen&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://zenzes.me/was-sind-eigentlich-prototypen-in-javascript-und-typescript/#erweiterung-von-prototypen&quot;&gt;Erweiterung von Prototypen&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Wenn wir später den Prototypen mit weiteren Funktionen erweitern würden, würden die Objekte auch davon profitieren (das fühlt sich ein wenig wie &lt;a href=&quot;https://kotlinlang.org/docs/extensions.html&quot; title=&quot;Dokumentation zu Extensions in Kotlin&quot;&gt;Extensions in Kotlin&lt;/a&gt; an).&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;Person&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;prototype&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function-variable function&quot;&gt;fullName&lt;/span&gt; &lt;span class=&quot;token operator&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;return&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 interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;firstName&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&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;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;lastName&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&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;
&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;picture class=&quot;&quot;&gt;
		&lt;source type=&quot;image/svg+xml&quot; srcset=&quot;https://zenzes.me/assets/images/j4cxPwIHsm-2944.svg 2944w&quot; sizes=&quot;100vw&quot; /&gt;
&lt;source type=&quot;image/webp&quot; srcset=&quot;https://zenzes.me/assets/images/j4cxPwIHsm-400.webp 400w, https://zenzes.me/assets/images/j4cxPwIHsm-800.webp 800w, https://zenzes.me/assets/images/j4cxPwIHsm-1280.webp 1280w, https://zenzes.me/assets/images/j4cxPwIHsm-2944.webp 2944w&quot; sizes=&quot;100vw&quot; /&gt;
		&lt;img src=&quot;https://zenzes.me/assets/images/j4cxPwIHsm-2944.webp&quot; width=&quot;2944&quot; height=&quot;1478&quot; alt=&quot;Prototype Chain für das erste Code-Beispiel&quot; class=&quot;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; /&gt;
	&lt;/picture&gt;
&lt;p&gt;Das funktioniert auch mit den Datentypen, die JavaScript mitbringt (wie String, Number, Array, Function, ...), ist aber ein Anti-Pattern, da diese Veränderung in einer Anwendung natürlich überall passieren könnte und dies dementsprechend zu unvorhergesehenen Effekten führen kann.&lt;/p&gt;
&lt;picture class=&quot;&quot;&gt;
		&lt;source type=&quot;image/svg+xml&quot; srcset=&quot;https://zenzes.me/assets/images/q7GlZbDmL4-2944.svg 2944w&quot; sizes=&quot;100vw&quot; /&gt;
&lt;source type=&quot;image/webp&quot; srcset=&quot;https://zenzes.me/assets/images/q7GlZbDmL4-400.webp 400w, https://zenzes.me/assets/images/q7GlZbDmL4-800.webp 800w, https://zenzes.me/assets/images/q7GlZbDmL4-1280.webp 1280w, https://zenzes.me/assets/images/q7GlZbDmL4-2944.webp 2944w&quot; sizes=&quot;100vw&quot; /&gt;
		&lt;img src=&quot;https://zenzes.me/assets/images/q7GlZbDmL4-2944.webp&quot; width=&quot;2944&quot; height=&quot;2188&quot; alt=&quot;Prototype Chain in JavaScript&quot; class=&quot;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; /&gt;
	&lt;/picture&gt;
&lt;p&gt;Das funktioniert, da jedes hier erstellte Objekt die Eigenschaft &lt;code&gt;__proto__&lt;/code&gt; hat, die auf unseren Prototypen &lt;code&gt;Person&lt;/code&gt; verweist (&lt;code&gt;Person.prototype === person1.__proto__&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;Der Wert von &lt;code&gt;__proto__&lt;/code&gt; in jeder Instanz des Konstruktors ist ein direkter Verweis auf den Prototyp des Konstruktors. Immer, wenn wir versuchen, auf eine Eigenschaft eines Objekts zuzugreifen, die nicht direkt auf diesem existiert, geht JavaScript die &lt;em&gt;Prototype Chain&lt;/em&gt; hinunter, um zu sehen, ob die Eigenschaft innerhalb dieser verfügbar ist.&lt;/p&gt;
&lt;p&gt;Diese Eigenschaft hat übrigens auch jedes andere Objekt in JavaScript. Wenn wir ein Objekt einfach erzeugen, dann ist dessen Prototyp immer &lt;code&gt;Object&lt;/code&gt;&lt;/p&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; person3 &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;firstName&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;Max&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
	&lt;span class=&quot;token literal-property property&quot;&gt;lastName&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;Mustermann&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
	&lt;span class=&quot;token function-variable function&quot;&gt;fullName&lt;/span&gt;&lt;span class=&quot;token operator&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;return&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 interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;firstName&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&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;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;lastName&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&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;
	&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;// person3.__proto__ === Object.prototype&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;klassen&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://zenzes.me/was-sind-eigentlich-prototypen-in-javascript-und-typescript/#klassen&quot;&gt;Klassen&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Heutzutage unterstützt JavaScript &amp;quot;Klassen&amp;quot;, baut aber intern weiterhin auf Prototypen, weicht also ein wenig vom Lehrbuch ab. Das Beispiel von oben lässt sich also heutzutage folgendermaßen schreiben:&lt;/p&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;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Person&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;token function&quot;&gt;constructor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;firstName&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; lastName&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;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;firstName &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; firstName&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
		&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;lastName &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; lastName&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;fullName&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 template-string&quot;&gt;&lt;span class=&quot;token template-punctuation 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;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;firstName&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&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;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;lastName&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&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;
	&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; person1 &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;Person&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;John&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;Doe&#39;&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;h3 id=&quot;vererbung&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://zenzes.me/was-sind-eigentlich-prototypen-in-javascript-und-typescript/#vererbung&quot;&gt;Vererbung&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Wenn wir von Objektorientierung sprechen, ist auch Vererbung ein Thema. Wir haben immer mal wieder spezialisierte Objekte, die zusätzliche Funktionen haben. In klassischem JavaScript ist eine Variante, den Prototyp manuell zu setzen:&lt;/p&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;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;Musician&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;firstName&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; lastName&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;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;firstName &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; firstName&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;lastName &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; lastName&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

Object&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setPrototypeOf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Musician&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;prototype&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Person&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;prototype&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 class-name&quot;&gt;Musician&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;prototype&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function-variable function&quot;&gt;sing&lt;/span&gt; &lt;span class=&quot;token operator&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 parameter&quot;&gt;song&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 template-string&quot;&gt;&lt;span class=&quot;token template-punctuation 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;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;fullName&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 interpolation-punctuation punctuation&quot;&gt;}&lt;/span&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;song&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&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;
&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;p&gt;Das sieht auf den ersten Blick etwas ungewöhnlich aus, erlaubt aber natürlich, sich einfach in die &lt;em&gt;Prototype Chain&lt;/em&gt; zu hängen und Vererbung einzuführen.&lt;/p&gt;
&lt;p&gt;Mit der Unterstützung von Klassen hat JavaScript nun aber auch die Unterstützung des Keywords &lt;code&gt;extends&lt;/code&gt; bekommen, womit wir die &lt;em&gt;Prototype Chain&lt;/em&gt; zu unserm Vorteil nutzen können und gleich lesbareren Code bekommen:&lt;/p&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;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Musician&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Person&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;token function&quot;&gt;constructor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;firstName&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; lastName&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;super&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;firstName&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; lastName&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;sing&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;song&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 template-string&quot;&gt;&lt;span class=&quot;token template-punctuation 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;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;fullName&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 interpolation-punctuation punctuation&quot;&gt;}&lt;/span&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;song&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&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;
	&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; paul &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;Musician&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;Paul&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;McCartney&#39;&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;// paul.__proto__ === Musician.prototype&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// paul.__proto__.__proto__ === Person.prototype&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;picture class=&quot;&quot;&gt;
		&lt;source type=&quot;image/svg+xml&quot; srcset=&quot;https://zenzes.me/assets/images/MGU8OgMujI-2248.svg 2248w&quot; sizes=&quot;100vw&quot; /&gt;
&lt;source type=&quot;image/webp&quot; srcset=&quot;https://zenzes.me/assets/images/MGU8OgMujI-400.webp 400w, https://zenzes.me/assets/images/MGU8OgMujI-800.webp 800w, https://zenzes.me/assets/images/MGU8OgMujI-1280.webp 1280w, https://zenzes.me/assets/images/MGU8OgMujI-2248.webp 2248w&quot; sizes=&quot;100vw&quot; /&gt;
		&lt;img src=&quot;https://zenzes.me/assets/images/MGU8OgMujI-2248.webp&quot; width=&quot;2248&quot; height=&quot;801&quot; alt=&quot;Prototype Chain für das Musician Code Beispiel&quot; class=&quot;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; /&gt;
	&lt;/picture&gt;
&lt;p&gt;Ich nutze Klassen kaum in JavaScript und TypeScript. Meist nutze ich Objekte nur, um Werte zu gruppieren (&lt;em&gt;value objects&lt;/em&gt;). Die Logik wird über Funktionen abgebildet. Wenn ich mit Klassen arbeite, liegt dies größtenteils an Frameworks. Trotzdem spiele ich immer wieder mit dem Gedanken, ob Objekte mit mehr Funktionen nicht auch nützlich sein könnten.&lt;/p&gt;
&lt;p&gt;Wie sieht das bei Euch aus? Schreibt ihr viele Klassen oder nutzt ihr mehr Funktionen? Schreibt mir gerne auf &lt;a href=&quot;https://chaos.social/@danielzenzes&quot;&gt;Mastodon&lt;/a&gt;.&lt;/p&gt;
</description>
        <pubDate>Mon, 15 Aug 2022 15:00:00 +0200</pubDate>
        <dc:creator>Daniel Zenzes</dc:creator>
        <guid>https://zenzes.me/was-sind-eigentlich-prototypen-in-javascript-und-typescript/</guid>
      </item>
      <item>
        <title>Mit bind, call und apply den Kontext in JavaScript meistern</title>
        <link>https://zenzes.me/mit-bind-call-und-apply-den-kontext-in-javascript-meistern/</link>
        <description>&lt;p&gt;In &lt;a href=&quot;https://zenzes.me/this-in-javascript-verstehen/&quot; title=&quot;Blog: this in JavaScript verstehen&quot;&gt;meinem letzten Beitrag&lt;/a&gt; habe ich bewusst noch ein paar Dinge unterschlagen, die im Umgang mit &lt;code&gt;this&lt;/code&gt; hilfreich sein können: &lt;code&gt;bind&lt;/code&gt;, &lt;code&gt;apply&lt;/code&gt; und &lt;code&gt;call&lt;/code&gt;. Zum einen war der Artikel schon gefühlt lang genug und außerdem nutze ich die drei Methoden (so gut wie) nie. Da mich &lt;a href=&quot;https://twitter.com/tobmaster&quot; title=&quot;Tobias bei Twitter&quot;&gt;Tobias&lt;/a&gt; &lt;a href=&quot;https://twitter.com/tobmaster/status/1552011784571191296&quot; title=&quot;Tobias Antwort auf meinen Artikel&quot;&gt;aber darauf hingewiesen hat&lt;/a&gt;, hole ich das Ganze hier nach.&lt;/p&gt;
&lt;h2 id=&quot;einer-methode-einen-context-zuweisen%2C-mit-bind&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://zenzes.me/mit-bind-call-und-apply-den-kontext-in-javascript-meistern/#einer-methode-einen-context-zuweisen%2C-mit-bind&quot;&gt;Einer Methode einen Context zuweisen, mit &lt;code&gt;bind&lt;/code&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Bisher habe ich, wenn ich einer Funktion einen Kontext mitgeben wollen, ein wenig geschummelt. In meinem letzten Artikel habe ich &lt;code&gt;this&lt;/code&gt; in einer anderen Variable gespeichert und diese dann in der Funktion genutzt.&lt;/p&gt;
&lt;p&gt;Sehen wir uns das Beispiel aus dem letzten Artikel nochmal mit einer kleinen Veränderung an und versuchen dann, ohne &lt;code&gt;that&lt;/code&gt; zu arbeiten:&lt;/p&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; john &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;lyrics&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;Let is be, let it be&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
	&lt;span class=&quot;token function&quot;&gt;sing&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;
		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;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;lyrics&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;singLater&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; that &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
		&lt;span class=&quot;token function&quot;&gt;setTimeout&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;
			that&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;sing&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 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;
john&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;singLater&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;// 🎵 Let is be, let it be&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Mithilfe von &lt;code&gt;bind&lt;/code&gt; erstellen wir nun eine neue Variable &lt;code&gt;singWithContext&lt;/code&gt; und binden in dieser den aktuellen Kontext (&lt;code&gt;this&lt;/code&gt;, was hier &lt;code&gt;john&lt;/code&gt; ist) an die Funktion &lt;code&gt;sing&lt;/code&gt;.&lt;/p&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; john &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;lyrics&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;Let is be, let it be&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
	&lt;span class=&quot;token function&quot;&gt;sing&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;
		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;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;lyrics&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;singLater&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; singWithContext &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;sing&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;&lt;span class=&quot;token keyword&quot;&gt;this&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;setTimeout&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;singWithContext&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 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;

john&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;singLater&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;// 🎵 Let is be, let it be&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;picture class=&quot;&quot;&gt;
		&lt;source type=&quot;image/webp&quot; srcset=&quot;https://zenzes.me/assets/images/gdNsPHve3L-400.webp 400w, https://zenzes.me/assets/images/gdNsPHve3L-602.webp 602w&quot; sizes=&quot;100vw&quot; /&gt;
&lt;source type=&quot;image/png&quot; srcset=&quot;https://zenzes.me/assets/images/gdNsPHve3L-400.png 400w, https://zenzes.me/assets/images/gdNsPHve3L-602.png 602w&quot; sizes=&quot;100vw&quot; /&gt;
		&lt;img src=&quot;https://zenzes.me/assets/images/gdNsPHve3L-602.webp&quot; width=&quot;602&quot; height=&quot;407&quot; alt=&quot;Die Funktion sing wird an this gebunden&quot; class=&quot;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; /&gt;
	&lt;/picture&gt;
&lt;p&gt;Das geht auch noch etwas kürzer:&lt;/p&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; john &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;lyrics&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;Let is be, let it be&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
	&lt;span class=&quot;token function&quot;&gt;sing&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;
		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;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;lyrics&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;singLater&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; singWithContext &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;sing&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;&lt;span class=&quot;token keyword&quot;&gt;this&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;setTimeout&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;singWithContext&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;
john&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;singLater&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;// 🎵 Let is be, let it be&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Man kann &lt;code&gt;bind&lt;/code&gt; auch noch nutzen, um sich Methoden von anderen Objekten zu „borgen“: Nehmen wir einmal das folgende Beispiel:&lt;/p&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; farin &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;firstName&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;Farin&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
	&lt;span class=&quot;token literal-property property&quot;&gt;lastName&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;Urlaub&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
	&lt;span class=&quot;token function-variable function&quot;&gt;fullName&lt;/span&gt;&lt;span class=&quot;token operator&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;return&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 interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;firstName&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&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;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;lastName&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&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;
	&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; bela &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;firstName&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;Bela B&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
	&lt;span class=&quot;token literal-property property&quot;&gt;lastName&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;Felsenheimer&#39;&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;farin&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;fullName&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 comment&quot;&gt;// Farin Urlaub&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Mittels &lt;code&gt;bind&lt;/code&gt; können wir jetzt den Kontext von Farins &lt;code&gt;fullName()&lt;/code&gt; ändern, um auch den Namen von Bela B auszugeben&lt;/p&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; farin &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;firstName&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;Farin&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
	&lt;span class=&quot;token literal-property property&quot;&gt;lastName&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;Urlaub&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
	&lt;span class=&quot;token function-variable function&quot;&gt;fullName&lt;/span&gt;&lt;span class=&quot;token operator&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;return&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 interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;firstName&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&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;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;lastName&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&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;
	&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; bela &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;firstName&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;Bela B&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
	&lt;span class=&quot;token literal-property property&quot;&gt;lastName&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;Felsenheimer&#39;&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;farin&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;fullName&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 comment&quot;&gt;// Farin Urlaub&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; belaBFullName &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; farin&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;fullName&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;bela&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;&lt;span class=&quot;token function&quot;&gt;belaBFullName&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 comment&quot;&gt;// Bela B Felsenheimer&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;picture class=&quot;&quot;&gt;
		&lt;source type=&quot;image/webp&quot; srcset=&quot;https://zenzes.me/assets/images/KXxNVHqr17-400.webp 400w, https://zenzes.me/assets/images/KXxNVHqr17-666.webp 666w&quot; sizes=&quot;100vw&quot; /&gt;
&lt;source type=&quot;image/png&quot; srcset=&quot;https://zenzes.me/assets/images/KXxNVHqr17-400.png 400w, https://zenzes.me/assets/images/KXxNVHqr17-666.png 666w&quot; sizes=&quot;100vw&quot; /&gt;
		&lt;img src=&quot;https://zenzes.me/assets/images/KXxNVHqr17-666.webp&quot; width=&quot;666&quot; height=&quot;490&quot; alt=&quot;Die Funktion fullName aus dem Objekt farin wird an das Objekt bela gebunden&quot; class=&quot;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; /&gt;
	&lt;/picture&gt;
&lt;p&gt;An einem unbekannten Ort ruft jemand jetzt wahrscheinlich: &amp;quot;Das geht auch mit Vererbung!&amp;quot; und diese Person hat auch mehr oder weniger Recht. Wir nutzen hier aber JavaScript und damit eine (halbwegs) funktionale Programmiersprache und diese bietet uns halt Wege, die in anderen Programmiersprachen so nicht existieren.&lt;/p&gt;
&lt;h2 id=&quot;apply-und-call&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://zenzes.me/mit-bind-call-und-apply-den-kontext-in-javascript-meistern/#apply-und-call&quot;&gt;apply und call&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Jetzt ist es stellenweise auch etwas umständlich, die mit &lt;code&gt;bind&lt;/code&gt; an einen Kontext gebundene Funktion immer in einer Variable speichern zu müssen.&lt;/p&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; rod &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;firstName&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;Rod&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
	&lt;span class=&quot;token literal-property property&quot;&gt;lastName&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;Gonzales&#39;&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;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;sing&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;lyrics&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;&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 interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;firstName&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&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;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;lastName&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&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;lyrics&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&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;&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; rodSings &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;sing&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;rod&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;rodSings&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;Das sind Dinge, von denen ich gar nichts wissen will&#39;&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;// 🎵 Rod Gonzales: Das sind Dinge, von denen ich gar nichts wissen will&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Mit &lt;code&gt;apply&lt;/code&gt; und &lt;code&gt;call&lt;/code&gt; können wir das etwas verkürzen&lt;/p&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; rod &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;firstName&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;Rod&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
	&lt;span class=&quot;token literal-property property&quot;&gt;lastName&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;Gonzales&#39;&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;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;sing&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;lyrics&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;&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 interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;firstName&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&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;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;lastName&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&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;lyrics&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&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;&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;sing&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;call&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;rod&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;Das sind Dinge, von denen ich gar nichts wissen will&#39;&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;// 🎵 Rod Gonzales: Das sind Dinge, von denen ich gar nichts wissen will&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Bei &lt;code&gt;call&lt;/code&gt; geben wir erst den Kontext an und dann alle Parameter, mit denen wir die Funktion aufrufen wollen.&lt;/p&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; rod &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;firstName&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;Rod&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
	&lt;span class=&quot;token literal-property property&quot;&gt;lastName&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;Gonzales&#39;&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;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;sing&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;lyrics&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; 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;&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 interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;firstName&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&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;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;lastName&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&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;lyrics&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&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;&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;sing&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;apply&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;rod&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 string&quot;&gt;&#39;Das sind Dinge, von denen ich gar nichts wissen will&#39;&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;// 🎵 Rod Gonzales: Das sind Dinge, von denen ich gar nichts wissen will&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Der Unterschied zu &lt;code&gt;apply&lt;/code&gt; ist minimal: &lt;code&gt;apply&lt;/code&gt; erwartet als zweiten Parameter einen Array, der alle Parameter für einen Aufruf enthält.&lt;/p&gt;
&lt;p&gt;Mit &lt;code&gt;bind&lt;/code&gt;, &lt;code&gt;apply&lt;/code&gt; und &lt;code&gt;call&lt;/code&gt;, haben wir drei Möglichkeiten, den Kontext einer Funktion zu manipulieren. Das ist definitiv einfacher zu lesen als Hilfsvariablen wie &lt;code&gt;that&lt;/code&gt; oder &lt;code&gt;self&lt;/code&gt; zu nutzen. Ich selbst nutze die drei aber, wie erwähnt, selten. Dies liegt wahrscheinlich daran, dass ich eher funktional programmiere und Objekte bei mir meistens nur Daten enthalten.&lt;/p&gt;
&lt;p&gt;Wie sieht Eure Erfahrung hier aus? Schlagt ihr Euch mit dem Kontext in Euren Programmen herum und setzt &lt;code&gt;bind&lt;/code&gt;, &lt;code&gt;apply&lt;/code&gt; und &lt;code&gt;call&lt;/code&gt; ein oder geht es Euch wie mir? Schreibt mir gerne auf &lt;a href=&quot;https://chaos.social/@danielzenzes&quot;&gt;Mastodon&lt;/a&gt;.&lt;/p&gt;
</description>
        <pubDate>Wed, 27 Jul 2022 15:00:00 +0200</pubDate>
        <dc:creator>Daniel Zenzes</dc:creator>
        <guid>https://zenzes.me/mit-bind-call-und-apply-den-kontext-in-javascript-meistern/</guid>
      </item>
      <item>
        <title>this in JavaScript verstehen</title>
        <link>https://zenzes.me/this-in-javascript-verstehen/</link>
        <description>&lt;p&gt;Gerade als ich mit JavaScript losgelegt habe, habe ich versucht &lt;code&gt;this&lt;/code&gt; in meinem Code zu vermeiden. Ich sage nur &lt;code&gt;undefined is not a function&lt;/code&gt;. Zu beliebig wirkte das Verhalten, verglichen mit anderen Sprachen, die ich damals kannte.&lt;/p&gt;
&lt;p&gt;Da ich immer mal wieder gefragt werde, wie das Ganze denn funktioniert, dachte ich mir, ich schreibe es hier mal zusammen.&lt;/p&gt;
&lt;h2 id=&quot;kontext&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://zenzes.me/this-in-javascript-verstehen/#kontext&quot;&gt;Kontext&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Im Gegensatz zu anderen Programmiersprachen, bei denen sich &lt;code&gt;this&lt;/code&gt; auf Objekte bezieht (also die jeweilige Instanz einer Klasse), bezieht sich &lt;code&gt;this&lt;/code&gt; in JavaScript auf den Kontext, in dem es aufgerufen wird. Wichtig ist zudem, &lt;em&gt;wie&lt;/em&gt; es aufgerufen wird, da wir dadurch diesen Kontext verändern können.&lt;/p&gt;
&lt;h2 id=&quot;globaler-kontext&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://zenzes.me/this-in-javascript-verstehen/#globaler-kontext&quot;&gt;Globaler Kontext&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Fangen wir an mit dem &lt;em&gt;globalen Kontext&lt;/em&gt; an. Im Browser ist dies die &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/Window&quot; title=&quot;Mozilla Developer Network Artikel zu Window&quot;&gt;Window&lt;/a&gt; Instanz.&lt;/p&gt;
&lt;p&gt;Wenn man in einem Browser die Developer Tools öffnet und dort in der Konsole &lt;code&gt;console.log(this)&lt;/code&gt; eingibt und Enter drückt, sieht man die aktuelle Instanz des Window Objekts für die aktuelle Seite.&lt;/p&gt;
&lt;picture class=&quot;&quot;&gt;
		&lt;source type=&quot;image/webp&quot; srcset=&quot;https://zenzes.me/assets/images/hYiYkP1c15-400.webp 400w, https://zenzes.me/assets/images/hYiYkP1c15-800.webp 800w, https://zenzes.me/assets/images/hYiYkP1c15-1280.webp 1280w, https://zenzes.me/assets/images/hYiYkP1c15-2326.webp 2326w&quot; sizes=&quot;100vw&quot; /&gt;
&lt;source type=&quot;image/png&quot; srcset=&quot;https://zenzes.me/assets/images/hYiYkP1c15-400.png 400w, https://zenzes.me/assets/images/hYiYkP1c15-800.png 800w, https://zenzes.me/assets/images/hYiYkP1c15-1280.png 1280w, https://zenzes.me/assets/images/hYiYkP1c15-2326.png 2326w&quot; sizes=&quot;100vw&quot; /&gt;
		&lt;img src=&quot;https://zenzes.me/assets/images/hYiYkP1c15-2326.webp&quot; width=&quot;2326&quot; height=&quot;1974&quot; alt=&quot;Entwicklerkonsole zeigt den Wert von this auf dieser Seite&quot; class=&quot;&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; /&gt;
	&lt;/picture&gt;
&lt;p&gt;Dieser Code gibt, wenn ihr ihn in Node.js ausführt, ein leeres Objekt &lt;code&gt;{}&lt;/code&gt; aus.&lt;/p&gt;
&lt;h2 id=&quot;innerhalb-von-konstruktoren&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://zenzes.me/this-in-javascript-verstehen/#innerhalb-von-konstruktoren&quot;&gt;Innerhalb von Konstruktoren&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Die nächste Möglichkeit, &lt;code&gt;this&lt;/code&gt; zu verwenden ist innerhalb eines Objekts. Wenn wir ein Objekt mithilfe einer Funktion und des &lt;code&gt;new&lt;/code&gt; Keywords erstellen, können wir hier mit &lt;code&gt;this&lt;/code&gt; Werte für das Objekt definieren.&lt;/p&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;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;Person&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;age&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;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;age &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; age&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; john &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;Person&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;24&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;john&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;// Person {age: 24, constructor: Object}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;objekt-methoden&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://zenzes.me/this-in-javascript-verstehen/#objekt-methoden&quot;&gt;Objekt Methoden&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Wenn wir nun Objekte erstellen und in diesen Methoden definieren, dann macht &lt;code&gt;this&lt;/code&gt;, was viele erwarten: es referenziert das eigentliche Objekt. Um den Code übersichtlicher zu gestalten, verzichte ich auf die Konstruktor Funktion.&lt;/p&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;let&lt;/span&gt; george &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;age&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;25&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
	&lt;span class=&quot;token function&quot;&gt;whoAmI&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;
		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;&lt;span class=&quot;token keyword&quot;&gt;this&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;

george&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;whoAmI&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;// {age: 25, whoAmI: ƒ whoAmI()}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Somit kann ich jetzt also auch auf Werte innerhalb meines Objekts zurückgreifen.&lt;/p&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; ringo &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;age&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;26&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
	&lt;span class=&quot;token function&quot;&gt;getAge&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 keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;age&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;

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;ringo&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;// Object { age: 26, getAge: getAge() }&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;ringo&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getAge&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 comment&quot;&gt;// 26&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Wahrscheinlich geht es Euch bis hierhin so, wie mir: Das alles ist vertraut und klappt ähnlich wie bei Objekt-orientierten Programmiersprachen. Kniffliger wird es, wenn wir uns Funktionen ansehen.&lt;/p&gt;
&lt;h2 id=&quot;funktionen&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://zenzes.me/this-in-javascript-verstehen/#funktionen&quot;&gt;Funktionen&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Innerhalb von Funktionen verweist &lt;code&gt;this&lt;/code&gt; immer auf den globalen Kontext (im Browser also das Window).&lt;/p&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;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;showContext&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;
	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;&lt;span class=&quot;token keyword&quot;&gt;this&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;showContext&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;// Window&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Das ist so weit in Ordnung, wenn ich aber jetzt eine Funktion, die &lt;code&gt;this&lt;/code&gt; nutzt innerhalb eines Objekts nutze, dann würde ich erwarten, dass sie auf den gerade gültigen Kontext (also das Objekt) verweist. Tut sie aber nicht.&lt;/p&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;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;showContext&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;
	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;&lt;span class=&quot;token keyword&quot;&gt;this&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; paul &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;show&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;showContext&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 function&quot;&gt;showContext&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;// Window&lt;/span&gt;
paul&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;show&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;// Window&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Obwohl meine Funktion &lt;code&gt;show&lt;/code&gt; in einem Objekt liegt, zeigt &lt;code&gt;showContext&lt;/code&gt; mir das Window an. Hier straucheln Einsteiger und mir ging es da auch nicht besser. Der Grund hierfür ist, dass der Kontext von &lt;code&gt;showContext&lt;/code&gt; weiterhin das &lt;code&gt;Window&lt;/code&gt; ist und der Aufruf für den Kontext keine Rolle spielt.&lt;/p&gt;
&lt;p&gt;Aber wie kann ich damit umgehen?&lt;/p&gt;
&lt;p&gt;Nehmen wir ein zweites, ähnliches Beispiel:&lt;/p&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; john &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;sing&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;
		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;&lt;span class=&quot;token string&quot;&gt;&#39;Let is be, let it be&#39;&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;singLater&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;setTimeout&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;
			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;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;sing&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 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;
john&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;singLater&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;// 💥 Uncaught TypeError: this.sing is not a function&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Dies funktioniert nicht, da innerhalb von &lt;code&gt;setTimeout&lt;/code&gt; &lt;code&gt;this&lt;/code&gt; an das Window gebunden ist und dort gibt es die Funktion &lt;code&gt;sing&lt;/code&gt; nicht. Eine schnelle Lösung ist es, &lt;code&gt;this&lt;/code&gt; in einer anderen Variable zu speichern:&lt;/p&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; john &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;sing&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;
		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;&lt;span class=&quot;token string&quot;&gt;&#39;Let is be, let it be&#39;&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;singLater&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; that &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
		&lt;span class=&quot;token function&quot;&gt;setTimeout&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;
			that&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;sing&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 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;
john&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;singLater&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;// 🎵 Let is be, let it be&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Manche nennen diese Variable &lt;code&gt;that&lt;/code&gt;, andere nennen sie &lt;code&gt;self&lt;/code&gt;. Der Name ist hier recht egal, wichtig ist, dass der richtige Kontext hier gespeichert wird und dieser innerhalb von anderen Funktionen dann genutzt werden kann.&lt;/p&gt;
&lt;p&gt;Seit ein paar Jahren geht dies aber auch etwas einfacher.&lt;/p&gt;
&lt;h2 id=&quot;arrow-funktionen&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://zenzes.me/this-in-javascript-verstehen/#arrow-funktionen&quot;&gt;Arrow Funktionen&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Arrow Funktionen wurden mit ES2015 eingeführt und ihr werdet sie sicher schon oft gesehen haben. Manche halten sie für cooler, andere haben sich gemerkt, dass man mit ihnen weniger Probleme mit &lt;code&gt;this&lt;/code&gt; hat, denn sie haben einen wichtigen Unterschied zu normalen Funktionen:&lt;/p&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; george &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;sing&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;
		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;&lt;span class=&quot;token string&quot;&gt;&#39;Let is be, let it be&#39;&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;singLater&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;setTimeout&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;
			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;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;sing&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 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;
george&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;singLater&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;// 🎵 Let is be, let it be&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Innerhalb von Arrow Funktionen ist &lt;code&gt;this&lt;/code&gt; an den gleichen Kontext gebunden, wie außerhalb der Funktion. Ich selbst nutze Arrow Funktionen daher am liebsten auch nur, wenn ich mit &lt;code&gt;this&lt;/code&gt; arbeiten muss, denn:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;so kann ich klar ausdrücken, dass ich hier eine Funktion habe, bei der der Kontext wichtig ist, und&lt;/li&gt;
&lt;li&gt;Arrow Funktionen sind &lt;em&gt;anonyme Funktionen&lt;/em&gt; und daher sind sie nicht so gut zu debuggen.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;event-listener&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://zenzes.me/this-in-javascript-verstehen/#event-listener&quot;&gt;Event Listener&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Innerhalb von Event Listenern ist &lt;code&gt;this&lt;/code&gt; an das Element gebunden, welches das Event ausgelöst hat:&lt;/p&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; button &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; document&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;querySelector&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;button&#39;&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;

button&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addEventListener&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;click&#39;&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;
	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;&lt;span class=&quot;token keyword&quot;&gt;this&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;// button&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;p&gt;Auch hier kann ich Arrow Funktionen nutzen. Wenn ich &lt;code&gt;this&lt;/code&gt; und das Element benötige, dann habe ich zwei Möglichkeiten:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;den Kontext vorher in einer Variable &lt;code&gt;that&lt;/code&gt; oder &lt;code&gt;self&lt;/code&gt; speichern, oder&lt;/li&gt;
&lt;li&gt;in der Arrow Funktion das jeweilige Event nutzen, da dieses das Element in &lt;code&gt;event.currentTarget&lt;/code&gt; speichert.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;HTML:&lt;/p&gt;
&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;button&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;play&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;button&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;JavaScript&lt;/p&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;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;Jukebox&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 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 function&quot;&gt;listenStart&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;
			element&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addEventListener&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;click&#39;&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 parameter&quot;&gt;event&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;
				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;event&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;currentTarget&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;// my element&lt;/span&gt;
				&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;play&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;// 🎵 Let is be, let it be&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;play&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;
			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;&lt;span class=&quot;token string&quot;&gt;&#39;Let is be, let it be&#39;&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;const&lt;/span&gt; button &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; document&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;querySelector&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;button&#39;&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; box &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;Jukebox&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;button&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
box&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;listenStart&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;p&gt;Das war ein erster Überblick, wie &lt;code&gt;this&lt;/code&gt; in JavaScript funktioniert und wie es sich, abhängig vom Kontext verhält. Arrow Funktionen sind hier das Mittel der Wahl, um das Verhalten so zu verändern, wie ihr es gerade benötigt. Wenn ihr mehr Artikel wie diesen lesen möchtet, schreibt mir gerne auf &lt;a href=&quot;https://chaos.social/@danielzenzes&quot;&gt;Mastodon&lt;/a&gt;.&lt;/p&gt;
</description>
        <pubDate>Sun, 24 Jul 2022 15:00:00 +0200</pubDate>
        <dc:creator>Daniel Zenzes</dc:creator>
        <guid>https://zenzes.me/this-in-javascript-verstehen/</guid>
      </item>
      <item>
        <title>Eleventy: PostCSS und Tailwind CSS integrieren</title>
        <link>https://zenzes.me/eleventy-postcss-und-tailwind-css-integrieren/</link>
        <description>&lt;p&gt;In meinem Eleventy Tutorial habe ich ja bereits gezeigt, wie man einen Blog mit Eleventy aufsetzen kann und auch, &lt;a href=&quot;https://zenzes.me/ein-einfacher-einstieg-in-eleventy/#css-einbinden&quot; title=&quot;Blogpost: Ein einfacher Einstieg in Eleventy. Link zum Abschnitt über CSS.&quot;&gt;wie man CSS in eine Eleventy Webseite integieren kann&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Da ich gerne mit Tailwind CSS arbeite, möchte ich dieses natürlich auch in meinen privaten Projekten einsetzen und habe hier auch einige Setups ausprobiert. Die meisten setzen hierbei PostCSS und TailwindCSS &amp;quot;klassisch&amp;quot; auf und passen dann die Skripte in der package.json so an, dass erst die Eleventy Seite gebaut wird und dann das passende CSS generiert wird. Das kann man so tun, machte in meinen Augen aber das Setup in der package.json komplizierter.&lt;/p&gt;
&lt;p&gt;Meine Alternative nutzt Eleventy Bordmittel, um das CSS zu generieren und fügt sich mit wenigen Zeilen Code in die bestehende Konfiguration ein.&lt;/p&gt;
&lt;p&gt;Das ganze könnt ihr Euch in &lt;a href=&quot;https://github.com/dzenzes/11ty-start&quot; title=&quot;GitHub: 11ty start Projekt&quot;&gt;meinem Tutorial Projekt&lt;/a&gt; im &lt;a href=&quot;https://github.com/dzenzes/11ty-start/tree/tailwind&quot; title=&quot;GitHub: 11ty-start Projekt. tailwind branch&quot;&gt;tailwind Branch&lt;/a&gt; ansehen (&lt;a href=&quot;https://github.com/dzenzes/11ty-start/commit/b24ce9bdde1a2315bcc15814308416531a00608a&quot; title=&quot;Commit mit Änderungen aus diesem Blogpost&quot;&gt;commit&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;Die Idee ist die folgende: Statt einem nachgelagerten Prozess, nutzen wir während des Builds über einen asynchronen Filter PostCss und erzeugen so über Eleventy auch direkt unser CSS.&lt;/p&gt;
&lt;p&gt;Damit wir PostCSS und Tailwind CSS nutzen können, müssen wir es im ersten Schritt installieren:&lt;/p&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; i &lt;span class=&quot;token parameter variable&quot;&gt;-D&lt;/span&gt; tailwindcss postcss autoprefixer cssnano&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In unserer Eleventy Konfiguration benötigen wir jetzt noch einen asynchronen Filter:&lt;/p&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; tailwind &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;&#39;tailwindcss&#39;&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; postCss &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;&#39;postcss&#39;&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; autoprefixer &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;&#39;autoprefixer&#39;&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; cssnano &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;&#39;cssnano&#39;&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; &lt;span class=&quot;token function-variable function&quot;&gt;postcssFilter&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;cssCode&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; done&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 comment&quot;&gt;// wir rufen hier PostCSS auf.&lt;/span&gt;
	&lt;span class=&quot;token function&quot;&gt;postCss&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;tailwind&lt;/span&gt;&lt;span class=&quot;token punctuation&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;&#39;./tailwind.config&#39;&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;autoprefixer&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;cssnano&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;preset&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;default&#39;&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;process&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;cssCode&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;// Pfad zu unserer CSS Datei&lt;/span&gt;
			&lt;span class=&quot;token literal-property property&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;./src/_includes/styles/tailwind.css&#39;&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;then&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 parameter&quot;&gt;r&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 function&quot;&gt;done&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; r&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;css&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 parameter&quot;&gt;e&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 function&quot;&gt;done&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;e&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&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;p&gt;Natürlich könnt ihr mit wenigen Anpassungen auch nur PostCSS nutzen. Lasst dann einfach den Tailwind CSS spezifischen Code raus.&lt;/p&gt;
&lt;p&gt;Den Filter fügen wir jetzt in der Konfiguration, zusammen mit einem &amp;quot;watch target&amp;quot;, hinzu&lt;/p&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;module&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function-variable function&quot;&gt;exports&lt;/span&gt; &lt;span class=&quot;token operator&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 parameter&quot;&gt;config&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;// ...&lt;/span&gt;
	config&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addWatchTarget&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;./src/_includes/styles/tailwind.css&#39;&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;
	config&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addNunjucksAsyncFilter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;postcss&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; postcssFilter&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;// ...&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;p&gt;Über &lt;code&gt;addWatchTarget&lt;/code&gt; teilen wir Eleventy mit, dass Änderungen an dieser Datei einen erneute build auslösen sollen, wenn wir gerade die Anwendung lokal mit &lt;code&gt;--serve&lt;/code&gt; laufen lassen. Der asynchrone Filter sorgt dafür, dass wir unser CSS umwandeln können.&lt;/p&gt;
&lt;p&gt;Jetzt fehlt nur noch das CSS, welches wir unter &lt;code&gt;./src/_includes/styles/tailwind.css&lt;/code&gt; im Projekt hinzufügen. Dort kann natürlich ganz normal mit Tailwind CSS gearbeitet werden:&lt;/p&gt;
&lt;pre class=&quot;language-css&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token atrule&quot;&gt;&lt;span class=&quot;token rule&quot;&gt;@tailwind&lt;/span&gt; base&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token atrule&quot;&gt;&lt;span class=&quot;token rule&quot;&gt;@tailwind&lt;/span&gt; components&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token atrule&quot;&gt;&lt;span class=&quot;token rule&quot;&gt;@tailwind&lt;/span&gt; utilities&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Wenn wir jetzt unser CSS in der Seite ergänzen möchten, haben wir zwei Möglichkeiten:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;als inline style an beliebiger Stelle in unsererm template&lt;/li&gt;
&lt;li&gt;als eigene CSS Datei&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Welche Variante hier die richtige ist, hängt stark vom Projekt ab und ist wahrscheinlich einen eigenen Blogpost wert. Ich zeige hier schnell beide Varianten:&lt;/p&gt;
&lt;p&gt;Im &lt;code&gt;head&lt;/code&gt; der Seite (in unserem Beispiel in der Datei &lt;code&gt;src/_includes/layout.njk&lt;/code&gt;):&lt;/p&gt;
&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;style&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token style&quot;&gt;&lt;span class=&quot;token language-css&quot;&gt;
	&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;% set css %&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
	&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;% include &lt;span class=&quot;token string&quot;&gt;&quot;styles/tailwind.css&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;% endset %&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;css | postcss | safe&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;style&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Wir setzen hier zunächst den Wert &lt;code&gt;css&lt;/code&gt; im Template und nutzen dann den &lt;code&gt;postcss&lt;/code&gt; Filter. Über den &lt;code&gt;safe&lt;/code&gt; Filter wird das ganze dann in unserem Template eingefügt. Für mich die richtige Lösung, wenn ich nur wenig CSS habe und die erzeugte HTML Datei nicht zu groß wird.&lt;/p&gt;
&lt;p&gt;Wenn man lieber eine eigene CSS Datei erzeugen möchte, kann man dies über ein eigenes Template machen (z. B. &lt;code&gt;src/style.njk&lt;/code&gt;)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;---
permalink: style.css
---
{% set css %}
{% include &amp;quot;styles/tailwind.css&amp;quot; %}
{% endset %}
{{css | postcss | safe}}

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Dank dem &lt;code&gt;permalink&lt;/code&gt; in der FrontMatter wird diese Datei als &lt;code&gt;style.css&lt;/code&gt; erzeugt und kann dann in unserem Template eingebettet werden (&lt;code&gt;src/_includes/layout.njk&lt;/code&gt;).&lt;/p&gt;
&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;link&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;rel&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;stylesheet&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;href&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;/style.css&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Kennt ihr einen besseren Weg, um CSS in Eleventy zu erzeugen und integrieren? Habt ihr weitere Fragen zu Eleventy? Schreibt mir gerne auf &lt;a href=&quot;https://chaos.social/@danielzenzes&quot;&gt;Mastodon&lt;/a&gt;.&lt;/p&gt;
</description>
        <pubDate>Mon, 04 Jul 2022 15:00:00 +0200</pubDate>
        <dc:creator>Daniel Zenzes</dc:creator>
        <guid>https://zenzes.me/eleventy-postcss-und-tailwind-css-integrieren/</guid>
      </item>
      <item>
        <title>Eleventy Templates mit Daten anreichern</title>
        <link>https://zenzes.me/eleventy-templates-mit-daten-anreichern/</link>
        <description>&lt;p&gt;Einer der Gründe, weshalb ich ein großer Fan von Eleventy bin, ist die Möglichkeit, Templates mit beliebigen Daten anzureichern und daraus Seiten zu generieren. Früher habe ich Seiten normalerweise mit Wordpress erstellt, da ich es kannte und damit meine Probleme lösen konnte. Als ich dann anfing, einen Podcast zu veröffentlichen, brachte mich Christian (&lt;a href=&quot;https://twitter.com/derschepp&quot; title=&quot;Christian Schaefer bei Twitter&quot;&gt;@derschepp&lt;/a&gt;) auf die Idee, mit einem static-site generator meine Webseite zu veröffentlichen, da es hier ja möglich sei aus externen Daten, wie einem RSS-Feed, die Webseite zu erzeugen.&lt;/p&gt;
&lt;p&gt;Ich war neugierig und fing an, mit Eleventy herumzuspielen und 5 Jahre später, ist es noch immer mein favorisiertes Tool, wenn es darum geht, Webseiten zu erstellen.&lt;/p&gt;
&lt;p&gt;In diesem Artikel gebe ich einen Einblick in den Umgang mit Daten in Eleventy, &lt;a href=&quot;https://zenzes.me/#der-_data-ordner&quot;&gt;wo man diese definiert&lt;/a&gt;, &lt;a href=&quot;https://zenzes.me/#dynamische-daten-erzeugen-und-einbinden&quot;&gt;wie man hier mit dynamischen Daten arbeiten kann&lt;/a&gt; und wie wir, bis zu einem gewissen Grad, &lt;a href=&quot;https://zenzes.me/eleventy-templates-mit-daten-anreichern/#%22dynamische%22-templates&quot;&gt;dynamische Templates&lt;/a&gt; erstellen können.&lt;/p&gt;
&lt;h2 id=&quot;der-_data-ordner&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://zenzes.me/eleventy-templates-mit-daten-anreichern/#der-_data-ordner&quot;&gt;Der &lt;code&gt;_data&lt;/code&gt; Ordner&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Ursprung für alle Daten, ist der &lt;code&gt;_data&lt;/code&gt; Ordner: hier kann man &lt;code&gt;.json&lt;/code&gt; und &lt;code&gt;.js&lt;/code&gt; Dateien ablegen, die Daten bereitstellen.&lt;/p&gt;
&lt;p&gt;Auf dieser Webseite habe ich in meinem &lt;code&gt;_data&lt;/code&gt; Ordner beispielsweise eine &lt;code&gt;metadata.json&lt;/code&gt;, die u. a. folgende Inhalte hat:&lt;/p&gt;
&lt;pre class=&quot;language-json&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;token property&quot;&gt;&quot;social&quot;&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 property&quot;&gt;&quot;href&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;https://chaos.social/web/@danielzenzes&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token property&quot;&gt;&quot;title&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Mastodon&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 property&quot;&gt;&quot;href&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;https://github.com/dzenzes&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token property&quot;&gt;&quot;title&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;GitHub&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;/code&gt;&lt;/pre&gt;
&lt;p&gt;In jedem meiner templates kann ich auf diese Informationen zugreifen und daraus meine Seite generieren. Die oben genannten Daten nutze ich im Footer, um die Links zu erzeugen.&lt;/p&gt;
&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;{%- for link in metadata.social %}
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;a&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;href&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;{{ link.href | url }}&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;{{ link.title }}&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;a&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
{%- endfor %} &lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;dynamische-daten-erzeugen-und-einbinden&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://zenzes.me/eleventy-templates-mit-daten-anreichern/#dynamische-daten-erzeugen-und-einbinden&quot;&gt;Dynamische Daten erzeugen und einbinden&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Nun gibt es aber auch immer wieder Daten, die aus einer anderen Quelle stammen und aus denen man Seiten generieren möchte. Bei mir war das ursprünglich immer der Wunsch, den RSS-Feed, den mein Podcast Anbieter bereitstellt, zu konsumieren und daraus eine Seite zu erzeugen. Hierzu lege ich im &lt;code&gt;_data&lt;/code&gt; Verzeichnis eine Datei episodes.js an und nutze folgenden Code (hier etwas vereinfacht)&lt;/p&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; Parser &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;&#39;rss-parser&#39;&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;&lt;span class=&quot;token function-variable function&quot;&gt;exports&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;async&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;let&lt;/span&gt; parser &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;Parser&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 keyword&quot;&gt;await&lt;/span&gt; parser&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;parseURL&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;https://herrmies.podigee.io/feed/mp3&#39;&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;p&gt;Mithilfe von &lt;a href=&quot;https://www.npmjs.com/package/rss-parser&quot; title=&quot;rss-parser library im npm Repository&quot;&gt;&lt;code&gt;rss-parser&lt;/code&gt;&lt;/a&gt; lade ich den RSS-Feed und wandle ihn in json um. Nun kann ich diese Dateien in meinem Template verwenden und könnte so unter anderem eine Liste der Folgen mit einem kleinen Audioplayer erzeugen:&lt;/p&gt;
&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;{% for item in episodes.items %}
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;article&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
	&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;h2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;{{item.title}}&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;h2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;

	&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;audio&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;audio&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;controls&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;controls&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;preload&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;auto&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
		&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;source&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;audio/mpeg&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;src&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;{{item.enclosure.url}}&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;
	&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;audio&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;article&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
{% endfor %}&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;%22dynamische%22-templates&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://zenzes.me/eleventy-templates-mit-daten-anreichern/#%22dynamische%22-templates&quot;&gt;&amp;quot;Dynamische&amp;quot; Templates&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Etwas, das ich auf der Seite von &lt;a href=&quot;https://davidea.st/articles/11ty-tips-i-wish-i-knew-from-the-start/&quot; title=&quot;David East - 11ty tips I wish I knew from the start&quot;&gt;David East&lt;/a&gt; gelernt habe, sind dynamische Templates. Man kann nämlich auch aus Templates heraus relativ komfortabel Inhalte laden.&lt;/p&gt;
&lt;p&gt;Zunächst benötigen wir hierfür einen asynchronen &lt;a href=&quot;https://www.11ty.dev/docs/shortcodes/&quot; title=&quot;Documentation zu Shortcodes&quot;&gt;Shortcode&lt;/a&gt;. Shortcodes sind eine Möglichkeit, die jeweils verwendete Template-Engine, um eigene Befehle zu erweitern.&lt;/p&gt;
&lt;p&gt;Sagen wir mal, wir möchten Code aus unserem GitHub Repository dynamisch in unseren Templates einbinden. Hierzu könnten wir in diesen folgenden Code ergänzen:&lt;/p&gt;
&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;pre&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;code&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
        {% github path=&quot;user/repo/branch/file.js&quot; %}
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;code&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;pre&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Der Shortcode muss dann nur noch in der Eleventy Konfiguration (&lt;code&gt;.eleventy,js&lt;/code&gt;) angelegt werden:&lt;/p&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;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; fetch &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;&#39;node-fetch&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;fetchCode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;githubPath&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; response &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;fetch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;githubUrl&lt;/span&gt;&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;https://raw.githubusercontent.com/&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;githubPath&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&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;&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; code &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; response&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;text&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 punctuation&quot;&gt;{&lt;/span&gt; githubPath&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;

module&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function-variable function&quot;&gt;exports&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;eleventyConfig&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 comment&quot;&gt;// ...&lt;/span&gt;
	eleventyConfig&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addNunjucksAsyncShortcode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;github&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;async&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;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; path &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 punctuation&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &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 keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;fetchCode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;path&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; 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;span class=&quot;token comment&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;p&gt;Natürlich sind diese Templates nur zur Build-Time &amp;quot;dynamisch&amp;quot; da am Ende eine statische Seite erzeugt wird. Wenn man hier noch Daten laden möchte kommt man an JavaScript nicht vorbei.&lt;/p&gt;
&lt;p&gt;Kennt ihr noch andere Anwendungsfälle für Daten in Eleventy oder habt ihr einen kreativen Use-Case? Schreibt mir gerne auf &lt;a href=&quot;https://chaos.social/@danielzenzes&quot;&gt;Mastodon&lt;/a&gt;.&lt;/p&gt;
</description>
        <pubDate>Tue, 28 Jun 2022 15:00:00 +0200</pubDate>
        <dc:creator>Daniel Zenzes</dc:creator>
        <guid>https://zenzes.me/eleventy-templates-mit-daten-anreichern/</guid>
      </item>
      <item>
        <title>Ein einfacher Einstieg in Eleventy</title>
        <link>https://zenzes.me/ein-einfacher-einstieg-in-eleventy/</link>
        <description>&lt;p&gt;&lt;a href=&quot;https://www.11ty.dev/&quot; title=&quot;Offizielle Eleventy Seite&quot;&gt;Eleventy&lt;/a&gt; (11ty) ist schon seit einigen Jahren mein Tool der Wahl, wenn es um die Erstellung von Webseiten geht. Dabei eignet sich Eleventy sowohl für eine einfache statische Seite, einen Blog wie diesen oder auch die Seite zu meinem Podcast &lt;a href=&quot;https://ready-for-review.dev/&quot; title=&quot;Mein Podcast: Ready for Review&quot;&gt;Ready for Review&lt;/a&gt;.&lt;br /&gt;
Das schöne ist, dass man hier recht schnell gute Ergebnisse erzielen kann und daher zeige ich in diesem Tutorial, die Grundlagen um einen Blog zu erstellen.&lt;/p&gt;
&lt;p&gt;Den Code für dieses Tutorial habe ich &lt;a href=&quot;https://github.com/dzenzes/11ty-start&quot; title=&quot;GitHub Repository mit dem Code zu diesem Tutorial&quot;&gt;auf Github veröffentlicht&lt;/a&gt;. Die Zielgruppe sind Menschen, die Eleventy lernen wollen. Ich zeige im Folgenden:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;wie man &lt;a href=&quot;https://zenzes.me/ein-einfacher-einstieg-in-eleventy/#schritt-1%3A-eine-einzelne-seite&quot; title=&quot;Schritt 1: Eine einzelne Seite&quot;&gt;eine einzelne Seite&lt;/a&gt; mit Eleventy erstellt (&lt;a href=&quot;https://github.com/dzenzes/11ty-start&quot; title=&quot;main Branch mit Code Beispiel&quot;&gt;main&lt;/a&gt; branch),&lt;/li&gt;
&lt;li&gt;wie man &lt;a href=&quot;https://zenzes.me/ein-einfacher-einstieg-in-eleventy/#schritt-2%3A-layout-und-styling-erg%C3%A4nzen&quot; title=&quot;Schritt 2: Layout und Styling ergänzen&quot;&gt;Styling und Layout ergänzen&lt;/a&gt; kann (&lt;a href=&quot;https://github.com/dzenzes/11ty-start/tree/layout&quot; title=&quot;layout Branch mit Code Beispiel&quot;&gt;layout&lt;/a&gt; branch), und&lt;/li&gt;
&lt;li&gt;wie ein &lt;a href=&quot;https://zenzes.me/ein-einfacher-einstieg-in-eleventy/#schritt-3%3A-einen-blog-erstellen&quot;&gt;Blog und eine Blog-Übersicht&lt;/a&gt; eingefügt werden können (&lt;a href=&quot;https://github.com/dzenzes/11ty-start/tree/blog&quot; title=&quot;blog Branch mit Code Beispiel&quot;&gt;blog&lt;/a&gt; branch).&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;schritt-1%3A-eine-einzelne-seite&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://zenzes.me/ein-einfacher-einstieg-in-eleventy/#schritt-1%3A-eine-einzelne-seite&quot;&gt;Schritt 1: Eine einzelne Seite&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Um eine erste Seite zu erstellen, sind die folgenden Schritte notwendig:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;ein neues Verzeichnis erstellen und in dieses wechseln&lt;/li&gt;
&lt;li&gt;eine Markdown Datei anlegen und als &lt;code&gt;index.md&lt;/code&gt; in diesem Ordner speichern&lt;/li&gt;
&lt;li&gt;im Verzeichnis mithilfe von &lt;a href=&quot;https://www.npmjs.com/package/npx&quot; title=&quot;Dokumentation zu npx&quot;&gt;npx&lt;/a&gt; eleventy ausführen: &lt;code&gt;npx @11ty/eleventy&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Eleventy verarbeitet nun die Markdown Datei und legt eine Datei &lt;code&gt;index.html&lt;/code&gt; im Standardausgabeordner &lt;code&gt;_site&lt;/code&gt; ab. Mit &lt;code&gt;npx @11ty/eleventy --serve&lt;/code&gt; können wir die Seite auch direkt lokal starten und im Browser betrachten (die URL steht im Terminal und sollte normalerweise &lt;a href=&quot;http://http//localhost:8080&quot; title=&quot;Link zum aktuellen Entwicklungsstand&quot;&gt;localhost:8080&lt;/a&gt; sein).&lt;/p&gt;
&lt;p&gt;Wenn alles funktioniert, können wir noch ein richtiges npm Projekt daraus machen und Skripte für unsere Arbeit anlegen:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;im Verzeichnis &lt;code&gt;npm init -y&lt;/code&gt; ausführen&lt;/li&gt;
&lt;li&gt;Eleventy mit &lt;code&gt;npm install @11ty/eleventy&lt;/code&gt; installieren&lt;/li&gt;
&lt;li&gt;In der &lt;code&gt;package.json&lt;/code&gt; die Skripte durch eigene ersetzen&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class=&quot;language-json&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;token property&quot;&gt;&quot;scripts&quot;&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 property&quot;&gt;&quot;build&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;eleventy&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
	&lt;span class=&quot;token property&quot;&gt;&quot;start&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;eleventy --serve&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;/code&gt;&lt;/pre&gt;
&lt;p&gt;Das &lt;code&gt;start&lt;/code&gt; Skript funktioniert auch einwandfrei ohne das &lt;code&gt;build&lt;/code&gt; Skript. Wenn wir Änderungen vornehmen, wird die Seite neu erstellt und direkt korrekt ausgeliefert.&lt;/p&gt;
&lt;h2 id=&quot;schritt-2%3A-layout-und-styling-erg%C3%A4nzen&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://zenzes.me/ein-einfacher-einstieg-in-eleventy/#schritt-2%3A-layout-und-styling-erg%C3%A4nzen&quot;&gt;Schritt 2: Layout und Styling ergänzen&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Bevor wir eine komplexere Seite bauen, benötigen wir etwas Struktur. Hierfür passen wir die Ordnerstruktur unseres Projekts mithilfe der Eleventy Konfiguration an.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;wir legen eine neue Datei &lt;code&gt;.eleventy.js&lt;/code&gt; an&lt;/li&gt;
&lt;li&gt;dort ergänzen wir die folgende Konfiguration:&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;module&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function-variable function&quot;&gt;exports&lt;/span&gt; &lt;span class=&quot;token operator&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 parameter&quot;&gt;config&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;dir&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;input&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;src&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
			&lt;span class=&quot;token literal-property property&quot;&gt;includes&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;_includes&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
			&lt;span class=&quot;token literal-property property&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;_data&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
			&lt;span class=&quot;token literal-property property&quot;&gt;output&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;_site&#39;&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;ol start=&quot;3&quot;&gt;
&lt;li&gt;die &lt;code&gt;index.md&lt;/code&gt; verschieben wir nun noch in einen neuen Ordner &lt;code&gt;src&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Falls der Eleventy Server läuft (&lt;code&gt;start&lt;/code&gt; Skript) beenden wir diesen und starten ihn dann neu&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Die Konfiguration erlaubt uns später noch weitere Anpassungen vorzunehmen. Momentan interessiert uns aber nur der Rückgabewert, über den wir die wichtigsten Verzeichnisse definieren:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;input&lt;/code&gt; definiert das Verzeichnis, wo unser Code liegt&lt;/li&gt;
&lt;li&gt;&lt;code&gt;includes&lt;/code&gt; legt fest, wo wir bspw. Layputs anlegen können. Dabei wird immer ein Unterverzeichnis von &lt;code&gt;input&lt;/code&gt; genommen, hier also &lt;code&gt;src/includes&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;data&lt;/code&gt; definiert den Ordner, wo wir zusätzliche Datenquellen anlegen. Diesen ignorieren wir in diesem Tutorial.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;output&lt;/code&gt; definiert das Verzeichnis, wo unser Code landet. Hier also weiterhin unverändert &lt;code&gt;_site&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;ein-layout-definieren&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://zenzes.me/ein-einfacher-einstieg-in-eleventy/#ein-layout-definieren&quot;&gt;Ein Layout definieren&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Was jetzt noch fehlt, ist ein Layout. Unsere Seite sollte schon valides HTML enthalten und später werden wir beispielsweise eine Navigation haben, die auf jeder Seite sichtbar sein soll.&lt;/p&gt;
&lt;p&gt;Layouts können wir im &lt;code&gt;src/_includes&lt;/code&gt; Ordner anlegen. Hierzu erstellen wir dort eine neue Datei &lt;code&gt;layout.njk&lt;/code&gt; (Eleventy unterstützt sehr viele unterschiedliche Templatesprachen. Ich nutze meistens &lt;a href=&quot;https://mozilla.github.io/nunjucks/&quot; title=&quot;Nunjucks Dokumentation&quot;&gt;Nunjucks&lt;/a&gt;) mit folgendem Inhalt:&lt;/p&gt;
&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;
&lt;span class=&quot;token doctype&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;!&lt;/span&gt;&lt;span class=&quot;token doctype-tag&quot;&gt;doctype&lt;/span&gt; &lt;span class=&quot;token name&quot;&gt;html&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;html&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;lang&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;de&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
	&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;head&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
		&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;meta&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;charset&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;UTF-8&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;
		&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;meta&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;http-equiv&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;X-UA-Compatible&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;content&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;IE=edge&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;
		&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;meta&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;viewport&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;content&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;width=device-width, initial-scale=1.0&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;
		&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;title&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;{{ title }}&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;title&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
	&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;head&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
	&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;body&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
		{{ content | safe }}
	&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;body&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;html&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In den geschweiften Klammern liegen Informationen, die zur Build Zeit dort eingefügt werden. Mit &lt;code&gt;{{content}}&lt;/code&gt; wird hier später der eigentliche Inhalt der Seite eingefügt.&lt;/p&gt;
&lt;p&gt;Nun müssen wir unser Layout nur noch mit unserer &lt;code&gt;index.md&lt;/code&gt; verknüpfen und den &lt;code&gt;title&lt;/code&gt; festlegen. Beides können wir in der &lt;code&gt;index.md&lt;/code&gt; über &lt;a href=&quot;https://www.11ty.dev/docs/data-frontmatter/&quot; title=&quot;FrontMatter Dokumentation&quot;&gt;FrontMatter&lt;/a&gt; erreichen:&lt;/p&gt;
&lt;pre class=&quot;language-md&quot;&gt;&lt;code class=&quot;language-md&quot;&gt;&lt;span class=&quot;token front-matter-block&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;---&lt;/span&gt;
&lt;span class=&quot;token front-matter yaml language-yaml&quot;&gt;layout: layout.njk
title: Unsere erste 11ty Seite&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;---&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;css-einbinden&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://zenzes.me/ein-einfacher-einstieg-in-eleventy/#css-einbinden&quot;&gt;CSS einbinden&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Nun fehlt nur noch eine CSS Datei, um das Ganze etwas hübscher aussehen zu lassen:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;wir erstellen eine Datei &lt;code&gt;src/style.css&lt;/code&gt; und ergänzen in dieser etwas CSS&lt;/li&gt;
&lt;li&gt;wir fügen &lt;code&gt;&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; href=&amp;quot;/style.css&amp;quot;/&amp;gt;&lt;/code&gt;im &lt;code&gt;head&lt;/code&gt; unseres Layouts (&lt;code&gt;/src/_includes/layout.njk&lt;/code&gt;) ein&lt;/li&gt;
&lt;li&gt;in der Eleventy Konfiguration legen wir fest, dass unsere CSS Datei einfach ins Zielverzeichnis kopiert werden soll&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;module&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function-variable function&quot;&gt;exports&lt;/span&gt; &lt;span class=&quot;token operator&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 parameter&quot;&gt;config&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;
	config&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addPassthroughCopy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;src/*.css&#39;&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;passthroughFileCopy&lt;/span&gt;&lt;span class=&quot;token operator&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 literal-property property&quot;&gt;dir&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;input&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;src&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
			&lt;span class=&quot;token literal-property property&quot;&gt;includes&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;_includes&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
			&lt;span class=&quot;token literal-property property&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;_data&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
			&lt;span class=&quot;token literal-property property&quot;&gt;output&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;_site&#39;&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;h2 id=&quot;schritt-3%3A-einen-blog-erstellen&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://zenzes.me/ein-einfacher-einstieg-in-eleventy/#schritt-3%3A-einen-blog-erstellen&quot;&gt;Schritt 3: Einen Blog erstellen&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Die meisten Dinge, die wir für einen Blog brauchen, haben wir schon in den beiden vorherigen Abschnitten angewendet. Daher ist die Erstellung eines neuen Blog Beitrags auch recht einfach:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;wir legen zunächst ein neues Verzeichnis src/blog an&lt;/li&gt;
&lt;li&gt;in diesem Verzeichnis legen wir für jeden Beitrag eine Markdown Datei an. Zum Beispiel &lt;a href=&quot;http://my-first-post.md/&quot;&gt;my-first-post.md&lt;/a&gt; und füllen sie mit Front Matter für Titel und Layout und unserem Beitrag&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class=&quot;language-md&quot;&gt;&lt;code class=&quot;language-md&quot;&gt;&lt;span class=&quot;token front-matter-block&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;---&lt;/span&gt;
&lt;span class=&quot;token front-matter yaml language-yaml&quot;&gt;layout: layout.njk
title: Mein erster Blogbeitrag&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;---&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;token title important&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;#&lt;/span&gt; Herzlich Willkommen&lt;/span&gt;

Dies ist mein neuer Blog&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Abrufbar ist dieser Beitrag jetzt unter &lt;a href=&quot;http://localhost:8080/blog/my-first-post&quot;&gt;http://localhost:8080/blog/my-first-post&lt;/a&gt;. Jetzt könnten wir den Link manuell an beliebiger Stelle pflegen, was mit der Zeit aber aufwendig wird. Eleventy erlaubt uns, dies zu automatisieren. Hierfür erstellen wir eine &lt;a href=&quot;https://www.11ty.dev/docs/collections/&quot;&gt;collection&lt;/a&gt; mit unseren Blog-Beiträgen:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;in der Front Matter des Blog-Beitrags ergänzen wir einen tag &lt;code&gt;blog&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class=&quot;language-md&quot;&gt;&lt;code class=&quot;language-md&quot;&gt;&lt;span class=&quot;token front-matter-block&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;---&lt;/span&gt;
&lt;span class=&quot;token front-matter yaml language-yaml&quot;&gt;layout: layout.njk
title: Mein erster Blogbeitrag
tags: blog&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;---&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;ol start=&quot;2&quot;&gt;
&lt;li&gt;die Datei &lt;code&gt;index.md&lt;/code&gt; benennen wir um in &lt;code&gt;index.njk&lt;/code&gt; um hier mit Nunjucks arbeiten zu können&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;---
layout: layout.njk
title: Unsere erste 11ty Seite
---

&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;h1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Dies ist meine erste 11ty Seite&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;h1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;ol start=&quot;3&quot;&gt;
&lt;li&gt;in der &lt;code&gt;index.njk&lt;/code&gt; nutzen wir unsere neue Collection, um eine Liste der Blog Beiträge anzeigen zu können&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;ul&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
	{% for post in collections.blog %}
	&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;li&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;a&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;href&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;{{ post.url }}&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;{{ post.data.title }}&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;a&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;li&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
	{% endfor %}
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;ul&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Wenn wir jetzt weitere Blog Beiträge mit dem passenden Tag erstellen, werden diese automatisch aufgelistet.&lt;/p&gt;
&lt;h3 id=&quot;einfachere-navigation&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://zenzes.me/ein-einfacher-einstieg-in-eleventy/#einfachere-navigation&quot;&gt;Einfachere Navigation&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Was jetzt nur noch fehlt, ist eine Navigation, damit wir wieder auf unsere Startseite kommen. Hierzu können wir im Layout (&lt;code&gt;src/_includes/layout.njk&lt;/code&gt;) diese über unserem Content einfügen:&lt;/p&gt;
&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;nav&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
	&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;a&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;href&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;/&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Start&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;a&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;nav&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Und das war es auch schon. Die nächsten Schritte wären wahrscheinlich weitere Seiten und eine etwas schönere Navigation. Was würde Euch an der Arbeit mit Eleventy noch interessieren? Schreibt mir gerne auf &lt;a href=&quot;https://chaos.social/@danielzenzes&quot;&gt;Mastodon&lt;/a&gt;.&lt;/p&gt;
</description>
        <pubDate>Fri, 17 Jun 2022 15:00:00 +0200</pubDate>
        <dc:creator>Daniel Zenzes</dc:creator>
        <guid>https://zenzes.me/ein-einfacher-einstieg-in-eleventy/</guid>
      </item>
      <item>
        <title>Frontend 1x1 for Backend Devs</title>
        <link>https://zenzes.me/en/frontend-1x1-for-backend-devs/</link>
        <description>&lt;p&gt;For developers, who are not working on the frontend, but would like to get at least an overview there.&lt;/p&gt;
&lt;p&gt;In this article I will provide a first insight into a typical frontend project and thereby help you to orientate yourself there a little bit. Even if you see your focus in other areas of the application, you can&#39;t avoid the frontend from time to time. Fortunately, there are a few standards that you can use as a guide.&lt;/p&gt;
&lt;p&gt;So we take a view how to set up an existing frontend application locally and then start, test or build it. In all steps there is the risk that it was of course solved a little differently in the respective project. In many cases this can be discussed, but we assume that the developers have their reasons. So if your project differs from what I write here, you&#39;ll have to ask your colleagues.&lt;/p&gt;
&lt;h2 id=&quot;starting-point%3A-package.json&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://zenzes.me/en/frontend-1x1-for-backend-devs/#starting-point%3A-package.json&quot;&gt;Starting point: package.json&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Build and dependencies in most projects are configured using the &lt;a href=&quot;https://docs.npmjs.com/cli/v7/configuring-npm/package-json&quot;&gt;&lt;code&gt;package.json&lt;/code&gt;&lt;/a&gt;, which should be in the root of the (frontend) project. It contains some meta information about the project like a name, sometimes a version, necessary dependencies and scripts to build, start and maybe test the project. Often it also contains the configuration for used tooling, but this can also be in a separate file.&lt;/p&gt;
&lt;p&gt;A good start is to install all dependencies first and that&#39;s where things can get exciting.&lt;/p&gt;
&lt;h2 id=&quot;the-correct-node-version&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://zenzes.me/en/frontend-1x1-for-backend-devs/#the-correct-node-version&quot;&gt;The correct node version&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Basically you should ensure that you have the correct &lt;a href=&quot;https://nodejs.org/en/&quot;&gt;node&lt;/a&gt; version installed. Usually this version is defined in the project, e.g. in the documentation, a readme, the &lt;code&gt;package.json&lt;/code&gt; or an own configuration file (&lt;code&gt;.nvmrc&lt;/code&gt;). I have been managing my node versions with &lt;a href=&quot;https://github.com/nvm-sh/nvm&quot;&gt;nvm&lt;/a&gt; for several years now and I am very satisfied with it. If there is a &lt;code&gt;.nvmrc&lt;/code&gt; in the project, you can use &lt;code&gt;nvm use&lt;/code&gt; to select and install the correct Node version. Otherwise I would use the current LTS version. The nvm documentation is excellent and describes all necessary steps.&lt;/p&gt;
&lt;p&gt;For most frontend projects, the use of the correct node version is not mandatory &amp;quot;just to start or test everything&amp;quot;, you should just not commit any changes to the code afterwards, which could arise, for example, during the installation of the dependencies. The same applies to the next step: the Package Manager.&lt;/p&gt;
&lt;h2 id=&quot;the-correct-package-manager&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://zenzes.me/en/frontend-1x1-for-backend-devs/#the-correct-package-manager&quot;&gt;The correct package manager&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;As with the Node version, there are many different opinions and in this article I don&#39;t want to go too deep into the topic of package managers. Node comes with &lt;a href=&quot;https://www.npmjs.com/&quot;&gt;npm&lt;/a&gt; (for me the main reason to use the right Node version) and in many projects this is enough to &amp;quot;just start everything&amp;quot;. As with the node version, it should be documented which tool is used in the project. Mostly this is either npm or &lt;a href=&quot;https://yarnpkg.com/&quot;&gt;yarn&lt;/a&gt;, but there are also many other tools here.&lt;/p&gt;
&lt;p&gt;If the project has a &lt;code&gt;package-lock.json&lt;/code&gt; next to the &lt;code&gt;package.json&lt;/code&gt;, this speaks for the use of npm. If there is a yarn.lock there instead, yarn is probably used. Of course there are also projects that contain both files or neither. In both cases I would question this critically, but this can also be an issue in the project.&lt;/p&gt;
&lt;p&gt;The fallback solution of my choice now would be the &amp;quot;standard&amp;quot; npm again though I would also watch what happens in the repository. I would also undo all changes and delete the node_modules folder again when I&#39;m done.&lt;/p&gt;
&lt;h2 id=&quot;install-dependencies&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://zenzes.me/en/frontend-1x1-for-backend-devs/#install-dependencies&quot;&gt;Install dependencies&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Dependencies can be installed using npm via &lt;code&gt;npm install&lt;/code&gt; or yarn via &lt;code&gt;yarn&lt;/code&gt;. Both should be executed in the folder where the &lt;code&gt;package.json&lt;/code&gt; is located. After that a &lt;code&gt;node_modules&lt;/code&gt; folder should be created in the same folder, that ( hopefully ) is also in the &lt;code&gt;.gitignore&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;At this point you may get an error if the used dependencies are in a separate repository and npm has to be configured. This should also be part of a normal project documentation and mostly just means that you have to create another &lt;code&gt;.npmrc&lt;/code&gt; in one of the parent directories of the frontend project.&lt;/p&gt;
&lt;p&gt;Now you can start, build and test the project by executing the appropriate scripts.&lt;/p&gt;
&lt;h2 id=&quot;start%2C-test-and-build-projects&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://zenzes.me/en/frontend-1x1-for-backend-devs/#start%2C-test-and-build-projects&quot;&gt;Start, test and build projects&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;This brings us back to the &lt;code&gt;package.json&lt;/code&gt; in which there should be a block &lt;code&gt;scripts&lt;/code&gt;. These key-value pairs describe the scripts that are supported in the project (this is the respective key) and what they do (the respective value). Even if I use npm in examples now, you can also use the package manager in use analogously:&lt;/p&gt;
&lt;p&gt;To start one of the scripts now, run &lt;code&gt;npm run &amp;lt;key&amp;gt;&lt;/code&gt; in the terminal. Let&#39;s assume our &lt;code&gt;package.json&lt;/code&gt; contains only one script to run tests and uses &lt;em&gt;jest&lt;/em&gt; for this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;quot;scripts&amp;quot;: {
   &amp;quot;test&amp;quot;: &amp;quot;jest&amp;quot;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Using &lt;code&gt;npm run test&lt;/code&gt; I can execute this script. The tools installed in the project (which we already have done) are attached to the &lt;code&gt;PATH&lt;/code&gt; by npm and so can be easily used within scripts.&lt;/p&gt;
&lt;p&gt;I would expect scripts to start and build the project here now. In most projects that I&#39;ve seen, the names are quite speaking, otherwise a look at the documentation or the coffee with your colleges is also recommended here.&lt;/p&gt;
&lt;p&gt;I hope this little guide helps you with your work. What else would you be interested in? Where do you hang out when working with frontend colleagues? Feel free to write me on &lt;a href=&quot;https://chaos.social/@danielzenzes&quot;&gt;Mastodon&lt;/a&gt;.&lt;/p&gt;
</description>
        <pubDate>Tue, 07 Jun 2022 15:00:00 +0200</pubDate>
        <dc:creator>Daniel Zenzes</dc:creator>
        <guid>https://zenzes.me/en/frontend-1x1-for-backend-devs/</guid>
      </item>
      <item>
        <title>Frontend 1x1 für Backend Devs</title>
        <link>https://zenzes.me/frontend-1x1-fur-backend-devs/</link>
        <description>&lt;p&gt;Für Entwickler:Innen, die nicht im Frontend aktiv sind, sich aber zumindest einen Überblick dort verschaffen wollen.&lt;/p&gt;
&lt;p&gt;In diesem Artikel möchte ich einen ersten Überblick über ein typisches Frontend-Projekt geben und dabei helfen, sich dort etwas zu orientieren. Auch wenn man seinen Schwerpunkt in anderen Bereichen der Anwendung sieht, kommt man hin und wieder nicht am Frontend vorbei. Glücklicherweise gibt es hier ein paar Standards, an denen man sich orientieren kann.&lt;/p&gt;
&lt;p&gt;Wir sehen uns also an wie man eine bestehende Frontend-Anwendung lokal einrichtet und dann auch starten, testen oder bauen kann. Bei allen Schritten besteht die Gefahr, dass es natürlich gerade im jeweiligen Projekt etwas anders gelöst wurde. In vielen Fällen kann man das sicher diskutieren, aber wir gehen mal davon aus, dass die Entwickler sich dabei was gedacht haben. Sollte Euer Projekt also davon abweichen, was ich hier schreibe, müsst ihr wohl mal bei den Kolleg:Innen nachfragen.&lt;/p&gt;
&lt;h2 id=&quot;startpunkt%3A-package.json&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://zenzes.me/frontend-1x1-fur-backend-devs/#startpunkt%3A-package.json&quot;&gt;Startpunkt: package.json&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Build und Dependencies werden in den meisten Projekten über die &lt;a href=&quot;https://docs.npmjs.com/cli/v7/configuring-npm/package-json&quot;&gt;&lt;code&gt;package.json&lt;/code&gt;&lt;/a&gt; konfiguriert, die im Root des (Frontend-) Projekts liegen sollte. Diese enthält einige Meta-Informationen zum Projekt wie einen Namen, manchmal eine Version, benötigte Dependencies und Skripte, mit denen man das Projekt bauen, starten und vielleicht auch testen kann. Oft enthält sie auch die Konfiguration für verwendetes Tooling, dies kann aber auch in einer eigenen Datei liegen.&lt;/p&gt;
&lt;p&gt;Ein guter Start ist hier zunächst alle Abhängigkeiten zu installieren und da kann es auch direkt spannender werden.&lt;/p&gt;
&lt;h2 id=&quot;die-richtige-node-version&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://zenzes.me/frontend-1x1-fur-backend-devs/#die-richtige-node-version&quot;&gt;Die richtige Node Version&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Grundsätzlich sollte man nun sicherstellen, dass man die richtige &lt;a href=&quot;https://nodejs.org/en/&quot;&gt;Node&lt;/a&gt; Version installiert hat. Normalerweise ist diese Version im Projekt definiert, etwa in einer Dokumentation, einer Readme, der &lt;code&gt;package.json&lt;/code&gt; oder einer eigenen Konfigurationsdatei (&lt;code&gt;.nvmrc&lt;/code&gt;). Ich verwalte meine Node-Versionen schon seit mehreren Jahren mit &lt;a href=&quot;https://github.com/nvm-sh/nvm&quot;&gt;nvm&lt;/a&gt; und bin damit auch sehr zufrieden. Sollte im Projekt eine &lt;code&gt;.nvmrc&lt;/code&gt; liegen, kann mit &lt;code&gt;nvm use&lt;/code&gt; die richtige Node Version ausgewählt und installiert werden. Ansonsten würde ich die aktuelle LTS Version nutzen. Die nvm Dokumentation ist hervorragend und beschreibt alle hierfür notwendigen Schritte.&lt;/p&gt;
&lt;p&gt;Bei den meisten Frontend-Projekten ist die Nutzung der richtigen Node-Version nicht zwingend erforderlich „um nur mal alles zu starten oder testen“, man sollte eben danach keine Änderungen am Code committen, die beispielsweise bei der Installation der Dependencies aufkommen könnten. Das Gleiche gilt auch für den nächsten Schritt: dem Package Manager.&lt;/p&gt;
&lt;h2 id=&quot;der-richtige-package-manager&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://zenzes.me/frontend-1x1-fur-backend-devs/#der-richtige-package-manager&quot;&gt;Der richtige Package Manager&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Wie schon bei der Node Version scheiden sich hier die Geister und in diesem Artikel möchte ich auch nicht zu tief auf das Thema Package Manager eingehen. Mit Node wird &lt;a href=&quot;https://www.npmjs.com/&quot;&gt;npm&lt;/a&gt; ausgeliefert (für mich der Hauptgrund die richtige Node Version zu nutzen) und in vielen Projekten reicht das auch um „nur mal alles zu starten“. Wie auch bei der Node Version sollte dokumentiert sein, welches Tool im Projekt eingesetzt wird. Meistens ist dies entweder npm oder &lt;a href=&quot;https://yarnpkg.com/&quot;&gt;yarn&lt;/a&gt;, es gibt aber auch viele andere Tools hier.&lt;/p&gt;
&lt;p&gt;Wenn das Projekt neben der &lt;code&gt;package.json&lt;/code&gt; eine &lt;code&gt;package-lock.json&lt;/code&gt; hat, spricht dies für die Nutzung von npm. Sollte stattdessen eine yarn.lock dort liegen, wird wohl yarn eingesetzt. Natürlich gibt es auch Projekte, die beide Dateien beinhalten oder keine von beiden. In beiden Fällen würde ich das kritisch hinterfragen, das kann aber auch ein Wespennest im Projekt sein.&lt;/p&gt;
&lt;p&gt;Die Fallback-Lösung meiner Wahl wäre jetzt wieder der „Standard“ npm wobei ich auch hier aufpassen würde, was im Repository passiert. Ich würde auch hier, wenn ich fertig bin, alle Änderungen rückgängig machen und den node_modules Ordner wieder löschen.&lt;/p&gt;
&lt;h2 id=&quot;dependencies-installieren&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://zenzes.me/frontend-1x1-fur-backend-devs/#dependencies-installieren&quot;&gt;Dependencies installieren&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Dependencies lassen sich mit npm über &lt;code&gt;npm install&lt;/code&gt; und mit yarn über &lt;code&gt;yarn&lt;/code&gt; installieren. Beides sollte im Ordner ausgeführt werden, in dem die &lt;code&gt;package.json&lt;/code&gt; liegt. Danach sollte im gleichen Ordner ein &lt;code&gt;node_modules&lt;/code&gt; Ordner angelegt werden, der (hoffentlich) auch in der &lt;code&gt;.gitignore&lt;/code&gt; steht.&lt;/p&gt;
&lt;p&gt;An dieser Stelle kann es zu einem Fehler kommen, wenn die verwendeten Dependencies in einem eigenen Repository liegen und npm konfiguriert werden muss. Dies sollte auch in einer normalen Projektdokumentation zu finden sein und bedeutet meistens nur, dass man in einem der Elternverzeichnisse des Frontend-Projekts noch eine &lt;code&gt;.npmrc&lt;/code&gt; anlegen muss.&lt;/p&gt;
&lt;p&gt;Nun kann man das Projekt starten, bauen und testen, indem man die passenden Skripte ausführt.&lt;/p&gt;
&lt;h2 id=&quot;projekte-starten%2C-testen-und-bauen&quot; tabindex=&quot;-1&quot;&gt;&lt;a class=&quot;header-anchor&quot; href=&quot;https://zenzes.me/frontend-1x1-fur-backend-devs/#projekte-starten%2C-testen-und-bauen&quot;&gt;Projekte starten, testen und bauen&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Wir kommen zurück zur &lt;code&gt;package.json&lt;/code&gt; in der es einen Block &lt;code&gt;scripts&lt;/code&gt; geben sollte. Diese key-value-Paare beschreiben die Skripte, die im Projekt unterstützt werden (das ist der jeweilige key) und was diese tun (das jeweilige value). Auch wenn ich jetzt in Beispielen npm nehme, kann man hier auch den jeweils in Verwendung befindlichen Package Manager analog nutzen:&lt;/p&gt;
&lt;p&gt;Um jetzt eines der Skripte zu starten, führt man im Terminal &lt;code&gt;npm run &amp;lt;key&amp;gt;&lt;/code&gt; aus. Nehmen wir an unsere &lt;code&gt;package.json&lt;/code&gt; enthält nur ein Skript, um Tests auszuführen und nutzt hierfür &lt;em&gt;jest&lt;/em&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;quot;scripts&amp;quot;: {
   &amp;quot;test&amp;quot;: &amp;quot;jest&amp;quot;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Mit einem &lt;code&gt;npm run test&lt;/code&gt; kann ich dann dieses Skript ausführen. Die im Projekt installierten Tools (die wir schon installiert haben) werden durch npm an den &lt;code&gt;PATH&lt;/code&gt; angehangen und können so einfach gestartet werden.&lt;/p&gt;
&lt;p&gt;Ich würde hier jetzt Skripte erwarten, die das Projekt starten und bauen können. Bei den meisten Projekten, die ich kenne, sind die Namen, da recht sprechend, ansonsten empfiehlt sich auch hier ein Blick auf die Dokumentation oder der Kaffee mit den Kolleg:Innen.&lt;/p&gt;
&lt;p&gt;Ich hoffe, dieser kleine Guide hilft Euch bei Eurer Arbeit. Was würde Euch noch interessieren? Wo hängt ihr bei der Arbeit mit den Frontend-Kolleg:Innen? Schreibt mir gerne auf &lt;a href=&quot;https://chaos.social/@danielzenzes&quot;&gt;Mastodon&lt;/a&gt;.&lt;/p&gt;
</description>
        <pubDate>Tue, 07 Jun 2022 15:00:00 +0200</pubDate>
        <dc:creator>Daniel Zenzes</dc:creator>
        <guid>https://zenzes.me/frontend-1x1-fur-backend-devs/</guid>
      </item>
  </channel>
</rss>