<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Vadim Vinogradov</title>
    <description>The latest articles on DEV Community by Vadim Vinogradov (@vadim).</description>
    <link>https://dev.to/vadim</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F134437%2F29cde6d6-8cfe-47e0-bd5e-007528047c27.jpeg</url>
      <title>DEV Community: Vadim Vinogradov</title>
      <link>https://dev.to/vadim</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/vadim"/>
    <language>en</language>
    <item>
      <title>Old Angular project with Claude Code</title>
      <dc:creator>Vadim Vinogradov</dc:creator>
      <pubDate>Fri, 13 Mar 2026 17:24:02 +0000</pubDate>
      <link>https://dev.to/vadim/old-angular-project-with-claude-code-2apk</link>
      <guid>https://dev.to/vadim/old-angular-project-with-claude-code-2apk</guid>
      <description>&lt;p&gt;This is a common friction point with Angular projects: &lt;em&gt;Claude Code&lt;/em&gt; will run &lt;strong&gt;Jest&lt;/strong&gt; instead of &lt;strong&gt;Karma&lt;/strong&gt; even if you have &lt;code&gt;karma.conf.js&lt;/code&gt;. Why? Because most of the training data and community content from recent years skews heavily toward &lt;strong&gt;Jest&lt;/strong&gt; (or Vitest) as the replacement.&lt;/p&gt;

&lt;p&gt;So &lt;em&gt;Claude Code's&lt;/em&gt; "prior" is that a modern JS/TS project uses &lt;em&gt;Jest&lt;/em&gt;. Outside Angular &amp;lt;17, virtually nobody uses &lt;strong&gt;Karma&lt;/strong&gt; anymore. &lt;em&gt;Claude Code&lt;/em&gt; doesn't have deep framework-specific heuristics — it pattern-matches across all JS/TS projects, and Jest dominates that distribution overwhelmingly.&lt;/p&gt;

&lt;p&gt;What we can do to steer it: in your &lt;code&gt;project/CLAUDE.md&lt;/code&gt; file, write something like:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;This project uses Karma + Jasmine for unit tests. Run tests with ng test or npx karma start. Do not use Jest.&lt;/code&gt;&lt;/p&gt;

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

</description>
      <category>angular</category>
      <category>testing</category>
      <category>frontend</category>
      <category>dotnet</category>
    </item>
    <item>
      <title>Stop Running Prettier Through ESLint — Here's Why Standalone Is Better</title>
      <dc:creator>Vadim Vinogradov</dc:creator>
      <pubDate>Mon, 02 Mar 2026 11:48:12 +0000</pubDate>
      <link>https://dev.to/vadim/stop-running-prettier-through-eslint-heres-why-standalone-is-better-78a</link>
      <guid>https://dev.to/vadim/stop-running-prettier-through-eslint-heres-why-standalone-is-better-78a</guid>
      <description>&lt;p&gt;If you've set up a JavaScript project in the last few years, there's a good chance you're running Prettier through &lt;code&gt;eslint-plugin-prettier&lt;/code&gt;. It was the go-to approach for a while — one tool, one command, one unified set of squiggly red lines in your editor. Simple, right?&lt;/p&gt;

&lt;p&gt;Here's the thing: the Prettier team themselves recommend against it. And once you understand why, you'll probably want to change your setup too.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prettier Formats Way More Than JavaScript
&lt;/h2&gt;

&lt;p&gt;ESLint is a JavaScript (and TypeScript) tool. That's its world. When you run Prettier as an ESLint plugin, Prettier is confined to that world — it only gets invoked on files that ESLint processes.&lt;/p&gt;

&lt;p&gt;But Prettier natively supports a much broader set of languages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CSS, Less, and SCSS&lt;/li&gt;
&lt;li&gt;HTML&lt;/li&gt;
&lt;li&gt;JSON&lt;/li&gt;
&lt;li&gt;YAML&lt;/li&gt;
&lt;li&gt;Markdown (including MDX)&lt;/li&gt;
&lt;li&gt;GraphQL&lt;/li&gt;
&lt;li&gt;Vue and Angular templates&lt;/li&gt;
&lt;li&gt;Handlebars&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That &lt;code&gt;package.json&lt;/code&gt; with inconsistent indentation? The &lt;code&gt;.yaml&lt;/code&gt; config where someone mixed tabs and spaces? The CSS file with wildly different formatting conventions? ESLint never touches those. If Prettier only runs as an ESLint plugin, those files stay messy.&lt;/p&gt;

