Search code examples
javascriptnode.jsreactjswebpackreact-snap

Prevent react-snap from putting all JS script links into generated files


I'm messing around with using react-snap to pre-render my new blog, and everything works quite fantastically except for a few things.

For some reason, scripts were being included in the headers, but I was able to apply async attributes to those scripts, so it wasn't that big a deal. But then I realized that there is no reason the majority of my scripts are being included in the first place...

There is no dynamic content in the blog, it's all just CSS/HTML, and I only used React to simplify development - however, I have Markdown libraries still included in the HTML, as well as react-dom, react-router and some others.

Given this package.json:

"scripts": {
    "build": "TS_NODE_PROJECT='tsconfig-webpack.json' webpack --mode production",
    "dev": "TS_NODE_PROJECT='tsconfig-webpack.json' webpack-dev-server --mode development --hot",
    "format": "prettier --write \"{./**/*.{ts,js,json,scss,css,less,md}*, !(node_modules)/**/*}\"",
    "postbuild": "react-snap",
    "test": "jest",
    "testing": "jest --watch"
},
"reactSnap": {
    "inlineCss": true,
    "sourceMaps": false,
    "asyncScriptTags": true
}

At the bottom of all of my pre-generated posts, I have:

<script async src="/runtime.d0e50ef7a54258c04b4b.js" type="text/javascript"></script>
<script async src="/npm.highlight.js.948b8c6fe7c6dff967e6.js" type="text/javascript"></script>
<script async src="/npm.remark-parse.752d87940c4e3c27644f.js" type="text/javascript"></script>
<script async src="/npm.js-yaml.38d965a6b2c1867313a0.js" type="text/javascript"></script>
<script async src="/npm.date-fns.e514c2b76cfb0e33eae1.js" type="text/javascript"></script>
<script async src="/npm.react-router.38c6735027e6ab8d92dc.js" type="text/javascript"></script>
<script async src="/npm.react-dom.43e459d17b017d4525f7.js" type="text/javascript"></script>
<script async src="/npm.buffer.03943cd6611cbaf46bd8.js" type="text/javascript"></script>
<script async src="/npm.esprima.485b4b9d10b5eb3bd8f0.js" type="text/javascript"></script>
<script async src="/vendors~main.f2266dc8cae4f4636b15.js" type="text/javascript"></script>
<script async src="/main.e3335690c0cf73e2a36c.js" type="text/javascript"></script>

BUT! (Except for maybe highlight.js) none of them are used!

Note: I know that putting JS files at the bottom of the body and having them marked async might be redundant/unnecessary, but for some reason after the snappening, those JS files are sometimes placed in the header (I have no clue why) - so for performance safety, I have react-snap marking them async.

Is there any way I can just stop the inclusion of any/all/some of my JS files? I know I can do this manually, or via some post-processing on the 100+ articles, but I feel like this must also be part of puppeteer or react-snap already.

EDIT: Sigh... As usual, even though I searched for this before, 5 minutes after posting an SO post - I came across a partial answer: removeScriptTags: true in the react-snap package.json

That satisfies the case where I want to remove ALL my scripts, however, is there any partial solution? For example, let's say I want to turn this blog into a PWA - and thus might need to register a service worker (or maybe I come across another use case where I need 1-2 JS files)


Solution

  • Well, you already found the partial solution. Unfortunately, no way to remove just some tags. In fact, removeScriptTags is likely to get dropped. Someone made a fork to implement that same feature you are asking for. See this issue for details: https://github.com/stereobooster/react-snap/issues/298

    To avoid having to fork or modify react-snap, you could instead write your own script, which loads the output and does something very similar to what react-snap would be doing with removeScriptTags, but selecting which scripts to yank. See the original implementation here: https://github.com/stereobooster/react-snap/blob/master/index.js#L232

    Then just add that script in your postbuild, after react-snap.