使用Vite将JS和CSS捆绑到单个文件中

问题描述 投票:0回答:8

我正在费尽心思地弄清楚如何在我的 Svelte 项目中从 Vite 构建单个 .js 文件,其中包括我的 Svelte 项目中构建的所有 javascript 和 CSS。默认情况下,Vite 将应用程序捆绑到一个 html 文件(这可以)、两个 .js 文件(为什么?)和一个 .css 文件(只想将其捆绑到一个 js 文件中)。

我运行了这个非常基本的命令来获取入门项目:

npx degit sveltejs/template myproject

我尝试添加几个插件,但我添加的任何插件都没有达到我想要的结果。首先,我发现的插件似乎想要创建一个包含所有内容的 HTML 文件。看来 PostCSS 可能会有所帮助,但我不明白我可以通过 Vite 设置什么配置来让它执行我想要的操作。

什么是神奇的插件和配置集,它将输出单个 HTML 文件和单个 js 文件,将我的 Svelte 应用程序及其 CSS 渲染到页面上?

javascript css bundle svelte vite
8个回答
29
投票

两步,

  • 我们可以使用
    vite-plugin-css-injected-by-js
    将 css 注入 js 资源中。
  • 我们可以通过在 rollup 的配置中禁用块来发出单个 js 资源。

最终结果,

import cssInjectedByJsPlugin from "vite-plugin-css-injected-by-js";

export default defineConfig({
  plugins: [cssInjectedByJsPlugin()],
  build: {
    rollupOptions: {
      output: {
        manualChunks: undefined,
      },
    },
  },
});

正如下面 @TheRockerRush 所建议的,您可能希望使用 vite-plugin-singlefile 将所有代码捆绑到单个 .html 文件中,尽管 OP 要求单个 .js 文件。


10
投票

如果您正在寻找解决方案,您可能需要查看 vite-plugin-singlefile


6
投票

这对于 vite 来说并不是开箱即用的,但你可以编写一个快速插件来实现这一点

const bundle_filename = ''
const css_filename = 'style.css'

defineConfig({
  build: {
    lib: {
      entry: 'src/mycomponent.js',
      name: 'mycomponent.js',
      fileName: () => 'mycomponent.js',
      formats: ['iife'],
    },
    cssCodeSplit: false,
    rollupOptions: {
      plugins: [
        {
          apply: 'build',
          enforce: 'post',
          name: 'pack-css',
          generateBundle(opts, bundle) {
            const {
              [css_filename]: { source: rawCss },
              [bundle_filename]: component,
            } = bundle

            const IIFEcss = `
            (function() {
              try {
                  var elementStyle = document.createElement('style');
                  elementStyle.innerText = ${JSON.stringify(rawCss)}
                  document.head.appendChild(elementStyle)
              } catch(error) {
                console.error(error, 'unable to concat style inside the bundled file')
              }
            })()`

            component.code += IIFEcss

            // remove from final bundle
            delete bundle[css_filename]
          },
        },
      ],
    },
  },
})

3
投票

我遇到了同样的问题,并且能够通过编辑

vite.config.ts
来修复,如下在
[email protected]

上进行测试
export default {
  build: {
    rollupOptions: {
      output: {
        manualChunks: undefined,
      },
    },
  },
};

2
投票

我为这个问题创建了一个样板 Vite 项目:
https://github.com/mvsde/svelte-micro-frontend

也许配置对您的情况有所帮助:

import { defineConfig } from 'vite'
import { svelte } from '@sveltejs/vite-plugin-svelte'

export default defineConfig({
  plugins: [
    svelte({
      emitCss: false
    })
  ],

  build: {
    assetsDir: '',
    sourcemap: true,
    lib: {
      entry: 'src/main.js',
      formats: ['iife'],
      name: 'SvelteMicroFrontend',
      fileName: 'svelte-micro-frontend'
    }
  }
})

2
投票

如果您正在使用 Svelte,则可以使用

emitCss
:

export default defineConfig({
    plugins: [svelte({
        emitCss: false,
    })],
})

0
投票

由于

manualChunks
不再适用于最新版本的 Vite,因此没有任何方法可以将所有块合并为一个。

但是找到了一个在构建后有

index.html
+
bundle.js
的黑客解决方案:https://github.com/d-velopment/SvelteKit-One-Bundle - 它重新包装了项目的初始 .js 文件。来自bundle.js,可以从index.html或外部项目加载。


0
投票

现在您可以使用:

https://www.npmjs.com/package/vite-plugin-singlefile

npm i vite-plugin-singlefile

import { defineConfig } from "vite"
import vue from "@vitejs/plugin-vue"
import { viteSingleFile } from "vite-plugin-singlefile"

export default defineConfig({   
plugins: [vue(), viteSingleFile()]
})

© www.soinside.com 2019 - 2024. All rights reserved.