&lt;p&gt;When you run Prettier standalone — via CLI, editor integration, or a pre-commit hook — a single &lt;code&gt;prettier --check .&lt;/code&gt; or &lt;code&gt;prettier --write .&lt;/code&gt; will catch formatting inconsistencies across &lt;em&gt;all&lt;/em&gt; of these file types in your project, not just the ones ESLint knows about.&lt;/p&gt;

&lt;p&gt;This is especially impactful in real-world projects. Think about how many non-JS files live in a typical repository: CI configs in YAML, style sheets, JSON data fixtures, Markdown documentation. Formatting consistency across all of them matters, and standalone Prettier gives you that for free.&lt;/p&gt;

&lt;h2&gt;
  
  
  It's Faster
&lt;/h2&gt;

&lt;p&gt;This isn't just anecdotal — it's documented by the Prettier team on their &lt;a href="https://prettier.io/docs/integrating-with-linters" rel="noopener noreferrer"&gt;official integration guide&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;[Prettier plugins run inside linters] are slower than running Prettier directly.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now, to be clear — both approaches parse your JS/TS files twice. Whether Prettier runs as a plugin or standalone, ESLint parses the file and Prettier parses the file. That part is the same.&lt;/p&gt;

&lt;p&gt;The performance difference comes from the &lt;strong&gt;integration overhead&lt;/strong&gt;. When Prettier runs as an ESLint plugin, there's an entire middle layer doing extra work for every file: it runs Prettier, diffs the formatted output against the original, then converts every formatting difference into an ESLint diagnostic object complete with line numbers, column offsets, and fix ranges. ESLint then processes all of those diagnostics through its reporting and auto-fix pipeline. That's a lot of machinery just to change a semicolon.&lt;/p&gt;

&lt;p&gt;Standalone Prettier skips all of that. It parses, formats, writes. No diffing, no diagnostic generation, no round-tripping through a linter's fix system. On a large codebase or in CI, that overhead adds up.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Red Squiggly Problem
&lt;/h2&gt;

&lt;p&gt;There's a subtler UX argument the Prettier docs also make: when Prettier runs as a linter rule, every formatting issue shows up as a lint error. Your editor fills with red and yellow underlines for things like trailing commas and bracket spacing — things that Prettier will auto-fix on save anyway.&lt;/p&gt;

&lt;p&gt;The whole point of Prettier is to &lt;em&gt;stop thinking about formatting&lt;/em&gt;. You write code however you want, hit save, and it snaps into place. Treating formatting deviations as lint errors defeats that purpose. It adds cognitive noise instead of removing it.&lt;/p&gt;

&lt;p&gt;With standalone Prettier, formatting happens silently via your editor's format-on-save or a pre-commit hook. The only time you hear from Prettier is when you explicitly run &lt;code&gt;--check&lt;/code&gt; in CI — and that's just a pass/fail gate, not a wall of warnings in your editor.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Recommended Setup
&lt;/h2&gt;

&lt;p&gt;The Prettier docs lay out a clean separation of concerns:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prettier&lt;/strong&gt; handles formatting: indentation, line length, semicolons, quotes, trailing commas — the stuff that doesn't affect how your code runs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ESLint&lt;/strong&gt; handles code quality: unused variables, unreachable code, implicit globals, potential bugs — the stuff that &lt;em&gt;does&lt;/em&gt; matter for correctness.&lt;/p&gt;

&lt;p&gt;To prevent them from fighting, install &lt;a href="https://github.com/prettier/eslint-config-prettier" rel="noopener noreferrer"&gt;eslint-config-prettier&lt;/a&gt;. It disables all ESLint rules that would conflict with Prettier, so the two tools stay in their lanes.&lt;/p&gt;

