PageSourceSearch

https://peterbeshai.com/blog/2020-10-22-cra-snowpack/

html peterbeshai.com collected 2026-09-25 21:04:13 UTC 44,971 bytes, 139 lines download raw bytes

1<!DOCTYPE html><html lang="en"><head><meta charSet="utf-8"/><meta http-equiv="x-ua-compatible" content="ie=edge"/><meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"/><style data-href="/styles.a6cf05b5abeb1d21fb12.css">/* ! tailwindcss v2.1.2 | MIT License | https://tailwindcss.com */
2
3/*! modern-normalize v1.1.0 | MIT License | https://github.com/sindresorhus/modern-normalize */html{-moz-tab-size:4;-o-tab-size:4;tab-size:4;line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0;font-family:system-ui,-apple-system,Segoe UI,Roboto,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji}hr{height:0;color:inherit}abbr[title]{-webkit-text-decoration:underline dotted;text-decoration:underline dotted}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Consolas,Liberation Mono,Menlo,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,select{text-transform:none}[type=button],[type=reset],button{-webkit-appearance:button}legend{padding:0}progress{vertical-align:baseline}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}button{background-color:transparent;background-image:none}button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}fieldset,ol,ul{margin:0;padding:0}ol,ul{list-style:none}html{font-family:IBM Plex Sans,ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;line-height:1.5}body{font-family:inherit;line-height:inherit}*,:after,:before{box-sizing:border-box;border:0 solid #e5e7eb}hr{border-top-width:1px}img{border-style:solid}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input:-ms-input-placeholder,textarea:-ms-input-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}button{cursor:pointer}table{border-collapse:collapse}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}button,input,optgroup,select,textarea{padding:0;line-height:inherit;color:inherit}code,kbd,pre,samp{font-family:Menlo,ui-monospace,SFMono-Regular,Monaco,Consolas,Liberation Mono,Courier New,monospace}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}html{font-size:1rem;line-height:1.5rem;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}body{--tw-bg-opacity:1;background-color:rgba(255,255,255,var(--tw-bg-opacity));font-family:IBM Plex Sans,ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;line-height:1.5;--tw-text-opacity:1;color:rgba(17,24,39,var(--tw-text-opacity));font-kerning:normal;font-feature-settings:"kern","liga","clig","calt";font-variant-ligatures:none;font-variant:none}.container{width:100%}@media (min-width:640px){.container{max-width:640px}}@media (min-width:768px){.container{max-width:768px}}@media (min-width:1024px){.container{max-width:1024px}}@media (min-width:1280px){.container{max-width:1280px}}@media (min-width:1536px){.container{max-width:1536px}}.prose{color:#374151;max-width:65ch}.prose [class~=lead]{color:#4b5563;font-size:1.25em;line-height:1.6;margin-top:1.2em;margin-bottom:1.2em}.prose a{color:#111827;text-decoration:underline;font-weight:500}.prose strong{color:#111827;font-weight:600}.prose ol[type=A]{--list-counter-style:upper-alpha}.prose ol[type=a]{--list-counter-style:lower-alpha}.prose ol[type=I]{--list-counter-style:upper-roman}.prose ol[type=i]{--list-counter-style:lower-roman}.prose ol[type="1"]{--list-counter-style:decimal}.prose ol>li{position:relative;padding-left:1.75em}.prose ol>li:before{content:counter(list-item,var(--list-counter-style,decimal)) ".";position:absolute;font-weight:400;color:#6b7280;left:0}.prose ul>li{position:relative;padding-left:1.75em}.prose ul>li:before{content:"";position:absolute;background-color:#d1d5db;border-radius:50%;width:.375em;height:.375em;top:.6875em;left:.25em}.prose hr{border-color:#e5e7eb;border-top-width:1px;margin-top:3em;margin-bottom:3em}.prose blockquote{font-weight:500;font-style:italic;color:#111827;border-left-width:.25rem;border-left-color:#e5e7eb;quotes:"\201C""\201D""\2018""\2019";margin-top:1.6em;margin-bottom:1.6em;padding-left:1em}.prose blockquote p:first-of-type:before{content:open-quote}.prose blockquote p:last-of-type:after{content:close-quote}.prose h1{color:#111827;font-weight:800;font-size:2.25em;margin-top:0;margin-bottom:.8888889em;line-height:1.1111111}.prose h2{color:#111827;font-weight:700;font-size:1.5em;margin-top:2em;margin-bottom:1em;line-height:1.3333333}.prose h3{font-size:1.25em;margin-top:1.6em;margin-bottom:.6em;line-height:1.6}.prose h3,.prose h4{color:#111827;font-weight:600}.prose h4{margin-top:1.5em;margin-bottom:.5em;line-height:1.5}.prose figure figcaption{color:#6b7280;font-size:.875em;line-height:1.4285714;margin-top:.8571429em}.prose code{color:#111827;font-weight:600;font-size:.875em}.prose code:after,.prose code:before{content:"`"}.prose a code{color:#111827}.prose pre{color:#e5e7eb;background-color:#1f2937;overflow-x:auto;font-size:.875em;line-height:1.7142857;margin-top:1.7142857em;margin-bottom:1.7142857em;border-radius:.375rem;padding:.8571429em 1.1428571em}.prose pre code{background-color:transparent;border-width:0;border-radius:0;padding:0;font-weight:400;color:inherit;font-size:inherit;font-family:inherit;line-height:inherit}.prose pre code:after,.prose pre code:before{content:none}.prose table{width:100%;table-layout:auto;text-align:left;margin-top:2em;margin-bottom:2em;font-size:.875em;line-height:1.7142857}.prose thead{color:#111827;font-weight:600;border-bottom-width:1px;border-bottom-color:#d1d5db}.prose thead th{vertical-align:bottom;padding-right:.5714286em;padding-bottom:.5714286em;padding-left:.5714286em}.prose tbody tr{border-bottom-width:1px;border-bottom-color:#e5e7eb}.prose tbody tr:last-child{border-bottom-width:0}.prose tbody td{vertical-align:top;padding:.5714286em}.prose{font-size:1rem;line-height:1.75}.prose p{margin-top:1.25em;margin-bottom:1.25em}.prose figure,.prose img,.prose video{margin-top:2em;margin-bottom:2em}.prose figure>*{margin-top:0;margin-bottom:0}.prose h2 code{font-size:.875em}.prose h3 code{font-size:.9em}.prose ol,.prose ul{margin-top:1.25em;margin-bottom:1.25em}.prose li{margin-top:.5em;margin-bottom:.5em}.prose>ul>li p{margin-top:.75em;margin-bottom:.75em}.prose>ul>li>:first-child{margin-top:1.25em}.prose>ul>li>:last-child{margin-bottom:1.25em}.prose>ol>li>:first-child{margin-top:1.25em}.prose>ol>li>:last-child{margin-bottom:1.25em}.prose ol ol,.prose ol ul,.prose ul ol,.prose ul ul{margin-top:.75em;margin-bottom:.75em}.prose h2+*,.prose h3+*,.prose h4+*,.prose hr+*{margin-top:0}.prose thead th:first-child{padding-left:0}.prose thead th:last-child{padding-right:0}.prose tbody td:first-child{padding-left:0}.prose tbody td:last-child{padding-right:0}.prose>:first-child{margin-top:0}.prose>:last-child{margin-bottom:0}.bg-black{--tw-bg-opacity:1;background-color:rgba(0,0,0,var(--tw-bg-opacity))}.rounded-lg{border-radius:.5rem}.border{border-width:1px}.block{display:block}.inline-block{display:inline-block}.inline{display:inline}
3.flex{display:flex}.table{display:table}.grid{display:grid}.hidden{display:none}.font-semibold{font-weight:600}.font-bold{font-weight:700}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-2xl{font-size:1.5rem;line-height:2rem}.leading-loose{line-height:2}.m-1{margin:.25rem}.my-1{margin-top:.25rem;margin-bottom:.25rem}.mx-auto{margin-left:auto;margin-right:auto}.mb-4{margin-bottom:1rem}.mt-8{margin-top:2rem}.mb-12{margin-bottom:3rem}.max-w-md{max-width:28rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-5{padding-left:1.25rem;padding-right:1.25rem}.pt-8{padding-top:2rem}.pb-12{padding-bottom:3rem}.fixed{position:fixed}.absolute{position:absolute}.resize{resize:both}*{--tw-shadow:0 0 transparent;--tw-ring-inset:var(--tw-empty,/*!*/ /*!*/);--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,0.5);--tw-ring-offset-shadow:0 0 transparent;--tw-ring-shadow:0 0 transparent}.text-white{--tw-text-opacity:1;color:rgba(255,255,255,var(--tw-text-opacity))}.text-gray-700{--tw-text-opacity:1;color:rgba(55,65,81,var(--tw-text-opacity))}.text-gray-800{--tw-text-opacity:1;color:rgba(31,41,55,var(--tw-text-opacity))}.text-pink-400{--tw-text-opacity:1;color:rgba(244,114,182,var(--tw-text-opacity))}.text-cyan-500{--tw-text-opacity:1;color:rgba(6,182,212,var(--tw-text-opacity))}.uppercase{text-transform:uppercase}.visible{visibility:visible}.w-1{width:.25rem}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.transform{--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;transform:translateX(var(--tw-translate-x)) translateY(var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.transition{transition-property:background-color,border-color,color,fill,stroke,opacity,box-shadow,transform,filter,-webkit-backdrop-filter;transition-property:background-color,border-color,color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-property:background-color,border-color,color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter,-webkit-backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}@-webkit-keyframes spin{to{transform:rotate(1turn)}}@keyframes spin{to{transform:rotate(1turn)}}@-webkit-keyframes ping{75%,to{transform:scale(2);opacity:0}}@keyframes ping{75%,to{transform:scale(2);opacity:0}}@-webkit-keyframes pulse{50%{opacity:.5}}@keyframes pulse{50%{opacity:.5}}@-webkit-keyframes bounce{0%,to{transform:translateY(-25%);-webkit-animation-timing-function:cubic-bezier(.8,0,1,1);animation-timing-function:cubic-bezier(.8,0,1,1)}50%{transform:none;-webkit-animation-timing-function:cubic-bezier(0,0,.2,1);animation-timing-function:cubic-bezier(0,0,.2,1)}}@keyframes bounce{0%,to{transform:translateY(-25%);-webkit-animation-timing-function:cubic-bezier(.8,0,1,1);animation-timing-function:cubic-bezier(.8,0,1,1)}50%{transform:none;-webkit-animation-timing-function:cubic-bezier(0,0,.2,1);animation-timing-function:cubic-bezier(0,0,.2,1)}}.filter{--tw-blur:var(--tw-empty,/*!*/ /*!*/);--tw-brightness:var(--tw-empty,/*!*/ /*!*/);--tw-contrast:var(--tw-empty,/*!*/ /*!*/);--tw-grayscale:var(--tw-empty,/*!*/ /*!*/);--tw-hue-rotate:var(--tw-empty,/*!*/ /*!*/);--tw-invert:var(--tw-empty,/*!*/ /*!*/);--tw-saturate:var(--tw-empty,/*!*/ /*!*/);--tw-sepia:var(--tw-empty,/*!*/ /*!*/);--tw-drop-shadow:var(--tw-empty,/*!*/ /*!*/);filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.invert{--tw-invert:invert(100%)}.funky-underline{display:inline-block;position:relative}.funky-underline:before{--underline-color:#22d3ee;position:absolute;bottom:-1px;left:-2px;right:-4px;content:"";height:4px;border-radius:99999px;background:var(--underline-color);transform:rotate(-2deg)}:root{--gray-50:#f9fafb;--gray-100:#f3f4f6;--gray-200:#e5e7eb;--gray-300:#d1d5db;--gray-400:#9ca3af;--gray-500:#6b7280;--gray-600:#4b5563;--gray-700:#374151;--gray-800:#1f2937;--gray-900:#111827;--cyan-400:#22d3ee;--cyan-500:#06b6d4}.prose a{text-decoration:none}code[class*=language-],pre[class*=language-]{color:#000;background:none;text-shadow:0 1px #fff;font-family:Consolas,Monaco,Andale Mono,Ubuntu Mono,monospace;font-size:.92em;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-ms-hyphens:none;hyphens:none}code[class*=language-]::-moz-selection,code[class*=language-] ::-moz-selection,pre[class*=language-]::-moz-selection,pre[class*=language-] ::-moz-selection{text-shadow:none;background:#b3d4fc}code[class*=language-]::selection,code[class*=language-] ::selection,pre[class*=language-]::selection,pre[class*=language-] ::selection{text-shadow:none;background:#b3d4fc}@media print{code[class*=language-],pre[class*=language-]{text-shadow:none}}pre[class*=language-]{padding:1em;margin:16px 0 32px;overflow:auto;border:1px solid var(--gray-200);background:var(--gray-50);border-radius:4px}:not(pre)>code[class*=language-]{padding:.1em;border-radius:.3em;white-space:normal;background:none}.token.cdata,.token.comment,.token.doctype,.token.prolog{color:#708090}.token.punctuation{color:#999}.namespace{opacity:.7}.token.boolean,.token.constant,.token.deleted,.token.number,.token.property,.token.symbol,.token.tag{color:#905}.token.attr-name,.token.builtin,.token.char,.token.inserted,.token.selector,.token.string{color:#690}.language-css .token.string,.style .token.string,.token.entity,.token.operator,.token.url{color:#a67f59;background:hsla(0,0%,100%,.5)}.token.atrule,.token.attr-value,.token.keyword{color:#07a}.token.function{color:#dd4a68}.token.important,.token.regex,.token.variable{color:#e90}.token.bold,.token.important{font-weight:700}.token.italic{font-style:italic}.token.entity{cursor:help}</style><meta name="generator" content="Gatsby 2.24.84"/><title data-react-helmet="true">Use Snowpack for ultra fast dev builds with Create React App - Peter Beshai</title><link data-react-helmet="true" href="https://fonts.googleapis.com/css?family=IBM+Plex+Sans:400,400i,500,600,700" rel="stylesheet"/><meta data-react-helmet="true" name="description" content="Learn how to modify a create-react-app react app to use snowpack during development for faster rebuilds."/><meta data-react-helmet="true" name="twitter:description" content="Learn how to modify a create-react-app react app to use snowpack during development for faster rebuilds."/><meta data-react-helmet="true" property="og:description" content="Learn how to modify a create-react-app react app to use snowpack during development for faster rebuilds."/><meta data-react-helmet="true" name="keywords" content="dataviz, data visualization, creative coding, generative art, nba, basketball"/><meta data-react-helmet="true" name="twitter:site" content="@pbesh"/><meta data-react-helmet="true" name="twitter:creator" content="@pbesh"/><meta data-react-helmet="true" property="og:title" content="Use Snowpack for ultra fast dev builds with Create React App"/><meta data-react-helmet="true" property="twitter:title" content="Use Snowpack for ultra fast dev builds with Create React App"/><meta data-react-helmet="true" property="og:url" content="https://peterbeshai.com/blog/2020-10-22-cra-snowpack/"/><meta data-react-helmet="true" property="og:image" content="https://peterbeshai.com/static/f597c6ebb9c1d793892a89c1e3fb678d/35c24/social.png"/><meta data-react-helmet="true" name="twitter:image" content="https://peterbeshai.com/static/f597c6ebb9c1d793892a89c1e3fb678d/35c24/social.png"/><meta data-react-helmet="true" property="og:type" content="article"/><meta data-react-helmet="true" name="twitter:card" content="summary_large_image"/><link rel="icon" href="/favicon-32x32.png?v=8eada2f2c54a980a0d0d715a284fca9b" type="image/png"/>
3<link rel="manifest" href="/manifest.webmanifest" crossorigin="anonymous"/><meta name="theme-color" content="#000000"/><link rel="apple-touch-icon" sizes="48x48" href="/icons/icon-48x48.png?v=8eada2f2c54a980a0d0d715a284fca9b"/><link rel="apple-touch-icon" sizes="72x72" href="/icons/icon-72x72.png?v=8eada2f2c54a980a0d0d715a284fca9b"/><link rel="apple-touch-icon" sizes="96x96" href="/icons/icon-96x96.png?v=8eada2f2c54a980a0d0d715a284fca9b"/><link rel="apple-touch-icon" sizes="144x144" href="/icons/icon-144x144.png?v=8eada2f2c54a980a0d0d715a284fca9b"/><link rel="apple-touch-icon" sizes="192x192" href="/icons/icon-192x192.png?v=8eada2f2c54a980a0d0d715a284fca9b"/><link rel="apple-touch-icon" sizes="256x256" href="/icons/icon-256x256.png?v=8eada2f2c54a980a0d0d715a284fca9b"/><link rel="apple-touch-icon" sizes="384x384" href="/icons/icon-384x384.png?v=8eada2f2c54a980a0d0d715a284fca9b"/><link rel="apple-touch-icon" sizes="512x512" href="/icons/icon-512x512.png?v=8eada2f2c54a980a0d0d715a284fca9b"/><style data-styled="dgrgPo bRzELH lcczCA gofAlC krNbLw liYjay cgJpCM hRIHo hJIQXL eiraze gQsBqH" data-styled-version="4.4.1">
4/* sc-component-id: core__Box-eqpeba-0 */
5.lcczCA{margin-left:auto;margin-right:auto;padding:16px;max-width:65ch;}.gofAlC{margin-top:128px;}.krNbLw{margin-left:auto;margin-right:auto;padding-left:16px;padding-right:16px;padding-top:64px;padding-bottom:64px;}
6/* sc-component-id: core__Flex-eqpeba-1 */
7.dgrgPo{margin-top:16px;margin-bottom:16px;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;}
8/* sc-component-id: core__Text-eqpeba-2 */
9.gQsBqH{text-align:center;}
10/* sc-component-id: core__Header-eqpeba-3 */
11.liYjay{margin:0px;margin-bottom:8px;font-size:27px;font-family:'IBM Plex Sans',-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif;color:#1f2937;font-family:'IBM Plex Sans',-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif;font-weight:bold;line-height:1.15;-webkit-letter-spacing:-0.01em;-moz-letter-spacing:-0.01em;-ms-letter-spacing:-0.01em;letter-spacing:-0.01em;}
12/* sc-component-id: core__StyledLink-eqpeba-5 */
13.eiraze{color:#374151;border-bottom:2px solid #e5e7eb;-webkit-text-decoration:none;text-decoration:none;background:transparent;-webkit-transition:0.2s background linear,0.2s border-color linear;transition:0.2s background linear,0.2s border-color linear;} .eiraze:hover{color:#1f2937;background:#e3fafc;border-color:#99e9f2;}
14/* sc-component-id: core__InlineList-eqpeba-11 */
15.cgJpCM{margin-bottom:8px;color:#4b5563;list-style-type:none;list-style-type:none;padding-left:0;}.hRIHo{list-style-type:none;padding-left:0;}
16/* sc-component-id: core__InlineListItem-eqpeba-12 */
17.hJIQXL{margin-right:16px;display:inline-block;} .hJIQXL:last-child{margin-right:0;} .hJIQXL::before{content:'•';color:#d1d5db;margin-right:16px;} .hJIQXL:first-child::before{content:'';margin-right:0;}
18/* sc-component-id: layout___StyledText-sc-1yov7wq-0 */
19.bRzELH{padding-left:8px;padding-right:8px;font-size:16px;color:#ffffff;background-color:#000000;font-weight:700;border-radius:5px;box-shadow:3px 4px #3bc9db;-webkit-text-decoration:none;text-decoration:none;-webkit-transition:box-shadow 200ms;transition:box-shadow 200ms;} .bRzELH:hover{box-shadow:5px 6px #3bc9db;} .bRzELH:active{box-shadow:2px 3px #3bc9db;}</style><link rel="preconnect" href="https://www.google-analytics.com"/><link rel="dns-prefetch" href="https://www.google-analytics.com"/><link as="script" rel="preload" href="/webpack-runtime-06a9210293dd0d2a2358.js"/><link as="script" rel="preload" href="/framework-d80f7338bc29523a5c3b.js"/><link as="script" rel="preload" href="/app-fcd7ff88a19f1bf11c6c.js"/><link as="script" rel="preload" href="/styles-e9d24b1846c7d6eb9685.js"/><link as="script" rel="preload" href="/commons-16a344fd9551feb818bd.js"/><link as="script" rel="preload" href="/21b0c71395f743ee87503268ff5f3f467b604f32-88a5d176af816359574b.js"/><link as="script" rel="preload" href="/component---src-templates-blog-post-js-0d55bb857b27ef483d4e.js"/>
19<link as="fetch" rel="preload" href="/page-data/blog/2020-10-22-cra-snowpack/page-data.json" crossorigin="anonymous"/><link as="fetch" rel="preload" href="/page-data/app-data.json" crossorigin="anonymous"/></head><body><div id="___gatsby"><div style="outline:none" tabindex="-1" id="gatsby-focus-wrapper"><div><div class="core__Box-eqpeba-0 core__Flex-eqpeba-1 dgrgPo"><a bg="black" color="white" px="2" font-size="1" font-weight="700" class="core__Box-eqpeba-0 core__Text-eqpeba-2 layout___StyledText-sc-1yov7wq-0 bRzELH" href="/">Peter Beshai</a></div><div class="core__Box-eqpeba-0 lcczCA"><h2 font-size="4" font-weight="bold" font-family="header" color="gray.8" letter-spacing="-0.01em" class="core__Box-eqpeba-0 core__Text-eqpeba-2 core__Header-eqpeba-3 liYjay">Use Snowpack for ultra fast dev builds with Create React App</h2><ul color="gray.6" class="core__Box-eqpeba-0 core__List-eqpeba-10 core__InlineList-eqpeba-11 cgJpCM"><li class="core__Box-eqpeba-0 core__Text-eqpeba-2 core__InlineListItem-eqpeba-12 hJIQXL">October 22, 2020</li><li class="core__Box-eqpeba-0 core__Text-eqpeba-2 core__InlineListItem-eqpeba-12 hJIQXL">4 min read</li><li class="core__Box-eqpeba-0 core__Text-eqpeba-2 core__InlineListItem-eqpeba-12 hJIQXL"><a href="https://github.com/pbeshai/cra-snowpack/pull/1/files" class="core__Box-eqpeba-0 core__Text-eqpeba-2 core__StyledLink-eqpeba-5 eiraze">GitHub</a></li></ul><div class="prose"><div><p>Long ago I gave up the ways of customizing webpack and embraced <a href="https://create-react-app.dev/" class="core__Box-eqpeba-0 core__Text-eqpeba-2 core__StyledLink-eqpeba-5 eiraze">create-react-app</a> (CRA) as a someone-else-has-solved-it-for-me way to live. It&#x27;s been great, truly. But could it be better? At least <a href="https://www.youtube.com/watch?v=qSfdtmcZ4d0" class="core__Box-eqpeba-0 core__Text-eqpeba-2 core__StyledLink-eqpeba-5 eiraze">Rich Harris seems to think so</a>— he points to <a href="https://www.snowpack.dev/" class="core__Box-eqpeba-0 core__Text-eqpeba-2 core__StyledLink-eqpeba-5 eiraze">Snowpack</a> (or similarly minded tech) as the way forward.</p>
20<p>What makes Snowpack special? According to <a href="https://www.snowpack.dev/" class="core__Box-eqpeba-0 core__Text-eqpeba-2 core__StyledLink-eqpeba-5 eiraze">snowpack.dev</a>:</p>
21<blockquote>
22<p>Snowpack leverages JavaScript’s native module system (known as ESM) to create a first-of-its-kind build system that never builds the same file twice. Snowpack pushes changes instantly to the browser, saving you hours of development time traditionally spent waiting around for your bundler.</p>
23</blockquote>
24<p>This architecture makes Snowpack fantastic for fast rebuilds during dev, but leaves work to be done for production builds if you want your coded bundled. To do so requires configuring the <a href="https://github.com/snowpackjs/snowpack/tree/master/plugins/plugin-webpack" class="core__Box-eqpeba-0 core__Text-eqpeba-2 core__StyledLink-eqpeba-5 eiraze">@snowpack/plugin-webpack</a>, which I&#x27;m entirely uninterested in doing. But hey, CRA does a good enough job with bundling prod builds, so why not keep using it for prod and only use Snowpack for dev? That is the setup this post aims to 
24share.</p>
25<h2>So what do we actually have to do?</h2>
26<p>Turns out, not very much. Feel free to jump ahead and view the end product with all required changes as a <a href="https://github.com/pbeshai/cra-snowpack/pull/1/files" class="core__Box-eqpeba-0 core__Text-eqpeba-2 core__StyledLink-eqpeba-5 eiraze">PR on GitHub</a>.</p>
27<h4>Step 1. Add two snowpack dependencies</h4>
28<div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">npm install snowpack @snowpack/app-scripts-react</code></pre></div>
29<p>Note that <a href="https://github.com/snowpackjs/snowpack/blob/master/create-snowpack-app/app-scripts-react/snowpack.config.js" class="core__Box-eqpeba-0 core__Text-eqpeba-2 core__StyledLink-eqpeba-5 eiraze">@snowpack/app-scripts-react</a> includes support for dotenv and react fast refresh. If you&#x27;re using SCSS or other extensions, you may have to <a href="https://www.snowpack.dev/#recipes" class="core__Box-eqpeba-0 core__Text-eqpeba-2 core__StyledLink-eqpeba-5 eiraze">add more plugins</a>. </p>
30<h4>Step 2. Add snowpack.config.js to your root dir</h4>
31<p>The most basic <code class="language-text">snowpack.config.js</code> contains the following:</p>
32<div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">module<span class="token punctuation">.</span>exports <span class="token operator">=</span> <span class="token punctuation">{</span>
33  <span class="token keyword">extends</span><span class="token operator">:</span> <span class="token string">&#x27;@snowpack/app-scripts-react&#x27;</span><span class="token punctuation">,</span>
34
35  devOptions<span class="token operator">:</span> <span class="token punctuation">{</span>
36    port<span class="token operator">:</span> <span class="token number">3000</span><span class="token punctuation">,</span>
37    src<span class="token operator">:</span> <span class="token string">&#x27;src&#x27;</span><span class="token punctuation">,</span>
38    bundle<span class="token operator">:</span> <span class="token boolean">false</span><span class="token punctuation">,</span>
39    fallback<span class="token operator">:</span> <span class="token string">&#x27;index.html&#x27;</span><span class="token punctuation">,</span>
40  <span class="token punctuation">}</span><span class="token punctuation">,</span>
41
42  installOptions<span class="token operator">:</span> <span class="token punctuation">{</span>
43    polyfillNode<span class="token operator">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span>
44  <span class="token punctuation">}</span><span class="token punctuation">,</span>
45<span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre></div>
46<p>The <a href="https://github.com/pbeshai/cra-snowpack/blob/main/snowpack.config.js" class="core__Box-eqpeba-0 core__Text-eqpeba-2 core__StyledLink-eqpeba-5 eiraze">example in the repo</a> additionally shows how to configure a proxy, where to add additional plugins, and how to emulate <code class="language-text">baseUrl: &quot;.&quot;</code> from a jsconfig.json.</p>
47<h4>Step 3. (Optionally) Add babel.config.json to your root dir</h4>
48<p>This step is only required if you do not use the <code class="language-text">.jsx</code> extension for files containing JSX. If you put JSX in <code class="language-text">.js</code> files, you&#x27;ll need babel to build your code, which Snowpack knows to use by the presence of this file (or <code class="language-text">.babelrc</code>). If all your JSX lives in <code class="language-text">.jsx</code> files, Snowpack can handle it directly without any babel config.</p>
49<div class="gatsby-highlight" data-language="json"><pre class="language-json"><code class="language-json"><span class="token punctuation">{</span>
50  <span class="token property">&quot;presets&quot;</span><span class="token operator">:</span> <span class="token punctuation">[</span><span class="token string">&quot;@babel/preset-react&quot;</span><span class="token punctuation">]</span>
51<span class="token punctuation">}</span></code></pre></div>
52<h4>Step 4. (Optionally) Set up postcss</h4>
53<p>Your app may work fine without making these changes, but they were a bit of a struggle to get right, so I&#x27;m sharing them here. In order to <a href="https://github.com/facebook/create-react-app/blob/0a93e32a434ba9995feb1a879bebf520fa6464e6/packages/react-scripts/config/webpack.config.js#L109-L133" class="core__Box-eqpeba-0 core__Text-eqpeba-2 core__StyledLink-eqpeba-5 eiraze">match create-react-app&#x27;s CSS transformations</a> and <a href="https://github.com/snowpackjs/snowpack/issues/389" class="core__Box-eqpeba-0 core__Text-eqpeba-2 core__StyledLink-eqpeba-5 eiraze">interpretations of <code class="language-text">@import</code>s</a>, we need to use <a href="https://postcss.org/" class="core__Box-eqpeba-0 core__Text-eqpeba-2 core__StyledLink-eqpeba-5 eiraze">postcss</a>.</p>
54<p>First, we need to install some dependencies:</p>
55<div class="gatsby-highlight" data-language="text"><pre class="language-text"><code class="language-text">
55npm install postcss-cli postcss-flexbugs-fixes postcss-import postcss-normalize postcss-preset-env</code></pre></div>
56<p><em>Note:</em> PostCSS 8 only recently came out and not everything is updated to work with it yet, so I actually specified postcss@^7.1.2 and postcss-import@^12.0.1 when I wrote this.</p>
57<p>Next, we modify <strong>snowpack.config.js</strong> to include <strong>plugins</strong></p>
58<div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">module<span class="token punctuation">.</span>exports <span class="token operator">=</span> <span class="token punctuation">{</span>
59  <span class="token operator">...</span>
60  plugins<span class="token operator">:</span> <span class="token punctuation">[</span>
61    <span class="token comment">// use postcss to get relative imports working and to match CRA</span>
62    <span class="token punctuation">[</span>
63      <span class="token string">&#x27;@snowpack/plugin-build-script&#x27;</span><span class="token punctuation">,</span>
64      <span class="token punctuation">{</span> cmd<span class="token operator">:</span> <span class="token string">&#x27;postcss $FILE&#x27;</span><span class="token punctuation">,</span> input<span class="token operator">:</span> <span class="token punctuation">[</span><span class="token string">&#x27;.css&#x27;</span><span class="token punctuation">]</span><span class="token punctuation">,</span> output<span class="token operator">:</span> <span class="token punctuation">[</span><span class="token string">&#x27;.css&#x27;</span><span class="token punctuation">]</span> <span class="token punctuation">}</span><span class="token punctuation">,</span>
65    <span class="token punctuation">]</span><span class="token punctuation">,</span>
66  <span class="token punctuation">]</span><span class="token punctuation">,</span>
67<span class="token punctuation">}</span></code></pre></div>
68<p>Finally, we add <strong>postcss.config.js</strong></p>
69<div class="gatsby-highlight" data-language="js"><pre class="language-js"><code class="language-js">module<span class="token punctuation">.</span><span class="token function-variable function">exports</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">ctx</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
70  <span class="token keyword">return</span> <span class="token punctuation">{</span>
71    plugins<span class="token operator">:</span> <span class="token punctuation">{</span>
72      <span class="token comment">// need this to get relative @import &quot;./Foo.css&quot;; working</span>
73      <span class="token string">&#x27;postcss-import&#x27;</span><span class="token operator">:</span> <span class="token punctuation">{</span> root<span class="token operator">:</span> ctx<span class="token punctuation">.</span>file<span class="token punctuation">.</span>dirname <span class="token punctuation">}</span><span class="token punctuation">,</span>
74
75      <span class="token comment">// copied from create-react-app</span>
76      <span class="token string">&#x27;postcss-flexbugs-fixes&#x27;</span><span class="token operator">:</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
77      <span class="token string">&#x27;postcss-preset-env&#x27;</span><span class="token operator">:</span> <span class="token punctuation">{</span>
78        autoprefixer<span class="token operator">:</span> <span class="token punctuation">{</span>
79          flexbox<span class="token operator">:</span> <span class="token string">&#x27;no-2009&#x27;</span><span class="token punctuation">,</span>
80        <span class="token punctuation">}</span><span class="token punctuation">,</span>
81        stage<span class="token operator">:</span> <span class="token number">3</span><span class="token punctuation">,</span>
82      <span class="token punctuation">}</span><span class="token punctuation">,</span>
83      <span class="token string">&#x27;postcss-normalize&#x27;</span><span class="token operator">:</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">,</span>
84    <span class="token punctuation">}</span><span class="token punctuation">,</span>
85  <span class="token punctuation">}</span><span class="token punctuation">;</span>
86<span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre></div>
87<p>You&#x27;ll see this is a bit atypical for a postcss config, but we need to know the current file when running postcss-import to get relative imports resolved correctly. This is also why we set <code class="language-text">postcss $FILE</code> as the cmd in snowpack.config.js above as opposed to just <code class="language-text">postcss</code> as <a href="https://www.snowpack.dev/#%40snowpack%2Fplugin-build-script" class="core__Box-eqpeba-0 core__Text-eqpeba-2 core__StyledLink-eqpeba-5 eiraze">the Snowpack docs show</a>.</p>
88<h4>Step 5. Configure your start script in package.json</h4>
89<p>I keep the CRA start script around just in case, but you shouldn&#x27;t need it anymore.</p>
90<div class="gatsby-highlight" data-language="json"><pre class="language-json"><code class="language-json"><span class="token property">&quot;start&quot;</span><span class="token operator">:</span> <span class="token string">&quot;snowpack dev --config snowpack.config.js&quot;</span><span class="token punctuation">,</span>
91<span class="token property">&quot;start:cra&quot;</span><span class="token operator">:</span> <span class="token string">&quot;react-scripts start&quot;</span><span class="token punctuation">,</span></code></pre></div>
92<h4>Step 6. Update index.html to include the snowpack dev entrypoint</h4>
93<p>Things get a bit weird here. What we want is code that the CRA minifier will remove during production builds, but will still be run when using the snowpack dev server. </p>
94<p>The trick is to use a snowpack specific interpolation variable c
94alled <a href="https://www.snowpack.dev/#environment-variables" class="core__Box-eqpeba-0 core__Text-eqpeba-2 core__StyledLink-eqpeba-5 eiraze"><code class="language-text">%MODE%</code></a> (essentially the same as <code class="language-text">process.env.NODE_ENV</code>). This interpolation only exists in the snowpack dev server, not in CRA, so the if statement will be analyzed as dead code and be pruned during the prod builds.</p>
95<div class="gatsby-highlight" data-language="html"><pre class="language-html"><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>body</span><span class="token punctuation">&gt;</span></span>
96  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>noscript</span><span class="token punctuation">&gt;</span></span>You need to enable JavaScript to run this app.<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>noscript</span><span class="token punctuation">&gt;</span></span>
97  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">&quot;</span>root<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
98
99  <span class="token comment">&lt;!-- 
100    add entry for snowpack, only used in dev, it is pruned in production.
101  --&gt;</span>
102  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>script</span><span class="token punctuation">&gt;</span></span><span class="token script"><span class="token language-javascript">
103    <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token string">&#x27;%MODE%&#x27;</span> <span class="token operator">===</span> <span class="token string">&#x27;development&#x27;</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
104      <span class="token comment">// we wrap this in a function to prevent the variables from leaking out</span>
105      <span class="token punctuation">(</span><span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> 
106        console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">&#x27;[dev] injecting snowpack entry&#x27;</span><span class="token punctuation">)</span>
107        <span class="token keyword">var</span> snowpackEntryScript <span class="token operator">=</span> document<span class="token punctuation">.</span><span class="token function">createElement</span><span class="token punctuation">(</span><span class="token string">&#x27;script&#x27;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
108        snowpackEntryScript<span class="token punctuation">.</span><span class="token function">setAttribute</span><span class="token punctuation">(</span><span class="token string">&#x27;type&#x27;</span><span class="token punctuation">,</span> <span class="token string">&#x27;module&#x27;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
109        snowpackEntryScript<span class="token punctuation">.</span><span class="token function">setAttribute</span><span class="token punctuation">(</span><span class="token string">&#x27;src&#x27;</span><span class="token punctuation">,</span> <span class="token string">&#x27;/_dist_/index.js&#x27;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
110        document<span class="token punctuation">.</span>head<span class="token punctuation">.</span><span class="token function">appendChild</span><span class="token punctuation">(</span>snowpackEntryScript<span class="token punctuation">)</span><span class="token punctuation">;</span>
111      <span class="token punctuation">}</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
112    <span class="token punctuation">}</span>
113  </span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>script</span><span class="token punctuation">&gt;</span></span>
114<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>body</span><span class="token punctuation">&gt;</span></span></code></pre></div>
115<p>If you view the index.html after running a CRA build, you&#x27;ll see that the script was mostly pruned. It is rendered as <code class="language-text">&lt;script&gt;0&lt;/script&gt;</code>, effectively doing nothing. Not quite as good as &quot;not there at all,&quot; but close enough for me.</p>
116<h2>Conclusion</h2>
117<p>Is it really a good idea to use a different build system for dev and production? Maybe not, but it sure is fun to try out. I hope the steps above have helped you figure out how to tempt fate and give Snowpack a shot. </p>
118<ul>
119<li>See <a href="https://github.com/pbeshai/cra-snowpack/pull/1/files" class="core__Box-eqpeba-0 core__Text-eqpeba-2 core__StyledLink-eqpeba-5 eiraze">the PR containing all the changes here</a></li>
120<li>See <a href="https://github.com/pbeshai/cra-snowpack" class="core__Box-eqpeba-0 core__Text-eqpeba-2 core__StyledLink-eqpeba-5 eiraze">the repo with the changes merged into a blank CRA app</a></li>
121</ul>
122<p>Thanks for reading! If you&#x27;ve got any questions, feel free to reach out to me on twitter <a href="https://twitter.com/pbesh" class="core__Box-eqpeba-0 core__Text-eqpeba-2 core__StyledLink-eqpeba-5 eiraze">@pbesh</a>.</p></div></div><div class="core__Box-eqpeba-0 gofAlC"><div shortname="peter-beshai" config="[object Object]" id="disqus_thread"></div></div></div><div class="core__Box-eqpeba-0 krNbLw"><div class="core__Box-eqpeba-0 core__Text-eqpeba-2 gQsBqH"><ul class="core__Box-eqpeba-0 core__List-eqpeba-10 core__InlineList-eqpeba-11 hRIHo"><li class="core__Box-eqpeba-0 core__Text-eqpeba-2 core__InlineListItem-eqpeba-12 hJIQXL"><a href="/cdn-cgi/l/email-protection#3242574657401c5057415a535b72555f535b5e1c515d5f" class="core__Box-eqpeba-0 core__Text-eqpeba-2 core__StyledLink-eqpeba-5 eiraze"><span class="__cf_email__" data-cfemail="2b5b4e5f4e5905494e58434a426b4c464a424705484446">[email&#160;protected]</span></a></li><li class="core__Box-eqpeba-0 core__Text-eqpeba-2 core__InlineListItem-eqpeba-12 hJIQXL"><a href="https://twitter.com/pbesh" class="core__Box-eqpeba-0 core__Text-eqpeba-2 core__StyledLink-eqpeba-5 eiraze">Twitter</a></li><li class="core__Box-eqpeba-0 core__Text-eqpeba-2 core__InlineListItem-eqpeba-12 hJIQXL"><a href="https://twitch.tv/pbeshai" class="core__Box-eqpeba-0 core__Text-eqpeba-2 core__StyledLink-eqpeba-5 eiraze">Twitch</a></li><li class="core__Box-eqpeba-0 core__Text-eqpeba-2 core__InlineListItem-eqpeba-12 hJIQXL"><a href="https://github.com/pbeshai" class="core__Box-eqpeba-0 core__Text-eqpeba-2 core__StyledLink-eqpeba-5 eiraze">GitHub</a></li><li class="core__Box-eqpeba-0 core__Text-eqpeba-2 core__InlineListItem-eqpeba-12 hJIQXL"><a href="https://instagram.com/pbeshasketch" class="core__Box-eqpeba-0 core__Text-eqpeba-2 core__StyledLink-eqpeba-5 eiraze">Instagram</a></li><li class="core__Box-eqpeba-0 core__Text-eqpeba-2 core__InlineListItem-eqpeba-12 hJIQXL"><a href="https://www.linkedin.com/in/pbeshai" class="core__Box-eqpeba-0 core__Text-eqpeba-2 core__StyledLink-eqpeba-5 eiraze">LinkedIn</a></li></ul></div></div></div></div><div id="gatsby-announcer" style="position:absolute;top:0;width:1px;height:1px;padding:0;overflow:hidden;clip:rect(0, 0, 0, 0);white-space:nowrap;border:0" aria-live="assertive" aria-atomic="true"></div></div>
vendor: 108 bytes, line 122
122<script data-cfasync="false" src="/cdn-cgi/scripts/5c5dd728/cloudflare-static/email-decode.min.js"></script>
122<script>
123  
124  
125  if(true) {
126    (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
127    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
128    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
129    })(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
130  }
131  if (typeof ga === "function") {
132    ga('create', 'UA-55938435-1', 'auto', {});
133      
134      
135      
136      
137      
138      }</script>
138<script id="gatsby-script-loader">/*<![CDATA[*/window.pagePath="/blog/2020-10-22-cra-snowpack/";/*]]>*/</script>
138<script id="gatsby-chunk-mapping">/*<![CDATA[*/window.___chunkMapping={"polyfill":["/polyfill-b540199392df4ae4b2b3.js"],"app":["/app-fcd7ff88a19f1bf11c6c.js"],"component---src-pages-404-js":["/component---src-pages-404-js-c2832438e0b6a94d149f.js"],"component---src-pages-index-js":["/component---src-pages-index-js-9fd4d7b2f08ac5830f3c.js"],"component---src-templates-blog-post-js":["/component---src-templates-blog-post-js-0d55bb857b27ef483d4e.js"],"component---src-templates-demo-js":["/component---src-templates-demo-js-86292a96b849eb84e1cf.js"]};/*]]>*/</script>
138<script src="/polyfill-b540199392df4ae4b2b3.js" nomodule=""></script>
138<script src="/component---src-templates-blog-post-js-0d55bb857b27ef483d4e.js" async=""></script>
138<script src="/21b0c71395f743ee87503268ff5f3f467b604f32-88a5d176af816359574b.js" async=""></script>
138<script src="/commons-16a344fd9551feb818bd.js" async=""></script>
138<script src="/styles-e9d24b1846c7d6eb9685.js" async=""></script>
138<script src="/app-fcd7ff88a19f1bf11c6c.js" async=""></script>
138<script src="/framework-d80f7338bc29523a5c3b.js" async=""></script>
138<script src="/webpack-runtime-06a9210293dd0d2a2358.js" async=""></script>
138<script type="module" src="https://static.cloudflareinsights.com/beacon.min.js/v31edd6df95cf4e85bb4c19e7a9bdbcba1788362987495" integrity="sha512-iIg7k2xntmwu6/uSb5tpc/hySgZc4eoL31yB29W6tJFo2akwjPWcEqnCEdJvGexCL0KEQwVYv5BlowfhVz26hg==" data-cf-beacon='{"version":"2024.11.0","token":"955d7c87d49a4378a21db6c033f2920c","r":1,"spa":2}' crossorigin="anonymous"></script>
138
139</body></html>

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.