Improve integration with @vite/plugin-legacy #928
Replies: 15 comments
-
Done (9b9f551).
Done (d578381).
I'm open to this as long as it doesn't decrease VPS maintainability all too much. We could also make @vitejs/plugin-legacy export that functionality for VPS (and others) to directly import instead of going over Vite. The proper way would be to add a Vite feature enabling plugins to provide FYI this how VPS currently handles |
Beta Was this translation helpful? Give feedback.
-
Wow, that was super quick, thank you so much.
I agree that this might be the biggest problem. |
Beta Was this translation helpful? Give feedback.
-
Hi, I am also trying to setup legacy plugin. and i noticed, that this commit because of It is necessary? or can it be loosened somehow? Thanks :) |
Beta Was this translation helpful? Give feedback.
-
Removing the line, fixes the problem |
Beta Was this translation helpful? Give feedback.
-
Does |
Beta Was this translation helpful? Give feedback.
-
Hi, yes it works. Thanks :) |
Beta Was this translation helpful? Give feedback.
-
👍 Released as |
Beta Was this translation helpful? Give feedback.
-
@brillout |
Beta Was this translation helpful? Give feedback.
-
You can already use VPS with |
Beta Was this translation helpful? Give feedback.
-
sorry, Maybe I didn't express it clearly, i used just wanna cover most of mobile phones. when <!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" type="text/css" href="/assets/_default.page.client.cc733d7d.css">
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="App using Vite + vite-plugin-ssr" />
<title>Vite SSR app</title>
</head>
<body>
<div id="app"> some doms </div>
<script type="module" src="/assets/entry-server-routing.0e8173a5.js" defer></script>
<link rel="modulepreload" href="/assets/src/pages/index/index.page.545e05bb.js" as="script" type="text/javascript">
<link rel="modulepreload" href="/assets/chunk-101896b7.js" as="script" type="text/javascript">
<link rel="modulepreload" href="/assets/chunk-ce4476bd.js" as="script" type="text/javascript">
<link rel="modulepreload" href="/assets/renderer/_default.page.client.03a442f4.js" as="script" type="text/javascript">
<link rel="modulepreload" href="/assets/chunk-3adbf793.js" as="script" type="text/javascript">
<script id="vite-plugin-ssr_pageContext" type="application/json">{"pageContext":{"_pageId":"/src/pages/index/index","pageProps":"!undefined","urlPathname":"/"}}</script>
</body>
</html>
how can i get both modern assets and legacy assets in responsed html ? <!DOCTYPE html>
<html lang="en">
<head>
<!-- injected if modern polyfills are enabled. Leave out if no such file exists -->
<script type="module" crossorigin src="/assets/polyfills.29399a5e.js"></script>
<!-- regular head content goes here... -->
<!-- feature detection. This snippet is always identical -->
<script type="module">try{import.meta.url;import("_").catch(()=>1);}catch(e){}window.__vite_is_modern_browser=true;</script>
<script type="module">!function(){if(window.__vite_is_modern_browser)return;console.warn("vite: loading legacy build because dynamic import or import.meta.url is unsupported, syntax error above should be ignored");var e=document.getElementById("vite-legacy-polyfill"),n=document.createElement("script");n.src=e.src,n.onload=function(){System.import(document.getElementById('vite-legacy-entry').getAttribute('data-src'))},document.body.appendChild(n)}();</script>
</head>
<body>
<!-- regular body content goes here... -->
<!-- script loader. This snippet is always identical. -->
<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>
<!-- legacy polyfill chunk. Leave out if no such file can be found. -->
<script nomodule crossorigin id="vite-legacy-polyfill" src="/assets/polyfills-legacy.d29a7a52.js"></script>
<!-- legacy entry. Here we need to inject the correct legacy chunk -->
<script nomodule crossorigin id="vite-legacy-entry" data-src="/assets/entry-server-routing-legacy.6fabb6ae.js">System.import(document.getElementById('vite-legacy-entry').getAttribute('data-src'))</script>
</body>
</html> |
Beta Was this translation helpful? Give feedback.
-
I'm not that familiar with |
Beta Was this translation helpful? Give feedback.
-
just confused,cuz after but when server rendering : got _pageAssets like this, no more curious how VPS got page's assets in server side? |
Beta Was this translation helpful? Give feedback.
-
It uses the module graph information at |
Beta Was this translation helpful? Give feedback.
-
well,in my opinion,
It is not possible to Implement the logic of all plug-ins,maybe just modified or combine those compiled html/blocks will much flexible, and doesn't decrease VPS maintainability~~~ |
Beta Was this translation helpful? Give feedback.
-
I'm afraid I didn't understand your message. Feel free to create a reproduction with a clear description of what you want VS what is happening. |
Beta Was this translation helpful? Give feedback.
-
Description
I know this issue has been posed before (#39), but I would like to open it again from a different angle because I HAVE a working solution, it is just quite hacky, and I would like to improve it. Also, there is one issue when using the plugin in older Edge browsers that should be easy to fix from your side.
Before going for the solution, let me motivate why I need the plugin in the first place. For me, it is not at all about IE11—that one is definitely dead. For me, it is about older phones. The current Vite baseline is dynamic
import()
+import.meta.url
support. This leaves out about 5% of users (https://caniuse.com/?search=import.meta) and for instance everyone stuck on Safari 10.And I do not think this has been the final time this baseline will be moved. For instance support for module workers (https://caniuse.com/?search=module%20worker) or import assertions could theoretically become part of the baseline in the future.
So here is my approach:
https://github.com/lukastaegert/vite-plugin-ssr-legacy
It works like this:
vite-plugin-ssr
and the legacy plugin. We needdisableAutoFullBuild: true
because otherwise, the extra build triggered by@vite/plugin-legay
will also trigger thessr
plugin which then will fail because there is nomanifest.json
(possible improvement:vite-plugin-ssr
detects this extra build and ignores it, or does something else sensible).vite build --ssr
so that the server files are generated.vite build
. This also triggers a nested build from@vite/plugin-legacy
that generates a-legacy.js
file for every regular generated file. AtbundleClose
, a special plugin kicks in thatprerender
function to generate the HTML files.entry-server-routing.[hash].js
entry-server-routing-legacy.[hash].js
transformIndexHtml
hook of the legacy plugin first on a simulated legacy chunk to set some internal state of the legacy plugin, and then again on a simulated "modern" chunk that will actually inject the legacy code. This is a really tricky step where I blindly copied quite a bit of logic from Vite to be able to parse the non-trivial response from that hook.To test this solution actually works, I downloaded a VM from https://developer.microsoft.com/en-us/microsoft-edge/tools/vms/ and tested the production build. I am working against "MSEdge von Win10", which supports ES6 imports but no dynamic imports or
import.meta.url
.With client routing, there is a bug that occurs when using
That triggers a history initialization with a
history.replaceState(someObject, undefined, undefined)
. In old Edge if you pass an explicitundefined
as the third parameter here, it actively changes the url to/undefined
. The fix would be as simple as changing https://github.com/brillout/vite-plugin-ssr/blob/aabfde988d2e427a9af78f3d8765276455947fb2/vite-plugin-ssr/client/router/history.ts#L81-L83 tobecause
null
indeed works as expected even in old Edge.Beyond that, here are things where I hope we can work to improve on
vite-plugin-ssr
:autoFullBuild
for pre-rendering. It could be as easy as detecting and ignoring that special run triggered by the legacy plugin.transformIndexHtml
hook. I am not sure this will be easily possible. The longer I think about it, the easiest way would probably be to do that as part of the plugin itself. The transforms are not terribly complicated. They could just be written as template strings where in the right place one would need to inject the name of the legacy chunk. Doing the transform yourself would also mean that it would not only work for pre-rendering, it could also work for true SSR. So it would mean when the plugin is detected,vite-plugin-ssr
automatically adds the necessary HTML transformations while the plugin just handles generating the legacy SystemJS JavaScript.Beta Was this translation helpful? Give feedback.
All reactions