&lt;p&gt;A typical setup looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Install both&lt;/span&gt;
npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--save-dev&lt;/span&gt; prettier eslint eslint-config-prettier
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add &lt;code&gt;prettier&lt;/code&gt; to the end of your ESLint config's &lt;code&gt;extends&lt;/code&gt; array (Flat Config shown):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;eslintConfigPrettier&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;eslint-config-prettier&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="c1"&gt;// ...your other configs&lt;/span&gt;
  &lt;span class="nx"&gt;eslintConfigPrettier&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then create your &lt;code&gt;.prettierrc&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"semi"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"singleQuote"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"trailingComma"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"all"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"printWidth"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now run them separately:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Check formatting across your ENTIRE project&lt;/span&gt;
npx prettier &lt;span class="nt"&gt;--check&lt;/span&gt; &lt;span class="nb"&gt;.&lt;/span&gt;

&lt;span class="c"&gt;# Auto-fix formatting&lt;/span&gt;
npx prettier &lt;span class="nt"&gt;--write&lt;/span&gt; &lt;span class="nb"&gt;.&lt;/span&gt;

&lt;span class="c"&gt;# Lint for code quality&lt;/span&gt;
npx eslint &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or better yet, add both to your CI pipeline and a pre-commit hook (with &lt;a href="https://github.com/lint-staged/lint-staged" rel="noopener noreferrer"&gt;lint-staged&lt;/a&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"lint-staged"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"*"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"prettier --write --ignore-unknown"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"*.{js,ts,jsx,tsx}"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"eslint --fix"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice the &lt;code&gt;*&lt;/code&gt; glob for Prettier — it runs on &lt;em&gt;everything&lt;/em&gt;, while ESLint is scoped to JS/TS files. That's the whole point.&lt;/p&gt;

&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Prettier via ESLint Plugin&lt;/th&gt;
&lt;th&gt;Prettier Standalone&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;File coverage&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Only JS/TS (whatever ESLint processes)&lt;/td&gt;
&lt;td&gt;CSS, JSON, YAML, Markdown, HTML, GraphQL, and more&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Speed&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Slower (double parsing)&lt;/td&gt;
&lt;td&gt;Faster (direct formatting)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Editor noise&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Red squiggly lines for formatting&lt;/td&gt;
&lt;td&gt;Silent format-on-save&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Recommended by Prettier&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;If you're still running &lt;code&gt;eslint-plugin-prettier&lt;/code&gt;, consider pulling Prettier out and letting it run on its own. You'll get broader coverage, faster runs, and a quieter editor. And you'll be following the approach the Prettier team actually recommends.&lt;/p&gt;

</description>
      <category>frontend</category>
      <category>vite</category>
      <category>javascript</category>
      <category>typescript</category>
    </item>
    <item>
      <title>WebStorm vs VSCode</title>
      <dc:creator>Vadim Vinogradov</dc:creator>
      <pubDate>Tue, 23 Sep 2025 20:19:01 +0000</pubDate>
      <link>https://dev.to/vadim/webstorm-vs-vscode-57da</link>
      <guid>https://dev.to/vadim/webstorm-vs-vscode-57da</guid>
      <description>&lt;p&gt;As a long-time WebStorm user trying to migrate to VSCode (mainly because VSCode seems to integrate better with modern AI tools and extensions), I quickly noticed some differences—especially around Git conflict resolution. While VSCode is powerful and extremely customizable, there are still areas where WebStorm offers a smoother, more feature-rich experience out of the box.&lt;/p&gt;

&lt;h2&gt;
  
  
  Merging Git Conflicts
&lt;/h2&gt;

&lt;p&gt;In WebStorm, conflict resolution feels more granular. You can manage each line individually:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhdvhuranpb0nbly3is5c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhdvhuranpb0nbly3is5c.png" alt=" " width="800" height="372"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In VSCode, the built-in merge editor works differently. It highlights conflict sections and provides options like “Accept Current,” “Accept Incoming,” “Accept Both,” or “Compare Changes.” However, it applies the choice to the whole conflict block, not line by line. This is faster for simple cases, but less precise if you want fine-grained control:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7vp2yk7hge9inow7b4fd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7vp2yk7hge9inow7b4fd.png" alt=" " width="800" height="361"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Viewing Which Files Had Conflicts
&lt;/h2&gt;

&lt;p&gt;After resolving a merge, it’s often useful to double-check which files originally had conflicts—especially when reviewing your work or collaborating on complex merges.&lt;/p&gt;

&lt;p&gt;In WebStorm, this is straightforward. The Git log not only shows merge commits but also clearly highlights which files had conflicts during that merge:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fadpsme43z00hblxii4xd.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fadpsme43z00hblxii4xd.jpg" alt=" " width="800" height="224"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In VSCode, you can see the list of files changed in a merge commit, but not specifically which ones had conflicts. Even with GitLens, the UI focuses on “modified vs added vs deleted” files. Conflict status isn’t preserved in the UI, so you lose that bit of insight after the merge is completed:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fajsbe5u7vamhckyrjmxx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fajsbe5u7vamhckyrjmxx.png" alt=" " width="800" height="646"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  CSS
&lt;/h2&gt;

&lt;p&gt;Right now, there is no VS Code extension that lets you click on a CSS selector and directly see all its Angular usages (like WebStorm does). Closest you get is CSS Peek + manual search. (Update: CSS Navigation extension can do CSS -&amp;gt; HTML find references).&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>vscode</category>
      <category>frontend</category>
      <category>webstorm</category>
    </item>
    <item>
      <title>Frontend Monitoring and Error Tracking</title>
      <dc:creator>Vadim Vinogradov</dc:creator>
      <pubDate>Mon, 12 Feb 2024 16:33:10 +0000</pubDate>
      <link>https://dev.to/vadim/frontend-monitoring-and-error-tracking-8mb</link>
      <guid>https://dev.to/vadim/frontend-monitoring-and-error-tracking-8mb</guid>
      <description>&lt;p&gt;Selecting an error tracking and reporting service is not always easy. There are three main criteria for good error-tracking software:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ability to group similar stack traces into one entity&lt;/li&gt;
&lt;li&gt;support for source maps (because your stack traces will likely be minified)&lt;/li&gt;
&lt;li&gt;ability to export stack traces&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's take one popular example of such systems, &lt;a href="https://sentry.io/" rel="noopener noreferrer"&gt;Sentry.io&lt;/a&gt;, and a couple of corporate-level ones: &lt;a href="https://aws.amazon.com/cloudwatch/" rel="noopener noreferrer"&gt;AWS CloudWatch RUM&lt;/a&gt; and &lt;a href="https://www.splunk.com/en_us/products/real-user-monitoring.html" rel="noopener noreferrer"&gt;Splunk RUM&lt;/a&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;a href="https://sentry.io/" rel="noopener noreferrer"&gt;Sentry.io:&lt;/a&gt;
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Error grouping&lt;/th&gt;
&lt;th&gt;Source maps&lt;/th&gt;
&lt;th&gt;Notifications&lt;/th&gt;
&lt;th&gt;Self-Hosted&lt;/th&gt;
&lt;th&gt;Export&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frf1vknq5l18g77iassd8.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frf1vknq5l18g77iassd8.jpeg" alt="Sentry.io" width="800" height="426"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;a href="https://aws.amazon.com/cloudwatch/" rel="noopener noreferrer"&gt;AWS CloudWatch RUM:&lt;/a&gt;
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Error grouping&lt;/th&gt;
&lt;th&gt;Source maps&lt;/th&gt;
&lt;th&gt;Notifications&lt;/th&gt;
&lt;th&gt;Self-Hosted&lt;/th&gt;
&lt;th&gt;Export&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo4933y6fzz9hgbxqdt1s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo4933y6fzz9hgbxqdt1s.png" alt="AWS CloudWatch RUM" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Error grouping:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpi93qky4f4emn5tdzfic.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpi93qky4f4emn5tdzfic.png" alt="AWS CloudWatch RUM Error grouping" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;No source maps:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7qdtcy0swk2rtyum85md.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7qdtcy0swk2rtyum85md.png" alt="AWS CloudWatch RUM source maps" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;a href="https://www.splunk.com/en_us/products/real-user-monitoring.html" rel="noopener noreferrer"&gt;Splunk RUM:&lt;/a&gt;
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Error grouping&lt;/th&gt;
&lt;th&gt;Source maps&lt;/th&gt;
&lt;th&gt;Notifications&lt;/th&gt;
&lt;th&gt;Self-Hosted&lt;/th&gt;
&lt;th&gt;Export&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fewztwjikdofcub0fqu6r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fewztwjikdofcub0fqu6r.png" alt="Splunk RUM" width="800" height="394"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;No error grouping:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyg27tfqjd66921c1xs5g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyg27tfqjd66921c1xs5g.png" alt="Splunk RUM error grouping" width="800" height="433"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;No source maps:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flpdue9q0w62o1u6gftlo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flpdue9q0w62o1u6gftlo.png" alt="Splunk RUM No source maps" width="800" height="431"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But Splunk RUM has strong features for tracking user actions step-by-step:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi3ixg6ce76dwjv8bxz04.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi3ixg6ce76dwjv8bxz04.png" alt="Splunk RUM session tracking" width="800" height="398"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;CloudWatch RUM and Spunk RUM are not focused on error tracking only, and they don't have notifications about errors. You need some extra time and skill to configure them (this might not be possible).&lt;/p&gt;

</description>
      <category>monitoring</category>
      <category>aws</category>
      <category>devops</category>
      <category>frontend</category>
    </item>
    <item>
      <title>Launch WebStorm from terminal or Finder folder by shortcut in MacOS</title>
      <dc:creator>Vadim Vinogradov</dc:creator>
      <pubDate>Mon, 10 Jan 2022 00:53:22 +0000</pubDate>
      <link>https://dev.to/vadim/launch-webstorm-from-terminal-or-finder-folder-by-shortcut-in-macos-5d59</link>
      <guid>https://dev.to/vadim/launch-webstorm-from-terminal-or-finder-folder-by-shortcut-in-macos-5d59</guid>
      <description>&lt;p&gt;Simple tutorial on how you can quickly run WebStorm (or any JetBrains Intellij Idea) from Finder in MacOS&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/V59RwTqhxzE"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>productivity</category>
      <category>webstorm</category>
    </item>
    <item>
      <title>Comparing frontend libraries</title>
      <dc:creator>Vadim Vinogradov</dc:creator>
      <pubDate>Sat, 08 Jan 2022 19:53:52 +0000</pubDate>
      <link>https://dev.to/vadim/comparing-libraries-3m58</link>
      <guid>https://dev.to/vadim/comparing-libraries-3m58</guid>
      <description>&lt;p&gt;I just want to highlight two great services. They provide some very interesting statistics which might help you to choose a library among competitions. If you haven't seen yet go check it out:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.npmtrends.com/:" rel="noopener noreferrer"&gt;https://www.npmtrends.com/:&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnavsonx5f0vflmnokiaj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnavsonx5f0vflmnokiaj.png" alt="npmtrends compare angular vue react svelte" width="800" height="469"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://openbase.com/:" rel="noopener noreferrer"&gt;https://openbase.com/:&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1zpzp8c4ajqtow13vpsy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1zpzp8c4ajqtow13vpsy.png" alt="openbase vue" width="800" height="335"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>react</category>
      <category>angular</category>
      <category>vue</category>
    </item>
    <item>
      <title>Webpack5 + vue3</title>
      <dc:creator>Vadim Vinogradov</dc:creator>
      <pubDate>Wed, 05 Jan 2022 11:27:25 +0000</pubDate>
      <link>https://dev.to/vadim/webpack5-vue3-g0n</link>
      <guid>https://dev.to/vadim/webpack5-vue3-g0n</guid>
      <description>&lt;p&gt;Nevertheless you can create a simple vue app by&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm install --save-dev @vue/cli&lt;/code&gt;&lt;br&gt;
&lt;code&gt;vue create vue3-project&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;but it is too simple. Sometimes we need to be close to bare metal - then we need a custom build with our own &lt;code&gt;webpack.config.js&lt;/code&gt;. Reasons you might need that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;you are a skilled webpack user&lt;/li&gt;
&lt;li&gt;you have a proven webpack config from a previous project&lt;/li&gt;
&lt;li&gt;you want to integrate with some third parties&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here a simple proven webpack.config.js which allows using &lt;code&gt;Single File Components (SFC)&lt;/code&gt;. Here is a project structure we are going to use:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxlikn7ahgdn27621g47f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxlikn7ahgdn27621g47f.png" alt="Huge Vue project structure with single file components" width="478" height="326"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Features included:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CSS modules&lt;/li&gt;
&lt;li&gt;extract node_modules to a separate file (or chunk, or bundle)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;webpack.config.js&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;path&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;HtmlWebpackPlugin&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;html-webpack-plugin&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;MiniCssExtractPlugin&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;mini-css-extract-plugin&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;CssMinimizerPlugin&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;css-minimizer-webpack-plugin&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;VueLoaderPlugin&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;vue-loader&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;CleanWebpackPlugin&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;clean-webpack-plugin&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;



&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;src&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;__dirname&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;src&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;dist&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;__dirname&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;dist&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;


&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;IS_PRODUCTION&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mode&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;production&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./src/index.js&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;output&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;dist&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;[name]-[contenthash].js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;

        &lt;span class="na"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;alias&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;src&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="na"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;devServer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;static&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;dist&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="na"&gt;plugins&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
            &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;HtmlWebpackPlugin&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
            &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;VueLoaderPlugin&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
            &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;CleanWebpackPlugin&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
        &lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="na"&gt;module&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;rules&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;
                &lt;span class="na"&gt;test&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;\.&lt;/span&gt;&lt;span class="sr"&gt;vue$/&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="na"&gt;loader&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;vue-loader&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="na"&gt;exclude&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sr"&gt;/node_modules/&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="na"&gt;test&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;\.&lt;/span&gt;&lt;span class="sr"&gt;css$/&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="na"&gt;use&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
                    &lt;span class="nx"&gt;IS_PRODUCTION&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;MiniCssExtractPlugin&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;loader&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;style-loader&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="p"&gt;{&lt;/span&gt;
                        &lt;span class="na"&gt;loader&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;css-loader&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="na"&gt;options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                            &lt;span class="na"&gt;modules&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                                &lt;span class="na"&gt;localIdentName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;[local]--[hash:base64:6]&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                            &lt;span class="p"&gt;},&lt;/span&gt;
                        &lt;span class="p"&gt;}&lt;/span&gt;
                    &lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="p"&gt;]&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="na"&gt;test&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;\.&lt;/span&gt;&lt;span class="sr"&gt;js$/&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="na"&gt;loader&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;babel-loader&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="na"&gt;exclude&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sr"&gt;/node_modules/&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="na"&gt;test&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;\.(&lt;/span&gt;&lt;span class="sr"&gt;png|jpe&lt;/span&gt;&lt;span class="se"&gt;?&lt;/span&gt;&lt;span class="sr"&gt;g|gif|webm|mp4|svg&lt;/span&gt;&lt;span class="se"&gt;)&lt;/span&gt;&lt;span class="sr"&gt;$/&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="na"&gt;loader&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;file-loader&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="na"&gt;options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="na"&gt;outputPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;assets&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;}]&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="na"&gt;optimization&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;minimizer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
                &lt;span class="c1"&gt;// extend default plugins&lt;/span&gt;
                &lt;span class="s2"&gt;`...`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="c1"&gt;// HTML and JS are minified by default if config.mode === production.&lt;/span&gt;
                &lt;span class="c1"&gt;// But for CSS we need to add this:&lt;/span&gt;
                &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;CssMinimizerPlugin&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="p"&gt;],&lt;/span&gt;
            &lt;span class="na"&gt;splitChunks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="na"&gt;cacheGroups&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="na"&gt;commons&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                      &lt;span class="na"&gt;test&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;[\\/]&lt;/span&gt;&lt;span class="sr"&gt;node_modules&lt;/span&gt;&lt;span class="se"&gt;[\\/]&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;node_modules&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                      &lt;span class="na"&gt;chunks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;all&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="p"&gt;},&lt;/span&gt;
                &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;


    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;IS_PRODUCTION&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// put all CSS files to a single &amp;lt;link rel="stylesheet" href="..."&amp;gt;&lt;/span&gt;
        &lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;plugins&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;MiniCssExtractPlugin&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
            &lt;span class="na"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;[contenthash].css&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
        &lt;span class="p"&gt;}));&lt;/span&gt;

    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// config.devtool = "inline-source-map";&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;package.json&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"start"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"webpack serve --open --mode=development"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"build"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"webpack --mode=production --progress"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"dist-clean"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"rm -fr dist/*"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Full project &lt;a href="https://github.com/vinogradov/webpack-templates/tree/main/webpack5-simple-vue3" rel="noopener noreferrer"&gt;https://github.com/vinogradov/webpack-templates/tree/main/webpack5-simple-vue3&lt;/a&gt;. Thanks!&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>vue</category>
      <category>webpack</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
