PageSourceSearch

https://shakacode.com/component---src-template-doc-article-tsx-con…ebpack-to-rspack-md-015fe0b8733e572f59d7.js

js shakacode.com collected 2026-10-04 00:25:19 UTC 83,218 bytes, 2 lines download raw bytes

1"use strict";(self.webpackChunkgatsby_starter_default=self.webpackChunkgatsby_starter_default||[]).push([[728],{38811:function(n,e,a){a.r(e),a.d(e,{Head:function(){return h},default:function(){return k}});var s=a(28453),t=a(96540);function o(n){const e=Object.assign({h1:"h1",a:"a",span:"span",p:"p",h2:"h2",ul:"ul",li:"li",h3:"h3",strong:"strong",blockquote:"blockquote",ol:"ol"},(0,s.R)(),n.components);return t.createElement(t.Fragment,null,t.createElement(e.h1,{id:"migrating-from-webpack-to-rspack",style:{position:"relative"}},t.createElement(e.a,{href:"#migrating-from-webpack-to-rspack","aria-label":"migrating from webpack to rspack permalink",className:"anchor before"},t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" height="20" version="1.1" viewBox="0 0 16 16" width="20"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}})),"Migrating from Webpack to Rspack"),"\n",t.createElement(e.p,null,"This guide documents the process of migrating from Webpack to Rspack using Shakapacker 9+. Rspack is a high-performance bundler written in Rust that provides significantly faster builds (~20x improvement) while maintaining Webpack API compatibility."),"\n",t.createElement(e.h2,{id:"prerequisites",style:{position:"relative"}},t.createElement(e.a,{href:"#prerequisites","aria-label":"prerequisites permalink",className:"anchor before"},t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" height="20" version="1.1" viewBox="0 0 16 16" width="20"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}})),"Prerequisites"),"\n",t.createElement(e.ul,null,"\n",t.createElement(e.li,null,"Shakapacker 9.0+ (Rspack support was added in 9.0)"),"\n",t.createElement(e.li,null,"Node.js 20+"),"\n",t.createElement(e.li,null,"React on Rails 13+"),"\n"),"\n",t.createElement(e.h2,{id:"quick-start",style:{position:"relative"}},t.createElement(e.a,{href:"#quick-start","aria-label":"quick start permalink",className:"anchor before"},t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" height="20" version="1.1" viewBox="0 0 16 16" width="20"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}})),"Quick Start"),"\n",t.createElement(e.p,null,"For new projects or simple migrations, the generator handles most of the setup:"),"\n",t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<div class="gatsby-highlight" data-language="bash"><pre class="language-bash"><code class="language-bash"><span class="token comment"># Generate with Rspack from scratch</span>\nrails generate react_on_rails:install <span class="token parameter variable">--rspack</span>\n\n<span class="token comment"># Or switch an existing app</span>\nbin/switch-bundler rspack</code></pre></div>'}}),"\n",t.createElement(e.p,null,"For complex projects with SSR, CSS Modules, or custom configurations, continue reading for important considerations."),"\n",t.createElement(e.h2,{id:"breaking-changes-in-shakapacker-9",style:{position:"relative"}},t.createElement(e.a,{href:"#breaking-changes-in-shakapacker-9","aria-label":"breaking changes in shakapacker 9 permalink",className:"anchor before"},t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" height="20" version="1.1" viewBox="0 0 16 16" width="20"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}})),"Breaking Changes in Shakapacker 9"),"\n",t.createElement(e.h3,{id:"css-modules-named-vs-default-exports",style:{position:"relative"}}
1,t.createElement(e.a,{href:"#css-modules-named-vs-default-exports","aria-label":"css modules named vs default exports permalink",className:"anchor before"},t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" height="20" version="1.1" viewBox="0 0 16 16" width="20"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}})),"CSS Modules: Named vs Default Exports"),"\n",t.createElement(e.p,null,t.createElement(e.strong,null,"This is the most critical breaking change.")," Shakapacker 9 changed the default CSS Modules configuration from default exports to named exports (",t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">namedExport: true</code>'}}),")."),"\n",t.createElement(e.p,null,t.createElement(e.strong,null,"Symptoms:")),"\n",t.createElement(e.ul,null,"\n",t.createElement(e.li,null,"CSS modules returning ",t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">undefined</code>'}})),"\n",t.createElement(e.li,null,"SSR errors: ",t.createElement(e.span,{dangerouslySetInnerHTML:{__html:"<code class=\"language-text\">Cannot read properties of undefined (reading 'className')</code>"}})),"\n",t.createElement(e.li,null,"Build warnings: ",t.createElement(e.span,{dangerouslySetInnerHTML:{__html:"<code class=\"language-text\">export 'default' (imported as 'css') was not found</code>"}})),"\n"),"\n",t.createElement(e.p,null,t.createElement(e.strong,null,"Affected code pattern:")),"\n",t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<div class="gatsby-highlight" data-language="javascript"><pre class="language-javascript"><code class="language-javascript"><span class="token comment">// This pattern breaks with Shakapacker 9 defaults</span>\n<span class="token keyword">import</span> css <span class="token keyword">from</span> <span class="token string">\'./Component.module.scss\'</span><span class="token punctuation">;</span>\nconsole<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>css<span class="token punctuation">.</span>myClass<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// undefined!</span></code></pre></div>'}}),"\n",t.createElement(e.p,null,t.createElement(e.strong,null,"Solution:")," Configure CSS loader to use default exports in your webpack configuration:"),"\n",t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<div class="gatsby-highlight" data-language="javascript"><pre class="language-javascript"><code class="language-javascript"><span class="token comment">// config/webpack/commonWebpackConfig.js</span>\n<span class="token keyword">const</span> <span class="token punctuation">{</span> generateWebpackConfig<span class="token punctuation">,</span> merge <span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">\'shakapacker\'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n\n<span class="token keyword">const</span> <span class="token function-variable function">commonWebpackConfig</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span>\n  <span class="token keyword">const</span> baseWebpackConfig <span class="token operator">=</span> <span class="token function">generateWebpackConfig</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n\n  <span class="token comment">// Fix CSS modules to use default exports for backward compatibility</span>\n  baseWebpackConfig<span class="token punctuation">.</span>module<span class="token punctuation">.</span>rules<span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">rule</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span>\n    <span class="token keyword">if</span> <span class="token punctuation">(</span>
1rule<span class="token punctuation">.</span>use <span class="token operator">&amp;&amp;</span> Array<span class="token punctuation">.</span><span class="token function">isArray</span><span class="token punctuation">(</span>rule<span class="token punctuation">.</span>use<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>\n      <span class="token keyword">const</span> cssLoader <span class="token operator">=</span> rule<span class="token punctuation">.</span>use<span class="token punctuation">.</span><span class="token function">find</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">loader</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span>\n        <span class="token keyword">const</span> loaderName <span class="token operator">=</span> <span class="token keyword">typeof</span> loader <span class="token operator">===</span> <span class="token string">\'string\'</span> <span class="token operator">?</span> loader <span class="token operator">:</span> loader<span class="token operator">?.</span>loader<span class="token punctuation">;</span>\n        <span class="token keyword">return</span> loaderName<span class="token operator">?.</span><span class="token function">includes</span><span class="token punctuation">(</span><span class="token string">\'css-loader\'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n      <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n\n      <span class="token keyword">if</span> <span class="token punctuation">(</span>cssLoader<span class="token operator">?.</span>options<span class="token operator">?.</span>modules<span class="token punctuation">)</span> <span class="token punctuation">{</span>\n        cssLoader<span class="token punctuation">.</span>options<span class="token punctuation">.</span>modules<span class="token punctuation">.</span>namedExport <span class="token operator">=</span> <span class="token boolean">false</span><span class="token punctuation">;</span>\n        cssLoader<span class="token punctuation">.</span>options<span class="token punctuation">.</span>modules<span class="token punctuation">.</span>exportLocalsConvention <span class="token operator">=</span> <span class="token string">\'camelCase\'</span><span class="token punctuation">;</span>\n      <span class="token punctuation">}</span>\n    <span class="token punctuation">}</span>\n  <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n\n  <span class="token keyword">return</span> baseWebpackConfig<span class="token punctuation">;</span>\n<span class="token punctuation">}</span><span class="token punctuation">;</span>\n\nmodule<span class="token punctuation">.</span>exports <span class="token operator">=</span> commonWebpackConfig<span class="token punctuation">;</span></code></pre></div>'}}),"\n",t.createElement(e.p,null,t.createElement(e.strong,null,"Key insight:")," This configuration must be inside the function so it applies to a fresh config each time."),"\n",t.createElement(e.h2,{id:"rspack-specific-configuration",style:{position:"relative"}},t.createElement(e.a,{href:"#rspack-specific-configuration","aria-label":"rspack specific configuration permalink",className:"anchor before"},t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" height="20" version="1.1" viewBox="0 0 16 16" width="20"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}})),"Rspack-Specific Configuration"),"\n",t.createElement(e.h3,{id:"bundler-auto-detection-pattern",style:{position:"relative"}}
1,t.createElement(e.a,{href:"#bundler-auto-detection-pattern","aria-label":"bundler auto detection pattern permalink",className:"anchor before"},t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" height="20" version="1.1" viewBox="0 0 16 16" width="20"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}})),"Bundler Auto-Detection Pattern"),"\n",t.createElement(e.p,null,"Use conditional logic to support both Webpack and Rspack in the same configuration files:"),"\n",t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<div class="gatsby-highlight" data-language="javascript"><pre class="language-javascript"><code class="language-javascript"><span class="token comment">// config/webpack/commonWebpackConfig.js</span>\n<span class="token keyword">const</span> <span class="token punctuation">{</span> config <span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">\'shakapacker\'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n\n<span class="token comment">// Auto-detect bundler from shakapacker config</span>\n<span class="token keyword">const</span> bundler <span class="token operator">=</span> config<span class="token punctuation">.</span>assets_bundler <span class="token operator">===</span> <span class="token string">\'rspack\'</span> <span class="token operator">?</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">\'@rspack/core\'</span><span class="token punctuation">)</span> <span class="token operator">:</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">\'webpack\'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n\n<span class="token comment">// Use for plugins that need the bundler reference</span>\nclientConfig<span class="token punctuation">.</span>plugins<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span>\n  <span class="token keyword">new</span> <span class="token class-name">bundler<span class="token punctuation">.</span>ProvidePlugin</span><span class="token punctuation">(</span><span class="token punctuation">{</span>\n    <span class="token comment">/* ... */</span>\n  <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">,</span>\n<span class="token punctuation">)</span><span class="token punctuation">;</span>\nserverConfig<span class="token punctuation">.</span>plugins<span class="token punctuation">.</span><span class="token function">unshift</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">bundler<span class="token punctuation">.</span>optimize<span class="token punctuation">.</span>LimitChunkCountPlugin</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">maxChunks</span><span class="token operator">:</span> <span class="token number">1</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre></div>'}}),"\n",t.createElement(e.p,null,t.createElement(e.strong,null,"Benefits:")),"\n",t.createElement(e.ul,null,"\n",t.createElement(e.li,null,"Single codebase for both bundlers"),"\n",t.createElement(e.li,null,"Easy to compare configurations"),"\n",t.createElement(e.li,null,"Clear visibility of bundler-specific differences"),"\n"),"\n",t.createElement(e.h3,{id:"server-bundle-css-extract-plugin-filtering",style:{position:"relative"}}
1,t.createElement(e.a,{href:"#server-bundle-css-extract-plugin-filtering","aria-label":"server bundle css extract plugin filtering permalink",className:"anchor before"},t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" height="20" version="1.1" viewBox="0 0 16 16" width="20"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}})),"Server Bundle: CSS Extract Plugin Filtering"),"\n",t.createElement(e.p,null,"Rspack uses a different CSS extract loader path than Webpack. Server-side rendering configs that filter out CSS extraction must handle both:"),"\n",t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<div class="gatsby-highlight" data-language="javascript"><pre class="language-javascript"><code class="language-javascript"><span class="token comment">// config/webpack/serverWebpackConfig.js</span>\n<span class="token keyword">const</span> <span class="token function-variable function">configureServer</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">serverWebpackConfig</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span>\n  serverWebpackConfig<span class="token punctuation">.</span>module<span class="token punctuation">.</span>rules<span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">rule</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span>\n    <span class="token keyword">if</span> <span class="token punctuation">(</span>
1rule<span class="token punctuation">.</span>use <span class="token operator">&amp;&amp;</span> Array<span class="token punctuation">.</span><span class="token function">isArray</span><span class="token punctuation">(</span>rule<span class="token punctuation">.</span>use<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>\n      <span class="token comment">// Filter out CSS extraction loaders for SSR</span>\n      rule<span class="token punctuation">.</span>use <span class="token operator">=</span> rule<span class="token punctuation">.</span>use<span class="token punctuation">.</span><span class="token function">filter</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">item</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span>\n        <span class="token keyword">let</span> testValue<span class="token punctuation">;</span>\n        <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">typeof</span> item <span class="token operator">===</span> <span class="token string">\'string\'</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>\n          testValue <span class="token operator">=</span> item<span class="token punctuation">;</span>\n        <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">typeof</span> item<span class="token punctuation">.</span>loader <span class="token operator">===</span> <span class="token string">\'string\'</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>\n          testValue <span class="token operator">=</span> item<span class="token punctuation">.</span>loader<span class="token punctuation">;</span>\n        <span class="token punctuation">}</span>\n\n        <span class="token comment">// Handle both Webpack and Rspack CSS extract loaders</span>\n        <span class="token keyword">return</span> <span class="token operator">!</span><span class="token punctuation">(</span>\n          testValue<span class="token operator">?.</span><span class="token function">match</span><span class="token punctuation">(</span><span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">mini-css-extract-plugin</span><span class="token regex-delimiter">/</span></span><span class="token punctuation">)</span> <span class="token operator">||</span>\n          testValue<span class="token operator">?.</span><span class="token function">includes</span><span class="token punctuation">(</span><span class="token string">\'cssExtractLoader\'</span><span class="token punctuation">)</span> <span class="token operator">||</span> <span class="token comment">// Rspack uses this path</span>\n          testValue <span class="token operator">===</span> <span class="token string">\'style-loader\'</span>\n        <span class="token punctuation">)</span><span class="token punctuation">;</span>\n      <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n    <span class="token punctuation">}</span>\n  <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n<span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre></div>'}}),"\n",t.createElement(e.p,null,t.createElement(e.strong,null,"Why this matters:")," Rspack uses ",t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">@rspack/core/dist/cssExtractLoader.js</code>'}})," instead of Webpack's ",t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">mini-css-extract-plugin</code>'}}),". Without this fix, CSS extraction remains in the server bundle, causing intermittent SSR failures."),"\n",t.createElement(e.h3,{id:"css-modules-with-ssr-stable-class-names",style:{position:"relative"}}
1,t.createElement(e.a,{href:"#css-modules-with-ssr-stable-class-names","aria-label":"css modules with ssr stable class names permalink",className:"anchor before"},t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" height="20" version="1.1" viewBox="0 0 16 16" width="20"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}})),"CSS Modules with SSR: Stable Class Names"),"\n",t.createElement(e.p,null,t.createElement(e.strong,null,"If you use ",t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">[contenthash]</code>'}})," in your ",t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">localIdentName</code>'}})," for CSS modules, class names can silently diverge between client and server builds with Rspack.")," Pages load but all CSS module styles are broken. This only affects production builds — development with HMR works fine because ",t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">style-loader</code>'}})," injects CSS inline."),"\n",t.createElement(e.p,null,"The root cause is that ",t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">[contenthash]</code>'}})," is computed from processed CSS content, which differs between client and server builds due to different loader chains (",t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">exportOnlyLocals: true</code>'}})," on server), different plugins (",t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">CssExtractRspackPlugin</code>'}})," on client only), and different optimization passes."),"\n",t.createElement(e.p,null,t.createElement(e.strong,null,"Solution:")," Replace ",t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">[contenthash]</code>'}})," with a custom ",t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">getLocalIdent</code>'}})," function that derives class names from stable inputs (file path, query string, and class name):"),"\n",t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<div class="gatsby-highlight" data-language="javascript"><pre class="language-javascript"><code class="language-javascript"><span class="token comment">// config/webpack/getLocalIdent.js</span>\n<span class="token keyword">const</span> crypto <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">\'crypto\'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n<span class="token keyword">const</span> path <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">\'path\'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n\n<span class="token keyword">const</span> <span class="token function-variable function">getLocalIdent</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">context<span class="token punctuation">,</span> _localIdentName<span class="token punctuation">,</span> localName</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span>\n  <span class="token keyword">const</span> resourcePath <span class="token operator">=</span> context<span class="token punctuation">.</span>resourcePath<span class="token punctuation">;</span>\n  <span class="token keyword">const</span> resourceQuery <span class="token operator">=</span> context<span class="token punctuation">.</span>resourceQuery <span class="token operator">||</span> <span class="token string">\'\'</span><span class="token punctuation">;</span> <span class="token comment">// needed for CSS-in-JS virtual modules; safe no-op otherwise</span>\n  <span class="token comment">
1// Prefer process.cwd() so this stays correct across custom/monorepo layouts.</span>\n  <span class="token keyword">const</span> projectRoot <span class="token operator">=</span> process<span class="token punctuation">.</span><span class="token function">cwd</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n  <span class="token comment">// Alternative if process.cwd() isn\'t reliable in your setup:</span>\n  <span class="token comment">// const projectRoot = path.resolve(__dirname, \'../..\'); // adjust depth as needed</span>\n  <span class="token keyword">const</span> relativePath <span class="token operator">=</span> path<span class="token punctuation">.</span><span class="token function">relative</span><span class="token punctuation">(</span>projectRoot<span class="token punctuation">,</span> resourcePath<span class="token punctuation">)</span><span class="token punctuation">;</span>\n\n  <span class="token keyword">const</span> hash <span class="token operator">=</span> crypto\n    <span class="token punctuation">.</span><span class="token function">createHash</span><span class="token punctuation">(</span><span class="token string">\'sha256\'</span><span class="token punctuation">)</span>\n    <span class="token punctuation">.</span><span class="token function">update</span><span class="token punctuation">(</span>relativePath <span class="token operator">+</span> <span class="token string">\'\\0\'</span> <span class="token operator">+</span> resourceQuery <span class="token operator">+</span> <span class="token string">\'\\0\'</span> <span class="token operator">+</span> localName<span class="token punctuation">)</span>\n    <span class="token punctuation">.</span><span class="token function">digest</span><span class="token punctuation">(</span><span class="token string">\'base64url\'</span><span class="token punctuation">)</span>\n    <span class="token punctuation">.</span><span class="token function">slice</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">8</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n\n  <span class="token keyword">const</span> basename <span class="token operator">=</span> path<span class="token punctuation">.</span><span class="token function">basename</span><span class="token punctuation">(</span>resourcePath<span class="token punctuation">)</span><span class="token punctuation">;</span>\n  <span class="token keyword">const</span> name <span class="token operator">=</span> basename\n    <span class="token punctuation">.</span><span class="token function">replace</span><span class="token punctuation">(</span><span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">\\.(module\\.)?(scss|sass|css|less|styl|tsx?|jsx?)$</span><span class="token regex-delimiter">/</span></span><span class="token punctuation">,</span> <span class="token string">\'\'</span><span class="token punctuation">)</span>\n    <span class="token punctuation">.</span><span class="token function">replace</span><span class="token punctuation">(</span><span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">-styles$</span><span class="token regex-delimiter">/</span></span><span class="token punctuation">,</span> <span class="token string">\'\'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n  <span class="token keyword">return</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>name<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">-</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>localName<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">_</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>hash<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">;</span>\n<span class="token punctuation">}</span><span class="token punctuation">;</span>\n\nmodule<span class="token punctuation">.</span>exports <span class="token operator">=</span> getLocalIdent<span class="token punctuation">;</span></code></pre></div>'}}),"\n",t.createElement(e.p,null,"For third-party CSS modules, ",t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">relativePath</code>'}})," may include ",t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">node_modules/</code>'}})," segments in the hash input. That's expected and stable; the visible class name prefix still comes from ",t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">path.basename(resourcePath)</code>'}}),"."),"\n",t.createElement(e.p,null,"Then use it in your ",t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">commonWebpackConfig.js</code>'}})," where you configure CSS modules:"),"\n",t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<div class="gatsby-highlight" data-language="javascript"><pre class="language-javascript"><code class="language-javascript"><span class="token keyword">const</span> getLocalIdent <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">\'./getLocalIdent\'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n\n<span class="token comment">// In the CSS modules configuration loop:</span>\n<span class="token keyword">if</span> <span class="token punctuation">(</span>cssLoader<span class="token operator">?.</span>options<span class="token operator">?.</span>modules<span class="token punctuation">)</span> <span class="token punctuation">{</span>\n  cssLoader<span class="token punctuation">.</span>options<span class="token punctuation">.</span>modules<span class="token punctuation">.</span>namedExport <span class="token operator">=</span> <span class="token boolean">
1false</span><span class="token punctuation">;</span>\n  cssLoader<span class="token punctuation">.</span>options<span class="token punctuation">.</span>modules<span class="token punctuation">.</span>exportLocalsConvention <span class="token operator">=</span> <span class="token string">\'camelCase\'</span><span class="token punctuation">;</span>\n  cssLoader<span class="token punctuation">.</span>options<span class="token punctuation">.</span>modules<span class="token punctuation">.</span>getLocalIdent <span class="token operator">=</span> getLocalIdent<span class="token punctuation">;</span> <span class="token comment">// Stable class names across builds</span>\n<span class="token punctuation">}</span></code></pre></div>'}}),"\n",t.createElement(e.p,null,"Because ",t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">getLocalIdent</code>'}})," uses stable inputs (file path, query string, and class name) rather than processed CSS content, the same class name is produced in both client and server builds regardless of bundler internals. The same function must be used in both builds so server-rendered HTML class names match client CSS selectors."),"\n",t.createElement(e.blockquote,null,"\n",t.createElement(e.p,null,t.createElement(e.strong,null,"Note — CSS-in-JS virtual modules (astroturf, etc.):")," The ",t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">resourceQuery</code>'}})," line in ",t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">getLocalIdent</code>'}})," above is a no-op for regular ",t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">.module.scss</code>'}})," files. It exists for CSS-in-JS tools that create virtual CSS modules via webpack's ",t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">!=!</code>'}})," matchResource syntax. In rspack, ",t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">context.resourcePath</code>'}})," points to the source file rather than the virtual path, so without ",t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">resourceQuery</code>'}})," in the hash, all virtual modules from the same file would collide. See the ",t.createElement(e.a,{href:"#css-in-js-styled-components-all-share-the-same-class-name"},"troubleshooting entry")," for details."),"\n"),"\n",t.createElement(e.h3,{id:"server-bundle-preserve-css-modules-configuration",style:{position:"relative"}},t.createElement(e.a,{href:"#server-bundle-preserve-css-modules-configuration","aria-label":"server bundle preserve css modules configuration permalink",className:"anchor before"},t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" height="20" version="1.1" viewBox="0 0 16 16" width="20"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}})),"Server Bundle: Preserve CSS Modules Configuration"),"\n",t.createElement(e.p,null,"When configuring SSR, merge CSS modules options instead of replacing them:"),"\n",t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<div class="gatsby-highlight" data-language="javascript"><pre class="language-javascript"><code class="language-javascript"><span class="token comment">// ❌ Wrong - overwrites namedExport setting</span>\n<span class="token keyword">if</span> <span class="token punctuation">(</span>cssLoader <span class="token operator">&amp;&amp;</span> cssLoader<span class="token punctuation">.</span>options<span class="token punctuation">)</span> <span class="token punctuation">{</span>\n  cssLoader<span class="token punctuation">.</span>options<span class="token punctuation">.</span>modules <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token literal-property property">exportOnlyLocals</span><span class="token operator">:</span> <span class="token boolean">true</span> <span class="token punctuation">}</span><span class="token punctuation">;</span>\n<span class="token punctuation">}</span>\n\n<span class="token comment">// ✅ Correct - preserves existing settings</span>\n<span class="token keyword">if</span> <span class="token punctuation">(</span>cssLoader <span class="token operator">&amp;&amp;</span> cssLoader<span class="token punctuation">.</span>options <span class="token operator">&amp;&amp;</span> cssLoader<span class="token punctuation">.</span>options<span class="token punctuation">.</span>modules<span class="token punctuation">)</span> <span class="token punctuation">{</span>\n  cssLoader<span class="token punctuation">.</span>options<span class="token punctuation">.</span>modules <span class="token operator">=</span> <span class="token punctuation">{</span>\n    <span class="token operator">...</span>cssLoader<span class="token punctuation">.</span>options<span class="token punctuation">.</span>modules<span class="token punctuation">,</span> <span class="token comment">
1// Preserve namedExport: false</span>\n    <span class="token literal-property property">exportOnlyLocals</span><span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span>\n  <span class="token punctuation">}</span><span class="token punctuation">;</span>\n<span class="token punctuation">}</span></code></pre></div>'}}),"\n",t.createElement(e.h2,{id:"react-runtime-configuration",style:{position:"relative"}},t.createElement(e.a,{href:"#react-runtime-configuration","aria-label":"react runtime configuration permalink",className:"anchor before"},t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" height="20" version="1.1" viewBox="0 0 16 16" width="20"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}})),"React Runtime Configuration"),"\n",t.createElement(e.h3,{id:"swc-react-runtime-for-ssr",style:{position:"relative"}},t.createElement(e.a,{href:"#swc-react-runtime-for-ssr","aria-label":"swc react runtime for ssr permalink",className:"anchor before"},t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" height="20" version="1.1" viewBox="0 0 16 16" width="20"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}})),"SWC React Runtime for SSR"),"\n",t.createElement(e.p,null,"If using SWC (common with Rspack), you may need to use the classic React runtime for SSR compatibility:"),"\n",t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<div class="gatsby-highlight" data-language="javascript"><pre class="language-javascript"><code class="language-javascript"><span class="token comment">// config/swc.config.js</span>\n<span class="token keyword">const</span> customConfig <span class="token operator">=</span> <span class="token punctuation">{</span>\n  <span class="token literal-property property">options</span><span class="token operator">:</span> <span class="token punctuation">{</span>\n    <span class="token literal-property property">jsc</span><span class="token operator">:</span> <span class="token punctuation">{</span>\n      <span class="token literal-property property">transform</span><span class="token operator">:</span> <span class="token punctuation">{</span>\n        <span class="token literal-property property">react</span><span class="token operator">:</span> <span class="token punctuation">{</span>\n          <span class="token literal-property property">runtime</span><span class="token operator">:</span> <span class="token string">\'classic\'</span><span class="token punctuation">,</span> <span class="token comment">// Use \'classic\' instead of \'automatic\' for SSR</span>\n          <span class="token literal-property property">refresh</span><span class="token operator">:</span> env<span class="token punctuation">.</span>isDevelopment <span class="token operator">&amp;&amp;</span> env<span class="token punctuation">.</span>runningWebpackDevServer<span class="token punctuation">,</span>\n        <span class="token punctuation">}</span><span class="token punctuation">,</span>\n      <span class="token punctuation">}</span><span class="token punctuation">,</span>\n    <span class="token punctuation">}</span><span class="token punctuation">,</span>\n  <span class="token punctuation">}</span><span class="token punctuation">,</span>\n<span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre></div>'}}),"\n",t.createElement(e.p,null,t.createElement(e.strong,null,"Symptom:")," SSR error about invalid ",t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">renderToString</code>'}})," call or function signature detection issues."),"\n",t.createElement(e.h2,{id:"additional-configuration",style:{position:"relative"}}
1,t.createElement(e.a,{href:"#additional-configuration","aria-label":"additional configuration permalink",className:"anchor before"},t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" height="20" version="1.1" viewBox="0 0 16 16" width="20"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}})),"Additional Configuration"),"\n",t.createElement(e.h3,{id:"rescript-support",style:{position:"relative"}},t.createElement(e.a,{href:"#rescript-support","aria-label":"rescript support permalink",className:"anchor before"},t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" height="20" version="1.1" viewBox="0 0 16 16" width="20"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}})),"ReScript Support"),"\n",t.createElement(e.p,null,"If using ReScript, add ",t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">.bs.js</code>'}})," to resolve extensions:"),"\n",t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<div class="gatsby-highlight" data-language="javascript"><pre class="language-javascript"><code class="language-javascript"><span class="token comment">// config/webpack/commonWebpackConfig.js</span>\n<span class="token keyword">const</span> commonOptions <span class="token operator">=</span> <span class="token punctuation">{</span>\n  <span class="token literal-property property">resolve</span><span class="token operator">:</span> <span class="token punctuation">{</span>\n    <span class="token literal-property property">extensions</span><span class="token operator">:</span> <span class="token punctuation">[</span><span class="token string">\'.css\'</span><span class="token punctuation">,</span> <span class="token string">\'.ts\'</span><span class="token punctuation">,</span> <span class="token string">\'.tsx\'</span><span class="token punctuation">,</span> <span class="token string">\'.bs.js\'</span><span class="token punctuation">]</span><span class="token punctuation">,</span>\n  <span class="token punctuation">}</span><span class="token punctuation">,</span>\n<span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre></div>'}}),"\n",t.createElement(e.h3,{id:"development-hot-reloading",style:{position:"relative"}},t.createElement(e.a,{href:"#development-hot-reloading","aria-label":"development hot reloading permalink",className:"anchor before"},t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" height="20" version="1.1" viewBox="0 0 16 16" width="20"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}})),"Development Hot Reloading"),"\n",t.createElement(e.p,null,"Different plugins are required for hot reloading:"),"\n",t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<div class="gatsby-highlight" data-language="javascript"><pre class="language-javascript"><code class="language-javascript"><span class="token comment">// config/webpack/development.js</span>\n<span class="token keyword">const</span> <span class="token punctuation">{</span> config <span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">\'shakapacker\'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n\n<span class="token keyword">if</span> <span class="token punctuation">(</span>config<span class="token punctuation">.</span>assets_bundler <span class="token operator">===</span> <span class="token string">\'rspack\'</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>\n  <span class="token keyword">const</span> ReactRefreshPlugin <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">\'@rspack/plugin-react-refresh\'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n  clientWebpackConfig<span class="token punctuation">.</span>plugins<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">ReactRefreshPlugin</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n<span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>\n  <span class="token keyword">const</span> ReactRefreshWebpackPlugin <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">\'@pmmmwh/react-refresh-webpack-plugin\'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n  clientWebpackConfig<span class="token punctuation">.</span>plugins<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">ReactRefreshWebpackPlugin</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>\n<span class="token punctuation">}</span></code></pre></div>'}}),"\n",t.createElement(e.h2,{id:"shakapacker-configuration",style:{position:"relative"}}
1,t.createElement(e.a,{href:"#shakapacker-configuration","aria-label":"shakapacker configuration permalink",className:"anchor before"},t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" height="20" version="1.1" viewBox="0 0 16 16" width="20"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}})),"Shakapacker Configuration"),"\n",t.createElement(e.p,null,"Enable Rspack in ",t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">config/shakapacker.yml</code>'}}),":"),"\n",t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<div class="gatsby-highlight" data-language="yaml"><pre class="language-yaml"><code class="language-yaml"><span class="token key atrule">default</span><span class="token punctuation">:</span> <span class="token important">&amp;default</span>\n  <span class="token key atrule">assets_bundler</span><span class="token punctuation">:</span> <span class="token string">\'rspack\'</span> <span class="token comment"># or \'webpack\'</span>\n  <span class="token key atrule">javascript_transpiler</span><span class="token punctuation">:</span> <span class="token string">\'swc\'</span> <span class="token comment"># Rspack works best with SWC</span></code></pre></div>'}}),"\n",t.createElement(e.h2,{id:"troubleshooting",style:{position:"relative"}},t.createElement(e.a,{href:"#troubleshooting","aria-label":"troubleshooting permalink",className:"anchor before"},t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" height="20" version="1.1" viewBox="0 0 16 16" width="20"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}})),"Troubleshooting"),"\n",t.createElement(e.h3,{id:"css-modules-return-undefined",style:{position:"relative"}},t.createElement(e.a,{href:"#css-modules-return-undefined","aria-label":"css modules return undefined permalink",className:"anchor before"},t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" height="20" version="1.1" viewBox="0 0 16 16" width="20"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}})),"CSS Modules Return ",t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">undefined</code>'}})),"\n",t.createElement(e.p,null,t.createElement(e.strong,null,"Symptoms:")),"\n",t.createElement(e.ul,null,"\n",t.createElement(e.li,null,t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">css.className</code>'}})," is ",t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">undefined</code>'}})),"\n",t.createElement(e.li,null,"SSR crashes with property access errors"),"\n",t.createElement(e.li,null,"Works in development but fails in SSR"),"\n"),"\n",t.createElement(e.p,null,t.createElement(e.strong,null,"Solutions:")),"\n",t.createElement(e.ol,null,"\n",t.createElement(e.li,null,"Configure ",t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">namedExport: false</code>'}})," (see Breaking Changes section)"),"\n",t.createElement(e.li,null,"Ensure server config preserves CSS modules settings"),"\n",t.createElement(e.li,null,"Filter Rspack's ",t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">cssExtractLoader</code>'}})," from server bundle"),"\n"),"\n",t.createElement(e.h3,{id:"css-module-styles-broken-in-production-ssr",style:{position:"relative"}}
1,t.createElement(e.a,{href:"#css-module-styles-broken-in-production-ssr","aria-label":"css module styles broken in production ssr permalink",className:"anchor before"},t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" height="20" version="1.1" viewBox="0 0 16 16" width="20"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}})),"CSS Module Styles Broken in Production (SSR)"),"\n",t.createElement(e.p,null,t.createElement(e.strong,null,"Symptoms:")),"\n",t.createElement(e.ul,null,"\n",t.createElement(e.li,null,"All CSS module styles missing in production"),"\n",t.createElement(e.li,null,"Class names in server-rendered HTML don't match CSS selectors"),"\n",t.createElement(e.li,null,"Works in development but breaks in production builds"),"\n",t.createElement(e.li,null,"No errors — just silently broken styles"),"\n"),"\n",t.createElement(e.p,null,t.createElement(e.strong,null,"Cause:")," ",t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">[contenthash]</code>'}})," in ",t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">localIdentName</code>'}})," produces different hashes in client and server builds with Rspack."),"\n",t.createElement(e.p,null,t.createElement(e.strong,null,"Solution:")," Use a custom ",t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">getLocalIdent</code>'}})," function instead of ",t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">[contenthash]</code>'}}),". See the ",t.createElement(e.a,{href:"#css-modules-with-ssr-stable-class-names"},"CSS Modules with SSR")," section above."),"\n",t.createElement(e.h3,{id:"css-in-js-styled-components-all-share-the-same-class-name",style:{position:"relative"}},t.createElement(e.a,{href:"#css-in-js-styled-components-all-share-the-same-class-name","aria-label":"css in js styled components all share the same class name permalink",className:"anchor before"},t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" height="20" version="1.1" viewBox="0 0 16 16" width="20"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}})),"CSS-in-JS Styled Components All Share the Same Class Name"),"\n",t.createElement(e.p,null,t.createElement(e.strong,null,"Symptoms:")),"\n",t.createElement(e.ul,null,"\n",t.createElement(e.li,null,"Multiple astroturf (or similar CSS-in-JS) styled components in the same file all get identical CSS class names"),"\n",t.createElement(e.li,null,"Styles look correct in development but are broken in production"),"\n",t.createElement(e.li,null,"Only one component's styles survive; others are overwritten"),"\n"),"\n",t.createElement(e.p,null,t.createElement(e.strong,null,"Cause:")," Rspack sets ",t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">context.resourcePath</code>'}})," to the actual source file instead of the virtual matchResource path. All virtual CSS modules from the same source file produce the same hash."),"\n",t.createElement(e.p,null,t.createElement(e.strong,null,"Solution:")," Include ",t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">context.resourceQuery</code>'}})," in the ",t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">getLocalIdent</code>'}})," hash. See the ",t.createElement(e.a,{href:"#css-modules-with-ssr-stable-class-names"},t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">getLocalIdent</code>'}})," implementation")," above, which already includes ",t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">resourceQuery</code>'}})," for this reason."),"\n",t.createElement(e.h3,{id:"intermittent-ssr-failures",style:{position:"relative"}}
1,t.createElement(e.a,{href:"#intermittent-ssr-failures","aria-label":"intermittent ssr failures permalink",className:"anchor before"},t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" height="20" version="1.1" viewBox="0 0 16 16" width="20"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}})),"Intermittent SSR Failures"),"\n",t.createElement(e.p,null,t.createElement(e.strong,null,"Cause:")," Incomplete CSS extraction filtering in server config."),"\n",t.createElement(e.p,null,t.createElement(e.strong,null,"Solution:")," Update the CSS extract loader filter to include ",t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">cssExtractLoader</code>'}})," for Rspack (see Server Bundle section)."),"\n",t.createElement(e.h3,{id:"module-resolution-errors",style:{position:"relative"}},t.createElement(e.a,{href:"#module-resolution-errors","aria-label":"module resolution errors permalink",className:"anchor before"},t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" height="20" version="1.1" viewBox="0 0 16 16" width="20"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}})),"Module Resolution Errors"),"\n",t.createElement(e.p,null,t.createElement(e.strong,null,"Symptom:")," ",t.createElement(e.span,{dangerouslySetInnerHTML:{__html:"<code class=\"language-text\">Module not found: Can't resolve './file.bs.js'</code>"}})),"\n",t.createElement(e.p,null,t.createElement(e.strong,null,"Solution:")," Add the file extension to webpack's resolve.extensions configuration."),"\n",t.createElement(e.h3,{id:"umd-libraries-behave-differently-under-rspacks-module-interop",style:{position:"relative"}},t.createElement(e.a,{href:"#umd-libraries-behave-differently-under-rspacks-module-interop","aria-label":"umd libraries behave differently under rspacks module interop permalink",className:"anchor before"},t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" height="20" version="1.1" viewBox="0 0 16 16" width="20"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}})),"UMD Libraries Behave Differently Under Rspack's Module Interop"),"\n",t.createElement(e.p,null,t.createElement(e.strong,null,"Symptoms:")),"\n",t.createElement(e.ul,null,"\n",t.createElement(e.li,null,t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">noConflict()</code>'}})," or other methods called on an import result return ",t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">undefined</code>'}})," or throw"),"\n",t.createElement(e.li,null,"Libraries that coexist via ",t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">noConflict()</code>'}})," (e.g., lodash + underscore) interfere with each other"),"\n"),"\n",t.createElement(e.p,null,t.createElement(e.strong,null,"Cause:")," Rspack's ES module interop wraps CommonJS exports differently than Webpack, so the import result may not have the methods you expect. Switching to ",t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">window.*</code>'}})," access can also be wrong if loaders like ",t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">imports-loader?define=>false</code>'}})," prevent the library from setting globals in the first place."),"\n",t.createElement(e.p,null,t.createElement(e.strong,null,"Solution:")," Audit any ",t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">noConflict()</code>'}})," calls or UMD workarounds. Check whether your loader chain already prevents the conflict, and remove the workaround if so. Verify behavior b
1y testing in both bundlers."),"\n",t.createElement(e.h3,{id:"modern-entry-points-crash-on-missing-globals",style:{position:"relative"}},t.createElement(e.a,{href:"#modern-entry-points-crash-on-missing-globals","aria-label":"modern entry points crash on missing globals permalink",className:"anchor before"},t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" height="20" version="1.1" viewBox="0 0 16 16" width="20"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}})),"Modern Entry Points Crash on Missing Globals"),"\n",t.createElement(e.p,null,t.createElement(e.strong,null,"Symptoms:")),"\n",t.createElement(e.ul,null,"\n",t.createElement(e.li,null,t.createElement(e.span,{dangerouslySetInnerHTML:{__html:"<code class=\"language-text\">Cannot use 'in' operator to search for 'X' in undefined</code>"}})),"\n",t.createElement(e.li,null,t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">Could not find component registered with name ...</code>'}})," (ReactOnRails registration fails)"),"\n",t.createElement(e.li,null,"Works in development but crashes on specific pages in production"),"\n"),"\n",t.createElement(e.p,null,t.createElement(e.strong,null,"Cause:")," Code in a modern entry point references a global (e.g., ",t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">window._</code>'}}),") that is only exposed via ",t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">expose-loader</code>'}})," in legacy bundles. The crash kills the script before ",t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">registerForRails()</code>'}})," executes, so ReactOnRails reports the component as missing. This bug can be latent under Webpack if legacy bundles happen to load first."),"\n",t.createElement(e.p,null,t.createElement(e.strong,null,"Solution:")," Audit all entry points for code that assumes sitewide globals exist. Remove or guard any such references, especially orphaned polyfills for removed features."),"\n",t.createElement(e.h3,{id:"cache-false-disables-rspacks-in-memory-cache",style:{position:"relative"}},t.createElement(e.a,{href:"#cache-false-disables-rspacks-in-memory-cache","aria-label":"cache false disables rspacks in memory cache permalink",className:"anchor before"},t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" height="20" version="1.1" viewBox="0 0 16 16" width="20"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}})),t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">cache: false</code>'}})," Disables Rspack's In-Memory Cache"),"\n",t.createElement(e.p,null,t.createElement(e.strong,null,"Symptoms:")),"\n",t.createElement(e.ul,null,"\n",t.createElement(e.li,null,'Subtle compilation issues after adding a "disable cache" environment variable'),"\n",t.createElement(e.li,null,"Slower rebuilds than expected even with in-memory caching supposedly enabled"),"\n"),"\n",t.createElement(e.p,null,t.createElement(e.strong,null,"Cause:")," Rspack's top-level ",t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">cache</code>'}})," option is boolean-only (",t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">true</code>'}}),"/",t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">false</code>'}}),"), unlike Webpack's ",t.createElement(e.span,{dangerouslySetInnerHTML:{__html:"<code class=\"language-text\">cache: { type: 'filesystem', buildDependencies: ... }</code>"}}),". Setting ",t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">cache: false</code>'}})," to disable disk persistence actually disables rspack's ",t.createElement(e.strong,null,"in-memory cache")," entirely. Persistent (disk) caching is controlled separately via ",t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">experiments.cache</code>'}}),"."),"\n",t.createElement(e.p,null,t.createElement(e.strong,null,"Solution:")," Always set ",t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">cache: true</code>'}})," for rspack. Control disk persistence exclusively through ",t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">experiments.cache</code>'}}),":"),"\n",t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<div class="gatsby-highlight" data-language="javascript"><pre class="language-javascript"><code class="language-javascript"><span class="token literal-property property">
1cache</span><span class="token operator">:</span> isRspack\n  <span class="token operator">?</span> <span class="token boolean">true</span> <span class="token comment">// always enable in-memory cache; disk persistence via experiments.cache</span>\n  <span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token literal-property property">type</span><span class="token operator">:</span> <span class="token string">\'filesystem\'</span><span class="token punctuation">,</span> <span class="token literal-property property">buildDependencies</span><span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token literal-property property">config</span><span class="token operator">:</span> <span class="token punctuation">[</span>__filename<span class="token punctuation">]</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">,</span>\n\n<span class="token comment">// Persistent cache (disk) — opt-in for rspack</span>\n<span class="token operator">...</span><span class="token punctuation">(</span>isRspack <span class="token operator">&amp;&amp;</span> <span class="token operator">!</span>process<span class="token punctuation">.</span>env<span class="token punctuation">.</span><span class="token constant">DISABLE_FILESYS_CACHE</span> <span class="token operator">&amp;&amp;</span> <span class="token punctuation">{</span>\n  <span class="token literal-property property">experiments</span><span class="token operator">:</span> <span class="token punctuation">{</span>\n    <span class="token literal-property property">cache</span><span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token literal-property property">type</span><span class="token operator">:</span> <span class="token string">\'persistent\'</span><span class="token punctuation">,</span> <span class="token literal-property property">buildDependencies</span><span class="token operator">:</span> <span class="token punctuation">[</span>__filename<span class="token punctuation">]</span> <span class="token punctuation">}</span><span class="token punctuation">,</span>\n  <span class="token punctuation">}</span><span class="token punctuation">,</span>\n<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">,</span></code></pre></div>'}}),"\n",t.createElement(e.h3,{id:"lazy-compilation-breaks-two-server-dev-setup",style:{position:"relative"}},t.createElement(e.a,{href:"#lazy-compilation-breaks-two-server-dev-setup","aria-label":"lazy compilation breaks two server dev setup permalink",className:"anchor before"},t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" height="20" version="1.1" viewBox="0 0 16 16" width="20"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}})),"Lazy Compilation Breaks Two-Server Dev Setup"),"\n",t.createElement(e.p,null,t.createElement(e.strong,null,"Symptoms:")),"\n",t.createElement(e.ul,null,"\n",t.createElement(e.li,null,"Dynamic imports fail silently in development"),"\n",t.createElement(e.li,null,"Network tab shows 404s for ",t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">/lazy-compilation-using-__&lt;N></code>'}})," paths hitting your Rails server"),"\n",t.createElement(e.li,null,"Entry points fail to load with no obvious error"),"\n"),"\n",t.createElement(e.p,null,t.createElement(e.strong,null,"Cause:")," Rspack's CLI ",t.createElement(e.a,{href:"https://github.com/web-infra-dev/rspack/blob/main/packages/rspack-cli/src/commands/serve.ts#L130-L133"},"auto-enables lazy compilation")," for web targets when using ",t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">rspack serve</code>'}}),". The lazy-compilation proxy uses relative URLs, so the browser resolves them against the page origin (your Rails server) instead of the dev server where the middleware lives. Webpack doesn't auto-enable this, so it's an invisible behavior change."),"\n",t.createElement(e.p,null,t.createElement(e.strong,null,"Solution:")," Explicitly disable lazy compilation:"),"\n",t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<div class="gatsby-highlight" data-language="javascript"><pre class="language-javascript"><code class="language-javascript"><span class="token operator">...</span><span class="token punctuation">(</span>isRspack <span class="token operator">&amp;&amp;</span> <span class="token punctuation">{</span> <span class="token literal-property property">lazyCompilation</span><span class="token operator">:</span> <span class="token boolean">
1false</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">,</span></code></pre></div>'}}),"\n",t.createElement(e.p,null,"Alternatively, configure ",t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">lazyCompilation.backend.listen</code>'}})," to match your dev server setup."),"\n",t.createElement(e.h3,{id:"third-party-package-issues",style:{position:"relative"}},t.createElement(e.a,{href:"#third-party-package-issues","aria-label":"third party package issues permalink",className:"anchor before"},t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" height="20" version="1.1" viewBox="0 0 16 16" width="20"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}})),"Third-Party Package Issues"),"\n",t.createElement(e.p,null,"Some packages may not ship compiled files. Use ",t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<code class="language-text">patch-package</code>'}})," to fix:"),"\n",t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<div class="gatsby-highlight" data-language="bash"><pre class="language-bash"><code class="language-bash"><span class="token function">pnpm</span> <span class="token function">add</span> --save-dev patch-package postinstall-postinstall</code></pre></div>'}}),"\n",t.createElement(e.p,null,"Add to package.json:"),"\n",t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<div class="gatsby-highlight" data-language="json"><pre class="language-json"><code class="language-json"><span class="token punctuation">{</span>\n  <span class="token property">"scripts"</span><span class="token operator">:</span> <span class="token punctuation">{</span>\n    <span class="token property">"postinstall"</span><span class="token operator">:</span> <span class="token string">"patch-package"</span>\n  <span class="token punctuation">}</span>\n<span class="token punctuation">}</span></code></pre></div>'}}),"\n",t.createElement(e.h2,{id:"performance-benefits",style:{position:"relative"}},t.createElement(e.a,{href:"#performance-benefits","aria-label":"performance benefits permalink",className:"anchor before"},t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" height="20" version="1.1" viewBox="0 0 16 16" width="20"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}})),"Performance Benefits"),"\n",t.createElement(e.p,null,"After migration, expect:"),"\n",t.createElement(e.ul,null,"\n",t.createElement(e.li,null,t.createElement(e.strong,null,"Build times:")," ~53-270ms with Rspack (vs seconds with Webpack)"),"\n",t.createElement(e.li,null,t.createElement(e.strong,null,"~20x faster transpilation")," with SWC"),"\n",t.createElement(e.li,null,t.createElement(e.strong,null,"Faster CI runs")," and development iteration"),"\n"),"\n",t.createElement(e.h2,{id:"reference-implementation",style:{position:"relative"}},t.createElement(e.a,{href:"#reference-implementation","aria-label":"reference implementation permalink",className:"anchor before"},t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" height="20" version="1.1" viewBox="0 0 16 16" width="20"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}})),"Reference Implementation"),"\n",t.createElement(e.p,null,"For a complete working example, see the ",t.createElement(e.a,{href:"https://github.com/shakacode/react-webpack-rails-tutorial/pull/680"},"react-webpack-rails-tutorial Rspack migration PR"),"."),"\n",t.createElement(e.h2,{id:"related-documentation",style:{position:"relative"}}
1,t.createElement(e.a,{href:"#related-documentation","aria-label":"related documentation permalink",className:"anchor before"},t.createElement(e.span,{dangerouslySetInnerHTML:{__html:'<svg aria-hidden="true" height="20" version="1.1" viewBox="0 0 16 16" width="20"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>'}})),"Related Documentation"),"\n",t.createElement(e.ul,null,"\n",t.createElement(e.li,null,t.createElement(e.a,{href:"/linked-assets/e72e5d49cb555fd964cbc7e46abdb41b/webpack-configuration.md"},"Webpack Configuration")," - Rspack vs Webpack overview"),"\n",t.createElement(e.li,null,t.createElement(e.a,{href:"/linked-assets/54e45a146503a9194b6540e0b1fa8747/react-server-rendering.md"},"Server-Side Rendering")," - SSR configuration"),"\n",t.createElement(e.li,null,t.createElement(e.a,{href:"/linked-assets/84e0ce93d0c37952eac8de9289f9e3d1/troubleshooting.md"},"Troubleshooting Guide")," - General troubleshooting"),"\n"))}var l=function(n){void 0===n&&(n={});const{wrapper:e}=Object.assign({},(0,s.R)(),n.components);return e?t.createElement(e,n,t.createElement(o,n)):o(n)},c=a(63679),p=a(95197),r=a(47388),i=a(23690),u=a(14487);const d=c.default.p.withConfig({displayName:"doc-article__RedirectFallback",componentId:"sc-tic2w5-0"})(["padding:2rem;"]),m=n=>{let{data:e,location:a,children:s}=n;const{headings:o}=e.article.childMdx,l=(0,p.X9)(a.pathname),[c,i]=t.useState(null),m=a.pathname.split("/"),k=m.indexOf("docs"),h=-1===k?a.pathname.length:m.slice(0,k+1).join("/").length,g=a.pathname.slice(0,h),f=a.pathname.slice(h+1).replace(/\/$/,"").split("/").filter((n=>""!==n)),v=f.length>1?f.slice(0,-1).join("/"):"";t.useEffect((()=>{if(!l)return;const{hash:n}=window.location;i(n);const e=""+l+n;window.location.href!==e&&window.location.replace(e)}),[l]);const S=null===l||null===c?null:""+l+c;return t.createElement(t.Fragment,null,null!==S?t.createElement(d,{role:"status","aria-live":"polite"},"Redirecting..."," ",t.createElement("a",{href:S,target:"_blank",rel:"noopener noreferrer"},"Click here if not redirected.")):t.createElement(r.A,{main:t.createElement(u.A,{body:s,headings:o,transformUrl:n=>{if(n.startsWith("http")||n.startsWith("#"))return n;const e=n.replace(/\.md$/,"/");if(e.startsWith("./"))return g+(""===v?"":"/"+v)+e.slice(1);if(e.startsWith("../")){if(""===v)return""+g+e.slice(2);const n=v.split("/").slice(0,-1).join("/");return g+(""===n?"":"/"+n)+e.slice(2)}return g+"/"+(""===v?"":v+"/")+e}})}))};function k(n){return t.createElement(m,n,t.createElement(l,n))}const h=n=>{let{data:e,location:a,pageContext:s}=n;const{headings:o}=e.article.childMdx,{siteUrl:l}=e.site.siteMetadata,{repoDisplayName:c}=s,r=o.find((n=>1===n.depth)),u=(0,p.X9)(a.pathname)||""+l.replace(/\/+$/,"")+a.pathname;return t.createElement(i.A,{title:r?r.value:c,description:r?r.value:c+" documentation",isArticle:!0,canonical:u,pathname:a.pathname})}}}]);
2//# sourceMappingURL=component---src-template-doc-article-tsx-content-file-path-cache-gatsby-source-git-react-on-rails-docs-oss-migrating-migrating-from-webpack-to-rspack-md-015fe0b8733e572f59d7.js.map

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.