vite icon indicating copy to clipboard operation
vite copied to clipboard

当构建库时使用 rollupOptions.output.banner 会导致打包出错误的 umd

Open ddosakura opened this issue 3 years ago • 8 comments

Describe the bug

also see #8163.

I determined that this was caused by #7948 and has not been fixed in #8110.

I currently use version 2.9.5 to avoid this problem.

I also tried v3.0.0-alpha 7. It has not been fixed at present.


我也遇到了 #8163 这个问题。

我确定这是由 #7948 引入的错误的正则替换导致的,并且并未在 #8110 中得到修复。

我目前使用 2.9.5 版本来避免这个问题。

我也尝试使用了v3.0.0-alpha.7,目前并未得到修复。

Reproduction

https://github.com/ddosakura/a-bug-for-vite/blob/master/dist/mylib.umd.js

System Info

Binaries:
    Node: 16.14.2 - ~/.nvm/versions/node/v16.14.2/bin/node
    Yarn: 1.22.15 - ~/.nvm/versions/node/v16.14.2/bin/yarn
    npm: 8.5.0 - ~/.nvm/versions/node/v16.14.2/bin/npm
  npmPackages:
    vite: ^2.9.9 => 2.9.9 

or

  Binaries:
    Node: 16.14.2 - ~/.nvm/versions/node/v16.14.2/bin/node
    Yarn: 1.22.15 - ~/.nvm/versions/node/v16.14.2/bin/yarn
    npm: 8.5.0 - ~/.nvm/versions/node/v16.14.2/bin/npm
  npmPackages:
    vite: ^3.0.0-alpha.7 => 3.0.0-alpha.7

Used Package Manager

pnpm

Logs

No response

Validations

ddosakura avatar May 31 '22 08:05 ddosakura

A plugin like this could be used to workaround it.

const bannerPlugin = {
  name: 'banner',
  enforce: 'post',
  generateBundle(options, bundle) {
    const banner = '/*! banner  */'
    const footer = ''

    for (const module of Object.values(bundle)) {
      if (module.type === 'chunk') {
        module.code = banner + module.code + footer
        // should change source map if needed
      }
    }
  }
}

sapphi-red avatar May 31 '22 11:05 sapphi-red

像这样的插件可以用来解决它。

const bannerPlugin = {
  name: 'banner',
  enforce: 'post',
  generateBundle(options, bundle) {
    const banner = '/*! banner  */'
    const footer = ''

    for (const module of Object.values(bundle)) {
      if (module.type === 'chunk') {
        module.code = banner + module.code + footer
        // should change source map if needed
      }
    }
  }
}

I found that the key to the bug was not rollupOptions.output.banner, but \n, see #8414 . @sapphi-red

ddosakura avatar May 31 '22 12:05 ddosakura

That PR will work for comments but it won't work with something like var someValueInjected = Object.assign({}, { value: 'by rollup.banner' });.

~~That said that PR will fix a bug when build.minify is false.~~ No, actually it didin't.

sapphi-red avatar May 31 '22 13:05 sapphi-red

Reopening as it is not completely fixed. https://github.com/vitejs/vite/pull/8414#pullrequestreview-991785346

sapphi-red avatar Jun 01 '22 13:06 sapphi-red

I adjusted the workaround plugin slightly to keep using build.rollupOptions.output.banner/.footer in my vite.config.js

// rollup-banner-plugin.js
const RollupBannerPlugin = {
  name: 'banner',
  enforce: 'post',
  generateBundle(options, bundle) {
    const banner = options.banner() || ''
    const footer = options.footer() || ''

    for (const module of Object.values(bundle)) {
      if (module.type === 'chunk') {
        module.code = banner + module.code + footer
        // should change source map if needed
      }
    }
  }
}
// vite.config.js
import RollupBannerPlugin from './rollup-banner-plugin.js'
export default defineConfig({
  build: {
  ...
    rollupOptions: {
      output: {
        banner: '/** Here goes my banner */\n\n',
        footer: '\n\n/** and here some footer notes. */',
      },
      plugins: [
        RollupBannerPlugin
      ]
    }
  }
})

abernh avatar Oct 07 '22 12:10 abernh

The workaround works, but I think it should work from the box, when a person uses Vite in the library mode.

AlttiRi avatar Apr 17 '23 18:04 AlttiRi

However, there is a bug with this workaround — it duplicates the line with "licence" text.

For the follow text:

// ==UserScript==
// @name        HrefTaker
// @license     GPL-3.0
// @version     0.7.1-2023.4.17
// @namespace   gh.alttiri
// ==/UserScript==

the result is

// ==UserScript==
// @name        HrefTaker
// @license     GPL-3.0
// @version     0.7.1-2023.4.17
// @namespace   gh.alttiri
// ==/UserScript==
// @license     GPL-3.0

with unnecessary appended // @license GPL-3.0.


The raw Rollup works fine:

import {rollup} from "rollup";

const bundle = await rollup({
  input: "./main.js",
});

await bundle.write({
  banner: `// ==UserScript==
// @name        HrefTaker
// @license     GPL-3.0
// @version     0.7.1-2023.4.17
// @namespace   gh.alttiri
// ==/UserScript==\n`,
    dir: "./dist"
});

It seems this issue reason is that Vite (even with minify: false) additionally removes all comments and empty lines from the bundle.

I see no option to disable it.

AlttiRi avatar Apr 17 '23 23:04 AlttiRi

slightly modified version to keep shebang when your have some.

const RollupBannerPlugin = {
  name: 'banner',
  enforce: 'post',
  generateBundle(options, bundle) {
    const banner = options.banner() || ''
    const footer = options.footer() || ''

    for (const module of Object.values(bundle)) {
      if (module.type === 'chunk') {
        const shebang = module.code.match(/^#![^\n]*\n/)
        if (shebang) {
          module.code = shebang[0] + banner + module.code.slice(shebang[0].length) + footer
        } else {
          module.code = banner + module.code + footer
        }
        // should change source map if needed
      }
    }
  }
}```

malko avatar Sep 26 '24 16:09 malko