如何将 Vite 构建包装在 IIFE 中,并且仍然将所有依赖项捆绑到单个文件中?

2024-01-17

我正在使用 Vite 作为构建工具构建 chrome 扩展。主要问题在缩小和修改过程中,创建了很多全局变量。将我的脚本注入页面后,它们与窗口对象上已定义的变量发生冲突。

我想完美的解决方案是将我的整个脚本封装在 IIFE 中。我尝试使用esbuild.format = 'iife'。生成的构建实际上包含在 IIFE 中,但是所有导入都不是内联的。相反,生成的脚本大约有 15 行长,其中包含一堆require语句,这显然在浏览器中不起作用。

这是我的配置文件:

export default defineConfig({
  plugins: [
    vue(),
  ],
  esbuild: {
    format: 'iife',
  },
  build: {
    emptyOutDir: false,
    rollupOptions: {
      input: resolve(__dirname, './src/web/index.ts'),
      output: {
        dir: resolve(__dirname, './dist'),
        entryFileNames: 'web.js',
        assetFileNames: 'style.css',
      },
    },
  },
  resolve: {
    alias: {
      '@': resolve(__dirname, './src'),
    },
  },
});

我目前正在使用这个黑客 https://github.com/vitejs/vite/issues/7188也就是说,将我的构建包装在 IIFE 中(为此,我删除了esbuild.format选项)。


嘿,我正在做同样的事情!我还注意到未缩小的变量和函数可能会与网页中的随机代码发生冲突。

根据我对这个主题的研究,你不应该改变esbuild使用 Vite 构建选项,因为这会阻止 Rollup 转换输出。相反,你应该使用format: 'iife' in the rollupOptions你的vite.config。但是,就我而言(我相信也是你的情况),我必须输出多个包,因为扩展代码无法在彼此之间共享模块。当您将格式设置为“iife”时,由于以下原因,它会崩溃:

Invalid value for option "output.inlineDynamicImports" - multiple inputs are not supported when "output.inlineDynamicImports" is true.

在我的例子中唯一的解决方案似乎是使用多个vite.configs(我已经有两个)对于我的每个包都有一个input入口点和格式为“iife”。或者,就像您所做的那样,只需使用一些 hacky 脚本自己编写自调用函数即可。目前看来还没有完美的解决方案。

编辑:好的,开始工作了。这是我的vite.config.ts (该项目 https://github.com/TeemuKoivisto/prosemirror-dev-toolkit):

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

import path from 'path'

/** @type {import('vite').UserConfig} */
export default defineConfig({
  plugins: [svelte({}), tsconfigPaths()],
  build: {
    minify: false,
    rollupOptions: {
      output: {
        chunkFileNames: '[name].js',
        entryFileNames: '[name].js'
      },
      input: {
        inject: path.resolve('./src/inject.ts'),
        proxy: path.resolve('./src/proxy.ts'),
        'pop-up': path.resolve('./pop-up.html')
      },
      plugins: [
        {
          name: 'wrap-in-iife',
          generateBundle(outputOptions, bundle) {
            Object.keys(bundle).forEach((fileName) => {
              const file = bundle[fileName]
              if (fileName.slice(-3) === '.js' && 'code' in file) {
                file.code = `(() => {\n${file.code}})()`
              }
            })
          }
        }
      ]
    }
  }
})
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何将 Vite 构建包装在 IIFE 中,并且仍然将所有依赖项捆绑到单个文件中? 的相关文章

随机推荐