问题
I can't find any example anywhere online that shows how to (or if we can) output a single HTML file from a Svelte project using Rollup (not Webpack), containing all CSS and JS injected inline (and not as URLs in script).
回答1:
There is no built-in way to achieve this, so you'll have to write your own plugin to do so. This code is some sort of an attemt to get this done and could act as a starter point. It is in no way actually complete or good. (to be honest I doubt you will be winning any sort of performance with this approach)
import svelte from 'rollup-plugin-svelte';
import fs from 'fs';
import path from 'path';
function inlineSvelte(template, dest) {
return {
name: 'Svelte Inliner',
generateBundle(opts, bundle) {
const file = path.parse(opts.file).base
const code = bundle[file].code
const output = fs.readFileSync(template, 'utf-8')
bundle[file].code = output.replace('%%script%%', code)
}
}
}
export default {
input: 'src/main.js',
output: {
format: 'iife',
file: './public/index.html',
name: 'app'
},
plugins: [
svelte({
}),
inlineSvelte('./src/template.html')
]
};
This will rely on a template.html file that in it's most basic would like this
<html>
<head>
<script>%%script%%</script>
</head>
<body></body>
</html>
回答2:
inliner can help
limit: inliner cant handle defer
scripts
so in your public/index.html
template file
move
<head>
<script defer src="/build/bundle.js"></script>
</head>
to after the </body>
tag, like
</body>
<script src="/build/bundle.js"></script>
</html>
now run inliner
npm i -D inliner
npm run build
npm run start &
sleep 5 # wait for webserver to start
npx inliner \
http://localhost:5000/index.html \
>build/index-inlined.html
回答3:
The accepted answer should work though for Svelte 3
I have to modify it as follows:
// rollup.config.js
import svelte from 'rollup-plugin-svelte'
import resolve from '@rollup/plugin-node-resolve'
export default {
input: 'Static.svelte',
output: {
file: 'static.html'
},
plugins: [
svelte(),
resolve(),
{
generateBundle(options, bundle) {
const name = path.parse(options.file).base // static.html
const module = bundle[name].facadeModuleId // Static.svelte
// We ignore the bundle[name].code generated by other plugins
// and load the input module explicitly instead.
require('svelte/register')
const Static = require(module).default
bundle[name].code = Static.render().html
}
}
]
}
In the above code we have to use the *-svelte
plugin because Rollup accepts only Javascript
. Here the Rollup is used just to follow a familiar building process, we see input and output files' names in one place, and it saves the output file.
Use npm
as an alternative way (much faster):
// static.js
require('svelte/register')
const Static = require('Static.svelte').default
console.log(Static.render().html)
// package.json
{ ...
"scripts": {
"build": "node static.js > static.html"
}
}
来源:https://stackoverflow.com/questions/61565251/output-single-html-file-from-svelte-project