<?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>Forem: NullVoxPopuli</title>
    <description>The latest articles on Forem by NullVoxPopuli (@nullvoxpopuli).</description>
    <link>https://forem.com/nullvoxpopuli</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%2F97500%2F077ff765-0daa-49b3-93cf-80f9ef2a2ee9.jpg</url>
      <title>Forem: NullVoxPopuli</title>
      <link>https://forem.com/nullvoxpopuli</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/nullvoxpopuli"/>
    <language>en</language>
    <item>
      <title>Errors encountered with one-shot AI</title>
      <dc:creator>NullVoxPopuli</dc:creator>
      <pubDate>Thu, 18 Dec 2025 20:51:00 +0000</pubDate>
      <link>https://forem.com/nullvoxpopuli/errors-encountered-with-one-shot-ai-g3l</link>
      <guid>https://forem.com/nullvoxpopuli/errors-encountered-with-one-shot-ai-g3l</guid>
      <description>&lt;p&gt;This is a lists of silly errors I've seen agents encounter, and how they should fix them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Could not resolve &lt;code&gt;@glimmer/application.json&lt;/code&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Error
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;✘ [ERROR] Could not resolve "@glimmer/application.json" [plugin embroider-esbuild-resolver]

    node_modules/.pnpm/@glimmer+component@1.1.2_@babel+core@7.28.5/node_modules/@glimmer/component/dist/modules/es2017/src/component.js:2:36:
      2 │ import { setComponentManager } from '@glimmer/application';
        ╵                                     ~~~~~~~~~~~~~~~~~~~~~~
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Solution
&lt;/h3&gt;

&lt;p&gt;Upgrade &lt;code&gt;@glimmer/component&lt;/code&gt; to &lt;code&gt;^2.0.0&lt;/code&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  failed to load config from vite.config.mjs ... ember-scoped-css
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Error
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;failed to load config from &amp;lt;repo&amp;gt;/vite.config.mjs
error when starting dev server:
file://&amp;lt;repo&amp;gt;/node_modules/.vite-temp/vite.config.mjs.timestamp-1766089944685-a3e3cc4ce187e8.mjs:5
import scopedCss from "file://&amp;lt;.pnpm&amp;gt;/&amp;lt;package path&amp;gt;/ember-scoped-css/src/build/public-exports/vite.js";
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Solution
&lt;/h3&gt;

&lt;p&gt;Read the docs at &lt;a href="https://github.com/auditboard/ember-scoped-css" rel="noopener noreferrer"&gt;https://github.com/auditboard/ember-scoped-css&lt;/a&gt; to see how to configure vite&lt;/p&gt;




&lt;h2&gt;
  
  
   ERR_PNPM_NO_MATCHING_VERSION ... for &lt;a class="mentioned-user" href="https://dev.to/glimmer"&gt;@glimmer&lt;/a&gt;/tracking@^2.0.0
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Error
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ERR_PNPM_NO_MATCHING_VERSION  No matching version found for @glimmer/tracking@^2.0.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Solution
&lt;/h3&gt;

&lt;p&gt;Remove &lt;code&gt;@glimmer/tracking&lt;/code&gt; from package.json. It is a virtual package provided by &lt;code&gt;ember-source&lt;/code&gt; via the &lt;code&gt;ember()&lt;/code&gt; vite plugin.&lt;/p&gt;




&lt;h2&gt;
  
  
  RegExp.escape is not a function (or other node related version issues)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Error
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  ✘ [ERROR] &amp;lt;file-path&amp;gt;: RegExp.escape is not a function [plugin &amp;lt;plugin-name&amp;gt;]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Solution
&lt;/h3&gt;

&lt;p&gt;Use node 24, likely by updating either the &lt;code&gt;package.json.volta&lt;/code&gt; config or the &lt;code&gt;engines.node&lt;/code&gt; option (which many tools read).&lt;br&gt;
If the environment is using &lt;code&gt;proto&lt;/code&gt;, delete the &lt;code&gt;.nvmrc&lt;/code&gt; or update it to &lt;em&gt;also&lt;/em&gt; use noed 24.&lt;/p&gt;


