preact-cli
preact-cli copied to clipboard
Feature request: new build-time option removing inline scripts to develop browser extensions
Do you want to request a feature or report a bug?
request a feature
What is the current behaviour?
preact build
generates index.html
with inline scripts.
If the current behaviour is a bug, please provide the steps to reproduce.
not a bug
What is the expected behaviour?
preact build
generates index.html
without inline scripts.
Current preact-cli
generates inline scripts like below(unminified):
<script type="__PREACT_CLI_DATA__">
%7B%22preRenderData%22:%7B%22url%22:%22/%22%7D%7D
</script>
<script nomodule="">
!(function() {
var e = document,
t = e.createElement("script");
if (!("noModule" in t) && "onbeforeload" in t) {
var n = !1;
e.addEventListener(
"beforeload",
function(e) {
if (e.target === t) n = !0;
else if (!e.target.hasAttribute("nomodule") || !n)
return;
e.preventDefault();
},
!0
),
(t.type = "module"),
(t.src = "."),
e.head.appendChild(t),
t.remove();
}
})();
</script>
I need to write out these scripts to files and load.
If this is a feature request, what is motivation or use case for changing the behaviour?
To develop browser extensions. Browsers forbid inline scripts without hash or nonce wrote in manifest.json as content security policy.
Please mention other relevant information.
The create-react-app supports this feature by environment variable switch, INLINE_RUNTIME_CHUNK
.
Please paste the results of preact info
here.
Environment Info:
System:
OS: macOS 10.15.7
CPU: (8) x64 Intel(R) Core(TM) i5-8257U CPU @ 1.40GHz
Binaries:
Node: 14.15.1 - /var/folders/tf/2sbxxh5552nc03mb6kz7gvcr0000gn/T/yarn--1609001521817-0.4367070293127109/node
Yarn: 1.22.10 - /var/folders/tf/2sbxxh5552nc03mb6kz7gvcr0000gn/T/yarn--1609001521817-0.4367070293127109/yarn
npm: 6.14.8 - ~/.anyenv/envs/nodenv/versions/14.15.1/bin/npm
Browsers:
Chrome: 87.0.4280.88
Firefox: 83.0
Safari: 14.0.2
npmPackages:
preact: ^10.3.1 => 10.5.7
preact-cli: ^3.0.0 => 3.0.5
preact-render-to-string: ^5.1.4 => 5.1.12
preact-router: ^3.2.1 => 3.2.1
✨ Done in 5.83s.
Thank you for reading!
Sorry for the late response, you can just use a custom template to get this behavior I believe.
Copy the template if you do not already have one in your repo. Remove the <% preact.bodyEnd %>
and then use the template via preact build --template path/to/template.html
.
@rschristian
No problem, thank you for answering. But removing <% preact.bodyEnd %>
does not work.
It removes the code blocks I mentioned from the template.html
and removes other critical code blocks, and then the app becomes blank completely.
Diff of The body element from with <% preact.bodyEnd %>
to without it is as follows:
88,137c41
< <body>
< <div id="app">
< <header class="header__3QGkI">
< <h1>Preact App</h1>
< <nav>
< <a href="/index.html" class="">Home</a
< ><a href="/profile" class="">Me</a
< ><a href="/profile/john" class="">John</a>
< </nav>
< </header>
< <div class="notfound__3HqSM">
< <h1>Error 404</h1>
< <p>That page doesn't exist.</p>
< <a href="/" class=""><h4>Back to Home</h4></a>
< </div>
< </div>
< <script type="__PREACT_CLI_DATA__">
< %7B%22preRenderData%22:%7B%22url%22:%22/%22%7D%7D
< </script>
< <script nomodule="">
< !(function() {
< var e = document,
< t = e.createElement("script");
< if (!("noModule" in t) && "onbeforeload" in t) {
< var n = !1;
< e.addEventListener(
< "beforeload",
< function(e) {
< if (e.target === t) n = !0;
< else if (!e.target.hasAttribute("nomodule") || !n)
< return;
< e.preventDefault();
< },
< !0
< ),
< (t.type = "module"),
< (t.src = "."),
< e.head.appendChild(t),
< t.remove();
< }
< })();
< </script>
< <script
< crossorigin="anonymous"
< src="/bundle.58077.esm.js"
< type="module"
< ></script>
< <script nomodule="" src="/polyfills.03bf6.js"></script>
< <script nomodule="" defer="defer" src="/polyfills.03bf6.js"></script>
< </body>
---
> <body></body>
CSS code for the app is also removed even I kept the <% preact.headEnd %>
.
The app
div element and loading scripts, /bundle.58077.esm.js
, /polyfills.03bf6.js
and /polyfills.03bf6.js
, is the application itself, but removed also.
Thank you for reading!
CSS inlining should still be there, that's something unrelated.
There's some way to regex with the script src, though I forget exactly how.
Regardless, Preact-CLI is mainly for PWAs. You're mostly on your own if you want to cut out parts for an entirely different purpose. I don't think it really makes sense to add this functionality.
I think adding support for non-inlined scripts could help harden PWAs as well via CSP. Here is the React equivalent: https://medium.com/@nrshahri/csp-cra-324dd83fe5ff
@jmoore34 That's the CRA equivalent, which is just Webpack. You can configure Preact-CLI's Webpack config as-is, see preact-cli#webpack.
That big Safari nomodule polyfill is gone now, and anything remaining you can strip out in a post-build yourself really. If there's something that you can't easily alter in the config or is preventing you from configuring as you'd like, certainly let me know.
Closing this out, CLI's target is PWAs.