从 Svelte 项目输出单个 HTML 文件

Output Single HTML File from Svelte Project

我在网上找不到任何示例来说明如何(或者如果我们可以)使用 Rollup(不是 Webpack)从 Svelte 项目输出单个 HTML 文件,其中包含所有 CSS 和 JS 内联注入(而不是脚本中的 URL)。

没有实现此目的的内置方法,因此您必须编写自己的插件才能实现。此代码是完成此操作的某种尝试,可以作为起点。它绝不是真正完整或好的。 (老实说,我怀疑你会用这种方法赢得任何形式的表现)

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')
    ]
};

这将依赖于一个 template.html 文件,最基本的文件就是这样

<html>
    <head>
        <script>%%script%%</script>
    </head>
    <body></body>
</html>

inliner 可以帮忙

限制:内联器无法处理 defer 脚本
所以在你的 public/index.html 模板文件中
移动

  <head>
    <script defer src="/build/bundle.js"></script>
  </head>

</body> 标签之后,喜欢

  </body>
  <script src="/build/bundle.js"></script>
</html>

现在运行内联

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

接受的答案应该适用于 Svelte 3 我必须按如下方式修改它:

// 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
      }
   }
  ]
}

在上面的代码中,我们必须使用 *-svelte 插件,因为 Rollup 只接受 Javascript。这里使用 Rollup 只是为了遵循熟悉的构建过程,我们在一个地方看到输入和输出文件的名称,并保存输出文件。

使用 npm 作为替代方法(更快):

// 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"
  }
}