&lt;h2&gt;
  
  
  Multiple exports with the same name "default"
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Error
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;✘ [ERROR] Multiple exports with the same name "default"

    src/components/search-widget.gjs:99:7:
      99 │ export default setComponentTemplate(createTemplateFactory(
         ╵        ~~~~~~~

  The name "default" was originally exported here:

    src/components/search-widget.gjs:1:0:
      1 │ import Component from '@glimmer/component';
        ╵ ~~~~~~
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;or&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;file-name&amp;gt; (330:0): Duplicate export "default"
file: &amp;lt;file-name&amp;gt;:330:0

328: }
329: 
330: &amp;lt;template&amp;gt;
     ^
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Solution
&lt;/h3&gt;

&lt;p&gt;This happens because the agent did this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export default class X extends Component { ... }

&amp;lt;template&amp;gt;
...
&amp;lt;/template&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is an incorrect understanding of how gjs works, and the Agent should review the #ember-mcp-provided documentation again, or check this &lt;a href="https://guides.emberjs.com/release/components/template-tag-format/" rel="noopener noreferrer"&gt;brief overview&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;&amp;lt;template&amp;gt;...&amp;lt;/template&amp;gt;&lt;/code&gt; must go inside the component like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export default class X extends Component { 
  // ...

  &amp;lt;template&amp;gt;
  ...
  &amp;lt;/template&amp;gt;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When having bare &lt;code&gt;&amp;lt;template&amp;gt;...&amp;lt;/template&amp;gt;&lt;/code&gt; in module space, that is known as the "implicit default form", as described in &lt;a href="https://github.com/emberjs/rfcs/pull/779" rel="noopener noreferrer"&gt;RFC #779&lt;/a&gt;&lt;/p&gt;




</description>
      <category>ember</category>
      <category>ai</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Logging tests to the terminal in browser tests to help AI find your test results</title>
      <dc:creator>NullVoxPopuli</dc:creator>
      <pubDate>Thu, 06 Nov 2025 16:45:11 +0000</pubDate>
      <link>https://forem.com/nullvoxpopuli/logging-tests-to-the-terminal-in-browser-tests-to-help-ai-find-your-test-results-1bl9</link>
      <guid>https://forem.com/nullvoxpopuli/logging-tests-to-the-terminal-in-browser-tests-to-help-ai-find-your-test-results-1bl9</guid>
      <description>&lt;p&gt;Before doing this though, you should see if your AI tool has tool to run your browser tests (VSCode has simpleBrowser, for example). That will yield better output, behavior, and interactions. AIs currently mistakenly want to use bad terminal commands for everything, so it's never a default for an AI to run tests in the browser without first being told.&lt;/p&gt;




&lt;p&gt;When using vite, you have a huge ecosystem of plugins to choose from.&lt;/p&gt;

&lt;p&gt;If you don't already have a vite app&lt;/p&gt;

&lt;p&gt;Create one via:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pnpm dlx ember-cli@latest new demo-terminal-logging-during-ember-browser-testing &lt;span class="nt"&gt;--pnpm&lt;/span&gt;
&lt;span class="nb"&gt;cd &lt;/span&gt;demo-terminal-logging-during-ember-browser-testing
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;I found &lt;a href="https://github.com/patak-dev/vite-plugin-terminal" rel="noopener noreferrer"&gt;https://github.com/patak-dev/vite-plugin-terminal&lt;/a&gt; by Patak, one of the vite developers!&lt;/p&gt;

&lt;p&gt;Setting this plugin up an an ember project to get browser-test results in the terminal is quite straight-forward:&lt;/p&gt;

&lt;p&gt;In your vite config, add the plugin:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="gi"&gt;+ import Terminal from 'vite-plugin-terminal';
&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;  export default defineConfig({
    plugins: [
&lt;span class="gi"&gt;+     Terminal({ console: 'terminal' }),
&lt;/span&gt;      ember(),
      babel({
        babelHelpers: 'runtime',
        extensions,
      }),
    ],
  });
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And QUnit doesn't log to the console in &lt;code&gt;/tests&lt;/code&gt; mode by default, so let's add some logging in &lt;code&gt;tests/test-helper.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="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;QUnit&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;qunit&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;QUnit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;testDone&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;info&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;info&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;failed&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;✅&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;❌&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;statusText&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;info&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;failed&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;passed&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;failed&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;group&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;info&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="s2"&gt; &amp;gt; &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;info&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;statusText&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`   Assertions:`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;assertion&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;info&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;assertions&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`     &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;assertion&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;assertion&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;groupEnd&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;And that's it!&lt;/p&gt;

&lt;p&gt;Now when you run tests, you'll get output like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;» [vite] connected.
» DEBUG: -------------------------------
» DEBUG: Ember : 6.8.1
» DEBUG: -------------------------------
»   ✅ example &amp;gt; example test: passed
»      Assertions:
»        true: okay
»
»   ✅ ember-qunit: Ember.onerror validation &amp;gt; Ember.onerror is functioning properly: passed
»      Assertions:
»        true: Ember.onerror handler with invalid testing behavior detected. An Ember.onerror handler _must_ rethrow exceptions when `Ember.testing` is `true` or the test suite is unreliable. See https://git.io/vbine for more details.
»
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Try it out here: &lt;a href="https://github.com/NullVoxPopuli/demo-terminal-logging-during-ember-browser-testing" rel="noopener noreferrer"&gt;https://github.com/NullVoxPopuli/demo-terminal-logging-during-ember-browser-testing&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>ember</category>
      <category>claude</category>
      <category>vscode</category>
    </item>
    <item>
      <title>Repository growth over time</title>
      <dc:creator>NullVoxPopuli</dc:creator>
      <pubDate>Fri, 15 Aug 2025 15:18:00 +0000</pubDate>
      <link>https://forem.com/nullvoxpopuli/repository-growth-over-time-1o5a</link>
      <guid>https://forem.com/nullvoxpopuli/repository-growth-over-time-1o5a</guid>
      <description>&lt;p&gt;For large corporate projects where performance often comes up, it's important to take things in to perspective.&lt;/p&gt;

&lt;p&gt;I like to use codebase size over time, which can be measured with &lt;a href="https://github.com/XAMPPRocky/tokei" rel="noopener noreferrer"&gt;tokei&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;And then there is are a couple secret git commands to checkout commits with relative dates.&lt;/p&gt;

&lt;p&gt;Git will actively fight you trying to fetch every commit for all of time.&lt;/p&gt;

&lt;p&gt;See this &lt;a href="https://www.endpointdev.com/blog/2014/05/git-checkout-at-specific-date/" rel="noopener noreferrer"&gt;other post for more/related information&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git checkout &lt;span class="si"&gt;$(&lt;/span&gt;git rev-list &lt;span class="nt"&gt;-1&lt;/span&gt; &lt;span class="nt"&gt;--before&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"Aug 15 2024"&lt;/span&gt; main&lt;span class="si"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There is a more ergonomic way to checkout old commits, but it only works if you already have the list of commits fetched, which is less easy to do than the above&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git checkout main@&lt;span class="o"&gt;{&lt;/span&gt;1.year.ago&lt;span class="o"&gt;}&lt;/span&gt; 
&lt;span class="c"&gt;# warning: log for 'main' only goes back to Tue, 15 Jul 2025 ...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This would get you the wrong commit (from only a month ago, instead of a year ago)&lt;/p&gt;

&lt;p&gt;Once we have the old commit (verified with the top of &lt;code&gt;git log&lt;/code&gt;), we can run &lt;code&gt;tokei&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;tokei
&lt;span class="c"&gt;#  Total                 18638      1981370      1671372        92166       217832&lt;/span&gt;
&lt;span class="c"&gt;#                                   ^ total lines&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>git</category>
    </item>
    <item>
      <title>What to do when your git worktree is not detecting file changes</title>
      <dc:creator>NullVoxPopuli</dc:creator>
      <pubDate>Mon, 07 Apr 2025 16:20:11 +0000</pubDate>
      <link>https://forem.com/nullvoxpopuli/what-to-do-when-your-git-worktree-is-not-detecting-f-ile-changes-33ad</link>
      <guid>https://forem.com/nullvoxpopuli/what-to-do-when-your-git-worktree-is-not-detecting-f-ile-changes-33ad</guid>
      <description>&lt;p&gt;I find that I run in to this problem about every other month or so -- just long enough to forget how to solve it.&lt;/p&gt;

&lt;p&gt;Here is the situation:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I have local changes&lt;/li&gt;
&lt;li&gt;editor tools can point out which lines have changes&lt;/li&gt;
&lt;li&gt;my &lt;code&gt;cat&lt;/code&gt; replacement (&lt;a href="https://github.com/sharkdp/bat" rel="noopener noreferrer"&gt;bat&lt;/a&gt;), shows the changed lines&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;The Problem&lt;/em&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;git diff&lt;/code&gt; and &lt;code&gt;git status&lt;/code&gt; report no local changes&lt;/li&gt;
&lt;li&gt;creating new files also do not show up in &lt;code&gt;git diff&lt;/code&gt; and &lt;code&gt;git status&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This leads to me being unable to create a commit.&lt;/p&gt;

&lt;p&gt;What I expect:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;git status&lt;/code&gt; to show changed files, and the new file, if I make one&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;git diff&lt;/code&gt; should only show changed tracked files (it wouldn't report new / untracked files by default)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Things I've verified:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The working directory of both the copy of the repo with the file changes and the terminal where I'm checking &lt;code&gt;git status&lt;/code&gt; are the same (sometimes it's easy to forget you can be in two very similar directories (but not exactly) when using worktrees) -- this is verified because &lt;code&gt;bat&lt;/code&gt; shows line-wise git information in the gutter.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The fix
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git update-index &lt;span class="nt"&gt;--no-assume-unchanged&lt;/span&gt; ./file1
git update-index &lt;span class="nt"&gt;--no-assume-unchanged&lt;/span&gt; ./file2

&lt;span class="c"&gt;# for every package.json&lt;/span&gt;
git update-index &lt;span class="nt"&gt;--no-assume-unchanged&lt;/span&gt;  &lt;span class="si"&gt;$(&lt;/span&gt;git ls-files | &lt;span class="nb"&gt;grep &lt;/span&gt;package.json&lt;span class="si"&gt;)&lt;/span&gt;

&lt;span class="c"&gt;# for all files &lt;/span&gt;
&lt;span class="c"&gt;# (for large repos we can't use the above command because &lt;/span&gt;
&lt;span class="c"&gt;#   update-index has a limit on the number of args passed)&lt;/span&gt;
&lt;span class="c"&gt;#&lt;/span&gt;
&lt;span class="c"&gt;# NOTE: this can be very slow&lt;/span&gt;
&lt;span class="k"&gt;for &lt;/span&gt;file &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;git ls-files&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
  &lt;/span&gt;git update-index &lt;span class="nt"&gt;--no-assume-unchanged&lt;/span&gt; &lt;span class="nv"&gt;$file&lt;/span&gt;
&lt;span class="k"&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On the repo I have at work where I run in to this problem, I have to do the above fix in every worktree and commit. &lt;/p&gt;

&lt;p&gt;It seems once I commit in a particular worktree, git starts tracking files automatically again.&lt;/p&gt;

&lt;p&gt;of note, the work computer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;is macOS 15.3.2, but I observed this behavior on 14.x, as well&lt;/li&gt;
&lt;li&gt;has various security tools on it, but they've been changed out a number of times, so I don't think I can blame a specific one&lt;/li&gt;
&lt;li&gt;git is installed via homebrew&lt;/li&gt;
&lt;li&gt;permanently in clamshell mode (laptops are notoriously not good at this -- &lt;em&gt;especially&lt;/em&gt; macOS)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;On Linux, I also make heavy use of worktrees, but have not run in to this problem -- but it's hard to compare&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;no XProtect (mac's default security software part of "System Integrity Protection")&lt;/li&gt;
&lt;li&gt;I manage the system myself&lt;/li&gt;
&lt;li&gt;I don't use clamshell (I use my linux laptop as an actual laptop, and my linux desktop... has no clamshell mode haha)&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>git</category>
    </item>
    <item>
      <title>Vite supports your ember project back to ember 3.28!</title>
      <dc:creator>NullVoxPopuli</dc:creator>
      <pubDate>Sun, 06 Apr 2025 21:44:48 +0000</pubDate>
      <link>https://forem.com/nullvoxpopuli/vite-supports-your-ember-project-back-to-ember-328-m8d</link>
      <guid>https://forem.com/nullvoxpopuli/vite-supports-your-ember-project-back-to-ember-328-m8d</guid>
      <description>&lt;p&gt;Originally posted by the &lt;a href="https://bsky.app/profile/emberjs.com/post/3lksovae6n22z" rel="noopener noreferrer"&gt;EmberJS account on bluesky&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Last week the Ember Tooling team released the &lt;a href="https://github.com/embroider-build/embroider/" rel="noopener noreferrer"&gt;embroider project&lt;/a&gt; from alpha to stable, signalling that non-explorers should now try Vite with their ember projects if they want a massive performance boost to their build system.&lt;/p&gt;

&lt;p&gt;There is a &lt;a href="https://mainmatter.com/blog/2025/03/10/ember-vite-codemod/" rel="noopener noreferrer"&gt;codemod by mainmatter&lt;/a&gt; to help everything with their migration.&lt;/p&gt;

&lt;p&gt;It (and embroider-vite) supports every LTS form 3.28+ and then ember-source 5.12+&lt;/p&gt;

&lt;p&gt;So that's &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;3.28&lt;/li&gt;
&lt;li&gt;4.4&lt;/li&gt;
&lt;li&gt;4.8&lt;/li&gt;
&lt;li&gt;4.12&lt;/li&gt;
&lt;li&gt;5.4&lt;/li&gt;
&lt;li&gt;5.8&lt;/li&gt;
&lt;li&gt;5.12&lt;/li&gt;
&lt;li&gt;6.4+&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is &amp;gt; 4 years of supported ember versions!&lt;/p&gt;

&lt;p&gt;There are now many vite-using ember apps in the wild, and I look forward to seeing what all everyone comes up with!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Ember.js Acquires React in Hostile Takeover, Demands it Learn Real Reactivity</title>
      <dc:creator>NullVoxPopuli</dc:creator>
      <pubDate>Sun, 06 Apr 2025 21:07:36 +0000</pubDate>
      <link>https://forem.com/nullvoxpopuli/emberjs-acquires-react-in-hostile-takeover-demands-it-learn-real-reactivity-3629</link>
      <guid>https://forem.com/nullvoxpopuli/emberjs-acquires-react-in-hostile-takeover-demands-it-learn-real-reactivity-3629</guid>
      <description>&lt;p&gt;for April 1st day, I asked GPT to make an onion headline... and OMG Chat GPT is &lt;em&gt;savage&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Originally posted on &lt;a href="https://bsky.app/profile/nullvoxpopuli.com/post/3llr5nvm5ue2f" rel="noopener noreferrer"&gt;bluesky&lt;/a&gt;&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%2Fcdn.bsky.app%2Fimg%2Ffeed_thumbnail%2Fplain%2Fdid%3Aplc%3Age6cnpneodmysqqgv5wylvaz%2Fbafkreih2fsd2w53vx4fyuznjfe5shov5h76vampodekdjvj7c6bi7n5iuu%40jpeg" 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%2Fcdn.bsky.app%2Fimg%2Ffeed_thumbnail%2Fplain%2Fdid%3Aplc%3Age6cnpneodmysqqgv5wylvaz%2Fbafkreih2fsd2w53vx4fyuznjfe5shov5h76vampodekdjvj7c6bi7n5iuu%40jpeg" alt="see text below" width="754" height="754"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It reads:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Ember.js Acquires React in Hostile Takeover, Demands It Learn Real Reactivity&lt;/p&gt;

&lt;p&gt;&lt;em&gt;React agrees to add templates, router, and sense of humility.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Vue.js declines to comment, just sips tea.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Just  🧑‍🍳 &lt;/p&gt;

&lt;p&gt;I wonder what source material it pulled from?&lt;br&gt;
Is there a way to even know?&lt;/p&gt;

</description>
      <category>ember</category>
      <category>react</category>
      <category>javascript</category>
    </item>
    <item>
      <title>One shot convert React to Ember with AI</title>
      <dc:creator>NullVoxPopuli</dc:creator>
      <pubDate>Sun, 06 Apr 2025 19:50:00 +0000</pubDate>
      <link>https://forem.com/nullvoxpopuli/one-shot-convert-react-to-ember-with-ai-5099</link>
      <guid>https://forem.com/nullvoxpopuli/one-shot-convert-react-to-ember-with-ai-5099</guid>
      <description>&lt;p&gt;Original Post on &lt;a href="https://bsky.app/profile/nullvoxpopuli.com/post/3lm5s77hlxs2o" rel="noopener noreferrer"&gt;bluesky&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Using the &lt;a href="https://chatgpt.com/g/g-NlX2z2g6H-ember-assistant" rel="noopener noreferrer"&gt;Ember Assistant&lt;/a&gt; custom GPT, you can one-shot convert React components to Ember components.&lt;/p&gt;

&lt;p&gt;For example, I asked the &lt;em&gt;Ember Assistant&lt;/em&gt;, simply:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;Can you convert this React component to Ember?

&lt;span class="p"&gt;```&lt;/span&gt;&lt;span class="nl"&gt;jsx
&lt;/span&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Counter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setCount&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&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;increment&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;setCount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;decrement&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;setCount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;This is our counter Application&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;decrement&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;-&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Clicks &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;increment&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;+&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&amp;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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;And this was Chat GPT's response -- which is not only correct, but also fixes a couple bugs!:&lt;/p&gt;




&lt;p&gt;Here's a modern Ember (Polaris edition) version of your React &lt;code&gt;Counter&lt;/code&gt; component using the &lt;code&gt;.gjs&lt;/code&gt; format:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;app/components/Counter.gjs&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import Component from '@glimmer/component';
import { tracked } from '@glimmer/tracking';

export default class Counter extends Component {
  @tracked count = 0;

  increment = () =&amp;gt; {
    this.count++;
  };

  decrement = () =&amp;gt; {
    this.count--;
  };

  &amp;lt;template&amp;gt;
    &amp;lt;div&amp;gt;This is our counter Application&amp;lt;/div&amp;gt;
    &amp;lt;div&amp;gt;
      &amp;lt;button type="button" {{on "click" this.decrement}} aria-label="Decrease count"&amp;gt;-&amp;lt;/button&amp;gt;
      &amp;lt;span&amp;gt;Clicks {this.count}&amp;lt;/span&amp;gt;
      &amp;lt;button type="button" {{on "click" this.increment}} aria-label="Increase count"&amp;gt;+&amp;lt;/button&amp;gt;
    &amp;lt;/div&amp;gt;
  &amp;lt;/template&amp;gt;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Notes:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Uses @tracked for reactivity.&lt;/li&gt;
&lt;li&gt;Uses arrow functions for actions (increment, decrement) — no need for the @action decorator.&lt;/li&gt;
&lt;li&gt;The buttons use type="button" and aria-label for accessibility (important in Ember too).&lt;/li&gt;
&lt;li&gt;Everything lives in a single .gjs file — ideal for Polaris.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let me know if you’d like to see this in classic .js + .hbs Octane format too!  &lt;/p&gt;




&lt;p&gt;NOTE: it seems dev.to doesn't render gjs 🤔&lt;/p&gt;

</description>
      <category>ember</category>
      <category>react</category>
      <category>ai</category>
    </item>
    <item>
      <title>Ember has typesafe HTML</title>
      <dc:creator>NullVoxPopuli</dc:creator>
      <pubDate>Sun, 06 Apr 2025 19:47:00 +0000</pubDate>
      <link>https://forem.com/nullvoxpopuli/ember-has-typesafe-html-50gn</link>
      <guid>https://forem.com/nullvoxpopuli/ember-has-typesafe-html-50gn</guid>
      <description>&lt;p&gt;Original post @ &lt;a href="https://nullvoxpopuli.com/2025-04-05-ember-has-typesafe-html" rel="noopener noreferrer"&gt;nullvoxpopuli.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ember has had typesafe HTML for a while now. Details on getting it set up &lt;a href="https://github.com/typed-ember/glint/blob/main/GLINT_V2.md" rel="noopener noreferrer"&gt;are here on the Glint repo&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;tl;dr: install the pre-release version of the Glint extension and enable &lt;code&gt;@builtin typescript&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;We're using the pre-release version of Glint here because it provides a far superior editing than the currently released stable version of Glint. Glint V2 is powered by &lt;a href="https://volarjs.dev/" rel="noopener noreferrer"&gt;Volar&lt;/a&gt; and lines up nicely with the &lt;a href="https://emberjs.com/editions/polaris/" rel="noopener noreferrer"&gt;Polaris&lt;/a&gt; efforts to align with broader ecosystem tooling in a way that unblocks all experimentation while also still supporting older code so that large codebase have a path to the modern tooling and DX.&lt;/p&gt;

&lt;p&gt;For neovim, I need to PR to the built in configs to make switching to the glint ts-plugin automatic, but here is what it looks like!&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%2Fypfmpg0tnvpmsi0hd39v.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%2Fypfmpg0tnvpmsi0hd39v.png" alt="image of href completion" width="800" height="380"&gt;&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%2Fthlzshxzqf5m6adtobcn.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%2Fthlzshxzqf5m6adtobcn.png" alt="image of href type error" width="800" height="413"&gt;&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%2Fw1pm41b4imekj5q1lmht.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%2Fw1pm41b4imekj5q1lmht.png" alt="image of aria atttribute completion" width="800" height="380"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ember</category>
      <category>javascript</category>
      <category>typescript</category>
    </item>
    <item>
      <title>Tired of the punycode deprecation message?</title>
      <dc:creator>NullVoxPopuli</dc:creator>
      <pubDate>Tue, 06 Aug 2024 19:43:04 +0000</pubDate>
      <link>https://forem.com/nullvoxpopuli/tired-of-the-punycode-deprecation-message-40ml</link>
      <guid>https://forem.com/nullvoxpopuli/tired-of-the-punycode-deprecation-message-40ml</guid>
      <description>&lt;p&gt;Are you tired of seeing 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="o"&gt;[&lt;/span&gt;DEP0040] DeprecationWarning: The &lt;span class="sb"&gt;`&lt;/span&gt;punycode&lt;span class="sb"&gt;`&lt;/span&gt; module is deprecated. Please use a userland alternative instead.
     at node:punycode:3:9
     at BuiltinModule.compileForInternalLoader &lt;span class="o"&gt;(&lt;/span&gt;node:internal/bootstrap/realm:399:7&lt;span class="o"&gt;)&lt;/span&gt;
     at BuiltinModule.compileForPublicLoader &lt;span class="o"&gt;(&lt;/span&gt;node:internal/bootstrap/realm:338:10&lt;span class="o"&gt;)&lt;/span&gt;
     at loadBuiltinModule &lt;span class="o"&gt;(&lt;/span&gt;node:internal/modules/helpers:96:7&lt;span class="o"&gt;)&lt;/span&gt;
     at Module._load &lt;span class="o"&gt;(&lt;/span&gt;node:internal/modules/cjs/loader:1070:17&lt;span class="o"&gt;)&lt;/span&gt;
     at TracingChannel.traceSync  
     ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The "Solve"
&lt;/h2&gt;

&lt;p&gt;Change your &lt;code&gt;start&lt;/code&gt; or &lt;code&gt;dev&lt;/code&gt; script in package.json to be prefixed with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;NODE_NO_WARNINGS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For example,&lt;br&gt;
if you previously had&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;start&lt;/span&gt;&lt;span class="dl"&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;vite&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;change it to&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;start&lt;/span&gt;&lt;span class="dl"&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;NODE_NO_WARNINGS=1 vite&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you can enjoy console output with 80,000 less lines of spew.&lt;/p&gt;




&lt;p&gt;If you are motivated and have the time, it &lt;em&gt;is&lt;/em&gt; beneficial to try to help out packages by either:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;upgrading them to a version that doesn't trigger the deprecation&lt;/li&gt;
&lt;li&gt;PR a fix that doesn't trigger the deprecation (uses a userland module, as instructed).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The userland module is here: &lt;a href="https://github.com/mathiasbynens/punycode.js" rel="noopener noreferrer"&gt;https://github.com/mathiasbynens/punycode.js&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And you can scan all your dependencies for violations (so you don't have to rely on runtime to find every occurrance) with this tool: &lt;a href="https://github.com/NullVoxPopuli/punycode-detector" rel="noopener noreferrer"&gt;punycode-detector&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx punycode-detector
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pnpm dlx punycode-detector
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;









&lt;p&gt;This also works for other tools&lt;/p&gt;

&lt;p&gt;For example,&lt;br&gt;
if you previously had&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;start&lt;/span&gt;&lt;span class="dl"&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;ember serve&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;change it to&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;start&lt;/span&gt;&lt;span class="dl"&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;NODE_NO_WARNINGS=1 ember serve&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>javascript</category>
      <category>node</category>
      <category>code</category>
    </item>
    <item>
      <title>Effects in Ember</title>
      <dc:creator>NullVoxPopuli</dc:creator>
      <pubDate>Fri, 07 Jun 2024 15:17:00 +0000</pubDate>
      <link>https://forem.com/nullvoxpopuli/effects-in-ember-15n9</link>
      <guid>https://forem.com/nullvoxpopuli/effects-in-ember-15n9</guid>
      <description>&lt;p&gt;Originally from &lt;a href="https://discuss.emberjs.com/t/how-to-make-an-effect-in-ember/20520?u=nullvoxpopuli" rel="noopener noreferrer"&gt;How to make an effect in Ember?&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a class="mentioned-user" href="https://dev.to/trusktr"&gt;@trusktr&lt;/a&gt; asks:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What’s the equivalent of Solid.js &lt;code&gt;createEffect()&lt;/code&gt; (or React &lt;code&gt;useEffect()&lt;/code&gt;, Meteor &lt;code&gt;Tracker.autorun()&lt;/code&gt;, MobX &lt;code&gt;autorun()&lt;/code&gt;, Vue &lt;code&gt;watchEffect()&lt;/code&gt;, Svelte &lt;code&gt;$effect()&lt;/code&gt;, Angular &lt;code&gt;effect()&lt;/code&gt;) in Ember.js?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is certainly shocking to folks new to ember, but ember deliberately doesn't have an any effect by default.&lt;/p&gt;

&lt;p&gt;Now, as a &lt;em&gt;framework&lt;/em&gt; author, the concept does  &lt;em&gt;sort of&lt;/em&gt; exist (at a high level) -- but I'll circle back around to this in a smidge.&lt;/p&gt;

&lt;p&gt;In your Solid demo, if you want to log function calls, you'd do:&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;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1&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;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;2&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;c&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;template&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="nf"&gt;log &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)}}&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/template&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Some notes on function invocation syntax, if needed&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://tutorial.glimdown.com/1-introduction/3-transforming-data" rel="noopener noreferrer"&gt;Glimmer Tutorial: Transforming Data&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://cheatsheet.glimmer.nullvoxpopuli.com/docs/templates#template__notation" rel="noopener noreferrer"&gt;https://cheatsheet.glimmer.nullvoxpopuli.com/docs/templates#template__notation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We use templates as the sole entrypoint to reactivity, whereas solid's reactivity is more general purpose.  With templates, and being DOM focused (&lt;a href="https://github.com/emberjs/ember.js/issues/20648" rel="noopener noreferrer"&gt;for now&lt;/a&gt;), we can ask ourselves:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"If the user can't see the data rendered, does the data need to exist?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now, you're demo (with logging) is definitely effect-y. And if you &lt;em&gt;had no other way&lt;/em&gt; (like the situation was somehow impossible to model in a derived data way), you can do this:&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;function&lt;/span&gt; &lt;span class="nf"&gt;myLog&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;a&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="nf"&gt;b&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="nf"&gt;c&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;template&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;myLog&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/template&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This would auto-track, so as the consumed tracked data accessed from each of &lt;code&gt;a&lt;/code&gt;, &lt;code&gt;b&lt;/code&gt;, and &lt;code&gt;c&lt;/code&gt; changed, &lt;code&gt;myLog&lt;/code&gt; would get to re-run. &lt;br&gt;
However, this has a caveat: data may not be &lt;em&gt;set&lt;/em&gt; within &lt;code&gt;myLog&lt;/code&gt;, else an infinite render loop would occur.&lt;/p&gt;

&lt;p&gt;This is covered here&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://tutorial.glimdown.com/2-reactivity/10-synchronizing-external-state" rel="noopener noreferrer"&gt;Glimmer Tutorial: &lt;em&gt;synchronizing state&lt;/em&gt;&lt;/a&gt; (to the console in this  case)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There is a way around the above caveat, not being able to set during render, by making &lt;code&gt;myLog&lt;/code&gt; invoke an async-IIFE, and waiting a tiny bit (i.e.: setting slightly after render):&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="c1"&gt;// now we're passing in the args directly so that they&lt;/span&gt;
&lt;span class="c1"&gt;// are tracked (all args are auto-tracked in all&lt;/span&gt;
&lt;span class="c1"&gt;// function / helper / component / modifier execution&lt;/span&gt;
&lt;span class="c1"&gt;// coming from the template)&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;myLog&lt;/span&gt;&lt;span class="p"&gt;(...&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="c1"&gt;// causes a change in a's data&lt;/span&gt;
    &lt;span class="c1"&gt;// and because we awaited, we don't infinite loop &lt;/span&gt;
    &lt;span class="nf"&gt;setA&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; 
    &lt;span class="c1"&gt;// prints a pre-setA, because a was passed in&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(...&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
 &lt;span class="c1"&gt;// return nothing, render nothing &lt;/span&gt;
 &lt;span class="c1"&gt;// (we have no result to show the user)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;template&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="nf"&gt;myLog &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)}}&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/template&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is nuanced, and is why I made this tiny abstraction a whole thing over here &lt;a href="https://reactive.nullvoxpopuli.com/functions/sync.sync.html" rel="noopener noreferrer"&gt;https://reactive.nullvoxpopuli.com/functions/sync.sync.html&lt;/a&gt;&lt;br&gt;
it's 95% documentation, 5% code 😅 &lt;/p&gt;




&lt;p&gt;So coming back to:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"We deliberately don't have effects"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Because of a couple current facts about our ecosystem:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;we want derived data to be preferred, because it is the most efficient way to have your render state settle&lt;/li&gt;
&lt;li&gt;calling a function from a template can only happen after the template is rendered, so doing so causes a &lt;em&gt;second render&lt;/em&gt; (I believe this is true in React as well) &lt;/li&gt;
&lt;li&gt;there &lt;em&gt;is&lt;/em&gt; a need to synchronize external state, and that has been part of the exploration of &lt;em&gt;Resources&lt;/em&gt;, and &lt;code&gt;Sync&lt;/code&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://newdocs-rho.vercel.app/docs/universal/fundamentals/sync.html" rel="noopener noreferrer"&gt;Starbeam Docs on &lt;code&gt;Sync&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.starbeamjs.com/guides/fundamentals/resources.html" rel="noopener noreferrer"&gt;Starbeam Docs on &lt;code&gt;Resource&lt;/code&gt;s&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Current ember implementation does not have &lt;code&gt;sync&lt;/code&gt; capabilities: &lt;a href="https://github.com/NullVoxPopuli/ember-resources/tree/main/docs" rel="noopener noreferrer"&gt;ember-resources&lt;/a&gt; (due to limitations of the private APIs implementing reactivity (ember-resources is public-API only))&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://tutorial.glimdown.com/2-reactivity/5-resources" rel="noopener noreferrer"&gt;Tutorial Chapters on Resources&lt;/a&gt; &lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;we think that effects are &lt;em&gt;overused&lt;/em&gt; and a huge footgun (for app devs), so by documenting a story more around synchronizing external state, we can continue to guide devs in to a pit of success.&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;Note: Starbeam is where we're extracting our reactivity primitives, and are planning to swap to Starbeam entirely at some point once we work out some composition ergonomics for serial Resources (the coloring problem).&lt;/p&gt;

&lt;p&gt;Hope this helps! &lt;br&gt;
If anything is unclear or if you have more questions, let me know!&lt;/p&gt;

</description>
      <category>ember</category>
      <category>effect</category>
      <category>javascript</category>
    </item>
    <item>
      <title>unsupported ambiguity between helper and component</title>
      <dc:creator>NullVoxPopuli</dc:creator>
      <pubDate>Tue, 09 Apr 2024 20:11:33 +0000</pubDate>
      <link>https://forem.com/nullvoxpopuli/unsupported-ambiguity-between-helper-and-component-3mgc</link>
      <guid>https://forem.com/nullvoxpopuli/unsupported-ambiguity-between-helper-and-component-3mgc</guid>
      <description>&lt;p&gt;This error occurs when you're progressing towards a modern ember app and have the following situation in your embroider options:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;staticHelpers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="nx"&gt;staticComponents&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and you reference a helper, such as &lt;code&gt;{{t}}&lt;/code&gt; from &lt;a href="https://github.com/ember-intl/ember-intl" rel="noopener noreferrer"&gt;&lt;code&gt;ember-intl&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Here is the full text:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;path to source of issue&amp;gt;: 
  unsupported ambiguity between helper and component: 
    this use of "{{t}}" could be helper "{{ (t) }}" or
    component "&amp;lt;T /&amp;gt;", and your settings for 
    staticHelpers and staticComponents do not agree. 
  Either switch to one of the unambiguous forms, 
    or make staticHelpers and staticComponents agree, 
    or use a "disambiguate" packageRule to work around 
    the problem if its in third-party code you cannot 
    easily fix. 
  in &amp;lt;path to source of issue&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To resolve, in your &lt;code&gt;ember-cli-build.js&lt;/code&gt;, you want:&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Webpack&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="s1"&gt;@embroider/webpack&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="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;@embroider/compat&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;compatBuild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Webpack&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// ...&lt;/span&gt;
    &lt;span class="na"&gt;staticHelpers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;staticComponents&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="c1"&gt;// ...&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When both of these options are true, there is no more ambiguity with curly syntax (&lt;code&gt;{{ }}&lt;/code&gt;) -- if it exists, it will be either a helper or a component, we don't need to guess at runtime anymore.&lt;/p&gt;

</description>
      <category>ember</category>
      <category>javascript</category>
      <category>modern</category>
    </item>
    <item>
      <title>Setting up Tailwind, the easy way</title>
      <dc:creator>NullVoxPopuli</dc:creator>
      <pubDate>Tue, 24 Oct 2023 20:23:05 +0000</pubDate>
      <link>https://forem.com/nullvoxpopuli/setting-up-tailwind-the-easy-way-5843</link>
      <guid>https://forem.com/nullvoxpopuli/setting-up-tailwind-the-easy-way-5843</guid>
      <description>&lt;p&gt;In the root of your ember app, follow these steps&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;add &lt;code&gt;tailwindcss&lt;/code&gt; to your &lt;code&gt;devDependencies&lt;/code&gt; &lt;/li&gt;
&lt;li&gt;make a &lt;code&gt;config/tailwind&lt;/code&gt; folder&lt;/li&gt;
&lt;li&gt;copy &lt;a href="https://github.com/NullVoxPopuli/ember-apply/tree/main/packages/ember/tailwind/files" rel="noopener noreferrer"&gt;these files&lt;/a&gt; to a your &lt;code&gt;config/tailwind&lt;/code&gt; folder.&lt;/li&gt;
&lt;li&gt;add &lt;code&gt;&amp;lt;link integrity="" rel="stylesheet" href="{{rootURL}}assets/tailwind.css"&amp;gt;&lt;/code&gt; in your app/index.html&lt;/li&gt;
&lt;li&gt;add &lt;code&gt;&amp;lt;link rel="stylesheet" href="{{rootURL}}assets/tailwind.css"&amp;gt;&lt;/code&gt; in your tests/index.html&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;add two package.json scripts:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;tailwind:build&lt;/span&gt;&lt;span class="dl"&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;npx tailwindcss -c ./config/tailwind/tailwind.config.js -i ./config/tailwind/tailwind-input.css -o ./public/assets/tailwind.css&lt;/span&gt;&lt;span class="dl"&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;tailwind:watch&lt;/span&gt;&lt;span class="dl"&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;npx tailwindcss -c ./config/tailwind/tailwind.config.js -i ./config/tailwind/tailwind-input.css -o ./public/assets/tailwind.css --watch&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;change your build script&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"build": "npm run tailwind:build &amp;amp;&amp;amp; ember build --environment=production"
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;add &lt;code&gt;public/assets/tailwind.css&lt;/code&gt; to your .gitignore file.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;🥳 You did it! you're done now!&lt;/p&gt;

&lt;p&gt;When you run your app (or build it), you'll run &lt;code&gt;tailwind:build&lt;/code&gt; or `tailwind:watch' along with your app&lt;/p&gt;




&lt;p&gt;or, if you have node 18+, you can automate all this with &lt;code&gt;npx ember-apply tailwind&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Note that this is an automation of what the &lt;a href="https://tailwindcss.com/docs/installation" rel="noopener noreferrer"&gt;Tailwind CLI&lt;/a&gt; documentation guides you through (and what the above 6 steps have you do as well)&lt;/p&gt;

</description>
      <category>ember</category>
      <category>javascript</category>
      <category>tailwindcss</category>
    </item>
  </channel>
</rss>
