Output Single HTML File from Svelte Project

梦想的初衷 提交于 2021-01-27 14:52:38

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!