vite
vite copied to clipboard
About @vitejs/plugin-legacy does not support library mode
Is your feature request related to a problem? Please describe. I'm a long time user of Vue in a webpack context and i'm giving a try to Vite. So far It's been a pleasant journey : Dev mode is really impressive !
My project consists of several standalone Vue components that are instantiated on demand from Vanilla Javascript. This is why they are currently built with the Webpack Library mode which works just fine.
I have successfully built these components with Vite (with dynamic import and everything) and they work juts fine on modern browser.
Describe the solution you'd like I'd like to also build those components for legacy browsers... And this is currently not allowed (error message : "@vitejs/plugin-legacy does not support library mode").
I'd like to know if there is still hope for this specific use case ?... And I also like to mention that these legacy builds don't have to be as polished as the es ones (considering that they will only be served to a small percentage of our visitors).
While I wish to give the best experience to the vast majority of my users (equipped with modern browsers), I would be fine with monolithic builds, without any code splitting or dynamic imports for legacy browsers. Maybe with something like Rollup's "inlineDynamicImports" ? After all, these legacy builds should vanish eventually.
Describe alternatives you've considered
Additional context Add any other context or screenshots about the feature request here.
Would love to see this implemented. As a developer who has to support IE11, Vite and its out-of-the-box speed and ease of use has been a blessing until I learned library mode doesn't support IE11 :(
I've been trying to get my library that was built with Vite working with https://observablehq.com, but so far to no avail. I thought maybe a legacy build would help, but unfortunately, that doesn't work at the moment as discussed here. 🤔
Hello ! @yyx990803 : what do you think would be needed to get that to work ? I have users on sanipasse.fr who are on old browsers and for whom the site is currently broken. I would be happy to contribute, but have no idea where to start.
Would love to see this implemented. As a developer who has to support IE11, Vite and its out-of-the-box speed and ease of use has been a blessing until I learned library mode doesn't support IE11 :(
Hope support soon.
Hope support soon.
Happy birthday to this issue 🎈🥳
Hope support soon.
IMHO, app which import the lib should care about to bunde it to be capable of old browser. It's not like build a site. So @vitejs/plugin-legacy doesn't need to support some IE 11. Thoughts?
I have figured out a solution to bundle lib supporting old browser without dependent @vitejs/plugin-legacy
although I insist that lib no need to worry about it.
Here is a sample config, hope to help anyone encountered this:
//vite.config.js
import { babel } from '@rollup/plugin-babel';
...
plugins: [
babel({
babelHelpers: 'runtime',
extensions: ['.js', '.jsx', '.es6', '.es', '.mjs', 'ts'],
})
]
//babel.config.js
module.exports = {
presets: [
[
'@babel/env',
{
useBuiltIns: 'usage',
corejs: 3,
},
],
],
plugins: ['@babel/plugin-transform-runtime'],
};
//package.json
"browserslist": [
"> 0.5%",
"not dead"
],
@wenjoy ts is ok ? i think esbuild will deal the ts
file but babel will not
@wenjoy ts is ok ? i think esbuild will deal the
ts
file but babel will not
esbuild will not transform to es5, but we cant config to let babel can handle ts even transform to es5.
我知道,你测试过这样写会进行转换ts么
@wenjoy ts is ok ? i think esbuild will deal the
ts
file but babel will notesbuild will not transform to es5, but we cant config to let babel can handle ts even transform to es5.
But the question is how ? :D
@wenjoy ts is ok ? i think esbuild will deal the
ts
file but babel will notesbuild will not transform to es5, but we cant config to let babel can handle ts even transform to es5.
But the question is how ? :D i tried, but the error told me Rollup failed to resolve import "@babel/runtime/helpers/typeof"
The following method should solve the problem, e.g:
// vite.config.js (e.g)
const { getBabelOutputPlugin } = require('@rollup/plugin-babel');
export default {
build: {
rollupOptions: {
plugins: [
/**
* Running Babel on the generated code:
* https://github.com/rollup/plugins/blob/master/packages/babel/README.md#running-babel-on-the-generated-code
*
* Transforming ES6+ syntax to ES5 is not supported yet, there are two ways to do:
* https://github.com/evanw/esbuild/issues/1010#issuecomment-803865232
* We choose to run Babel on the output files after esbuild.
*
* @vitejs/plugin-legacy does not support library mode:
* https://github.com/vitejs/vite/issues/1639
*/
getBabelOutputPlugin({
allowAllFormats: true,
presets: [
[
'@babel/preset-env',
{
useBuiltIns: false, // Default:false
// Exclude transforms that make all code slower
exclude: ['transform-typeof-symbol'],
// https://babeljs.io/docs/en/babel-preset-env#modules
modules: false,
},
],
],
plugins: [
/**
* Extract the helper function.
*/
[
'@babel/plugin-transform-runtime',
{
corejs: false,
// version: require('@babel/runtime').version,
},
],
],
}),
],
},
},
};
Running babel on the generated code by esbuild (vite).
The presets and plugins configuration of babel is only suitable for me, you can modify it.
I have figured out a solution to bundle lib supporting old browser without dependent
@vitejs/plugin-legacy
although I insist that lib no need to worry about it.Here is a sample config, hope to help anyone encountered this:
//vite.config.js import { babel } from '@rollup/plugin-babel'; ... plugins: [ babel({ babelHelpers: 'runtime', extensions: ['.js', '.jsx', '.es6', '.es', '.mjs', 'ts'], }) ]
//babel.config.js module.exports = { presets: [ [ '@babel/env', { useBuiltIns: 'usage', corejs: 3, }, ], ], plugins: ['@babel/plugin-transform-runtime'], };
//package.json "browserslist": [ "> 0.5%", "not dead" ],
its useful for js application when use vite
IMHO, app which import the lib should care about to bunde it to be capable of old browser. It's not like build a site. So @vitejs/plugin-legacy doesn't need to support some IE 11. Thoughts?
This rationale does not consider building a UMD formatted bundle (which is one of the default build formats), or an IIFE format, both of which can be directly included onto a page in older browsers.
it's work for me:
pnpm i -D @babel/plugin-transform-runtime @babel/preset-env @babel/runtime @rollup/plugin-babel
// vite.config.ts
import { fileURLToPath, URL } from 'node:url'
import { resolve } from 'path'
import type { ConfigEnv, UserConfigExport } from 'vite'
import vue from '@vitejs/plugin-vue'
import vueJsx from '@vitejs/plugin-vue-jsx'
import svgLoader from 'vite-svg-loader'
import cssInjectedByJsPlugin from 'vite-plugin-css-injected-by-js'
import babel from '@rollup/plugin-babel'
export default ({ command, mode }: ConfigEnv): UserConfigExport => {
const config: UserConfigExport = {
plugins: [vue(), vueJsx(), cssInjectedByJsPlugin(), svgLoader()],
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url)),
},
},
build: {
minify: 'terser',
terserOptions: {
compress: {
drop_console: true,
drop_debugger: true,
},
},
lib: {
entry: resolve(__dirname, 'src/index.ts'),
name: 'IntegrationPlatformNavbar',
fileName: 'integration-platform-navbar',
},
rollupOptions: {
// 确保外部化处理那些你不想打包进库的依赖
external: ['vue', 'element-plus'],
output: {
// 在 UMD 构建模式下为这些外部化的依赖提供一个全局变量
globals: {
vue: 'Vue',
'element-plus': 'ElementPlus',
},
},
plugins: [
babel({
extensions: ['.js', '.ts', '.vue'],
babelHelpers: 'runtime',
plugins: ['@babel/plugin-transform-runtime'],
presets: [
[
'@babel/preset-env',
{
useBuiltIns: false,
targets: {
browsers: ['last 2 versions', '> 1%', 'not ie <= 11'],
},
},
],
],
}),
],
},
},
}
return config
}
it's work for me:
pnpm i -D @babel/plugin-transform-runtime @babel/preset-env @babel/runtime @rollup/plugin-babel
// vite.config.ts import { fileURLToPath, URL } from 'node:url' import { resolve } from 'path' import type { ConfigEnv, UserConfigExport } from 'vite' import vue from '@vitejs/plugin-vue' import vueJsx from '@vitejs/plugin-vue-jsx' import svgLoader from 'vite-svg-loader' import cssInjectedByJsPlugin from 'vite-plugin-css-injected-by-js' import babel from '@rollup/plugin-babel' export default ({ command, mode }: ConfigEnv): UserConfigExport => { const config: UserConfigExport = { plugins: [vue(), vueJsx(), cssInjectedByJsPlugin(), svgLoader()], resolve: { alias: { '@': fileURLToPath(new URL('./src', import.meta.url)), }, }, build: { minify: 'terser', terserOptions: { compress: { drop_console: true, drop_debugger: true, }, }, lib: { entry: resolve(__dirname, 'src/index.ts'), name: 'IntegrationPlatformNavbar', fileName: 'integration-platform-navbar', }, rollupOptions: { // 确保外部化处理那些你不想打包进库的依赖 external: ['vue', 'element-plus'], output: { // 在 UMD 构建模式下为这些外部化的依赖提供一个全局变量 globals: { vue: 'Vue', 'element-plus': 'ElementPlus', }, }, plugins: [ babel({ extensions: ['.js', '.ts', '.vue'], babelHelpers: 'runtime', plugins: ['@babel/plugin-transform-runtime'], presets: [ [ '@babel/preset-env', { useBuiltIns: false, targets: { browsers: ['last 2 versions', '> 1%', 'not ie <= 11'], }, }, ], ], }), ], }, }, } return config }
it works!
When I use useBuiltIns:"useage"
,It can't run......
In fact, it look like import"core-js/modules/esnext.global-this.js";
in my bundle file.But I want to use "inline" mode.
it's work for me:
pnpm i -D @babel/plugin-transform-runtime @babel/preset-env @babel/runtime @rollup/plugin-babel
// vite.config.ts import { fileURLToPath, URL } from 'node:url' import { resolve } from 'path' import type { ConfigEnv, UserConfigExport } from 'vite' import vue from '@vitejs/plugin-vue' import vueJsx from '@vitejs/plugin-vue-jsx' import svgLoader from 'vite-svg-loader' import cssInjectedByJsPlugin from 'vite-plugin-css-injected-by-js' import babel from '@rollup/plugin-babel' export default ({ command, mode }: ConfigEnv): UserConfigExport => { const config: UserConfigExport = { plugins: [vue(), vueJsx(), cssInjectedByJsPlugin(), svgLoader()], resolve: { alias: { '@': fileURLToPath(new URL('./src', import.meta.url)), }, }, build: { minify: 'terser', terserOptions: { compress: { drop_console: true, drop_debugger: true, }, }, lib: { entry: resolve(__dirname, 'src/index.ts'), name: 'IntegrationPlatformNavbar', fileName: 'integration-platform-navbar', }, rollupOptions: { // 确保外部化处理那些你不想打包进库的依赖 external: ['vue', 'element-plus'], output: { // 在 UMD 构建模式下为这些外部化的依赖提供一个全局变量 globals: { vue: 'Vue', 'element-plus': 'ElementPlus', }, }, plugins: [ babel({ extensions: ['.js', '.ts', '.vue'], babelHelpers: 'runtime', plugins: ['@babel/plugin-transform-runtime'], presets: [ [ '@babel/preset-env', { useBuiltIns: false, targets: { browsers: ['last 2 versions', '> 1%', 'not ie <= 11'], }, }, ], ], }), ], }, }, } return config }
replaceAll not be polyfill
it's work for me:这对我有用:
pnpm i -D @babel/plugin-transform-runtime @babel/preset-env @babel/runtime @rollup/plugin-babel
// vite.config.ts import { fileURLToPath, URL } from 'node:url' import { resolve } from 'path' import type { ConfigEnv, UserConfigExport } from 'vite' import vue from '@vitejs/plugin-vue' import vueJsx from '@vitejs/plugin-vue-jsx' import svgLoader from 'vite-svg-loader' import cssInjectedByJsPlugin from 'vite-plugin-css-injected-by-js' import babel from '@rollup/plugin-babel' export default ({ command, mode }: ConfigEnv): UserConfigExport => { const config: UserConfigExport = { plugins: [vue(), vueJsx(), cssInjectedByJsPlugin(), svgLoader()], resolve: { alias: { '@': fileURLToPath(new URL('./src', import.meta.url)), }, }, build: { minify: 'terser', terserOptions: { compress: { drop_console: true, drop_debugger: true, }, }, lib: { entry: resolve(__dirname, 'src/index.ts'), name: 'IntegrationPlatformNavbar', fileName: 'integration-platform-navbar', }, rollupOptions: { // 确保外部化处理那些你不想打包进库的依赖 external: ['vue', 'element-plus'], output: { // 在 UMD 构建模式下为这些外部化的依赖提供一个全局变量 globals: { vue: 'Vue', 'element-plus': 'ElementPlus', }, }, plugins: [ babel({ extensions: ['.js', '.ts', '.vue'], babelHelpers: 'runtime', plugins: ['@babel/plugin-transform-runtime'], presets: [ [ '@babel/preset-env', { useBuiltIns: false, targets: { browsers: ['last 2 versions', '> 1%', 'not ie <= 11'], }, }, ], ], }), ], }, }, } return config }
我这样配置后,构建产物里有旧浏览器不支持的语法:
var createPropertyDescriptor$8 = function createPropertyDescriptor2(bitmap, value) {
return {
enumerable: !(bitmap & 1),
configurable: !(bitmap & 2),
writable: !(bitmap & 4),
value
};
};
这里的 'value' 在旧浏览器中不兼容,这些代码应该是babel 加入进去的,很奇怪,我使用版本是:
"@babel/plugin-transform-runtime": "^7.23.7",
"@babel/preset-env": "^7.23.8",
"@babel/runtime": "^7.23.8",
"@babel/runtime-corejs3": "^7.23.8",
"@rollup/plugin-babel": "^5.3.1",
"vite": "^5.0.11",
it's work for me:这对我有用:
pnpm i -D @babel/plugin-transform-runtime @babel/preset-env @babel/runtime @rollup/plugin-babel
// vite.config.ts import { fileURLToPath, URL } from 'node:url' import { resolve } from 'path' import type { ConfigEnv, UserConfigExport } from 'vite' import vue from '@vitejs/plugin-vue' import vueJsx from '@vitejs/plugin-vue-jsx' import svgLoader from 'vite-svg-loader' import cssInjectedByJsPlugin from 'vite-plugin-css-injected-by-js' import babel from '@rollup/plugin-babel' export default ({ command, mode }: ConfigEnv): UserConfigExport => { const config: UserConfigExport = { plugins: [vue(), vueJsx(), cssInjectedByJsPlugin(), svgLoader()], resolve: { alias: { '@': fileURLToPath(new URL('./src', import.meta.url)), }, }, build: { minify: 'terser', terserOptions: { compress: { drop_console: true, drop_debugger: true, }, }, lib: { entry: resolve(__dirname, 'src/index.ts'), name: 'IntegrationPlatformNavbar', fileName: 'integration-platform-navbar', }, rollupOptions: { // 确保外部化处理那些你不想打包进库的依赖 external: ['vue', 'element-plus'], output: { // 在 UMD 构建模式下为这些外部化的依赖提供一个全局变量 globals: { vue: 'Vue', 'element-plus': 'ElementPlus', }, }, plugins: [ babel({ extensions: ['.js', '.ts', '.vue'], babelHelpers: 'runtime', plugins: ['@babel/plugin-transform-runtime'], presets: [ [ '@babel/preset-env', { useBuiltIns: false, targets: { browsers: ['last 2 versions', '> 1%', 'not ie <= 11'], }, }, ], ], }), ], }, }, } return config }
我这样配置后,构建产物里有旧浏览器不支持的语法:
var createPropertyDescriptor$8 = function createPropertyDescriptor2(bitmap, value) { return { enumerable: !(bitmap & 1), configurable: !(bitmap & 2), writable: !(bitmap & 4), value }; };
这里的 'value' 在旧浏览器中不兼容,这些代码应该是babel 加入进去的,很奇怪,我使用版本是:
"@babel/plugin-transform-runtime": "^7.23.7", "@babel/preset-env": "^7.23.8", "@babel/runtime": "^7.23.8", "@babel/runtime-corejs3": "^7.23.8", "@rollup/plugin-babel": "^5.3.1", "vite": "^5.0.11",
你这个配置 polyfill 是运行时的, 如果想要 umd 自带 polyfill, babelHelpers 应该为 bundled,并且去掉 @babel/plugin-transform-runtime
it's work for me:这对我有用:
pnpm i -D @babel/plugin-transform-runtime @babel/preset-env @babel/runtime @rollup/plugin-babel
// vite.config.ts import { fileURLToPath, URL } from 'node:url' import { resolve } from 'path' import type { ConfigEnv, UserConfigExport } from 'vite' import vue from '@vitejs/plugin-vue' import vueJsx from '@vitejs/plugin-vue-jsx' import svgLoader from 'vite-svg-loader' import cssInjectedByJsPlugin from 'vite-plugin-css-injected-by-js' import babel from '@rollup/plugin-babel' export default ({ command, mode }: ConfigEnv): UserConfigExport => { const config: UserConfigExport = { plugins: [vue(), vueJsx(), cssInjectedByJsPlugin(), svgLoader()], resolve: { alias: { '@': fileURLToPath(new URL('./src', import.meta.url)), }, }, build: { minify: 'terser', terserOptions: { compress: { drop_console: true, drop_debugger: true, }, }, lib: { entry: resolve(__dirname, 'src/index.ts'), name: 'IntegrationPlatformNavbar', fileName: 'integration-platform-navbar', }, rollupOptions: { // 确保外部化处理那些你不想打包进库的依赖 external: ['vue', 'element-plus'], output: { // 在 UMD 构建模式下为这些外部化的依赖提供一个全局变量 globals: { vue: 'Vue', 'element-plus': 'ElementPlus', }, }, plugins: [ babel({ extensions: ['.js', '.ts', '.vue'], babelHelpers: 'runtime', plugins: ['@babel/plugin-transform-runtime'], presets: [ [ '@babel/preset-env', { useBuiltIns: false, targets: { browsers: ['last 2 versions', '> 1%', 'not ie <= 11'], }, }, ], ], }), ], }, }, } return config }
我这样配置后,构建产物里有旧浏览器不支持的语法:
var createPropertyDescriptor$8 = function createPropertyDescriptor2(bitmap, value) { return { enumerable: !(bitmap & 1), configurable: !(bitmap & 2), writable: !(bitmap & 4), value }; };
这里的 'value' 在旧浏览器中不兼容,这些代码应该是babel 加入进去的,很奇怪,我使用版本是:
"@babel/plugin-transform-runtime": "^7.23.7", "@babel/preset-env": "^7.23.8", "@babel/runtime": "^7.23.8", "@babel/runtime-corejs3": "^7.23.8", "@rollup/plugin-babel": "^5.3.1", "vite": "^5.0.11",
你这个配置 polyfill 是运行时的, 如果想要 umd 自带 polyfill, babelHelpers 应该为 bundled,并且去掉 @babel/plugin-transform-runtime
我这样改了,构建产物里还是有 { value, } 的代码,这里有个在线实例可验证, 希望能帮我看下怎么调整: https://stackblitz.com/edit/vitejs-vite-fip7pv?file=vite.config.ts
在 dist/vite-ts.umd.js 里 410 行可以看到
@yin-shu 我这编译没有这个问题,但是我这是直接rollup的。你提供的链接我空了再看看。
我测试直接用rollup没问题,但在vite中使用不行
The following method should solve the problem, e.g:
// vite.config.js (e.g) const { getBabelOutputPlugin } = require('@rollup/plugin-babel'); export default { build: { rollupOptions: { plugins: [ /** * Running Babel on the generated code: * https://github.com/rollup/plugins/blob/master/packages/babel/README.md#running-babel-on-the-generated-code * * Transforming ES6+ syntax to ES5 is not supported yet, there are two ways to do: * https://github.com/evanw/esbuild/issues/1010#issuecomment-803865232 * We choose to run Babel on the output files after esbuild. * * @vitejs/plugin-legacy does not support library mode: * https://github.com/vitejs/vite/issues/1639 */ getBabelOutputPlugin({ allowAllFormats: true, presets: [ [ '@babel/preset-env', { useBuiltIns: false, // Default:false // Exclude transforms that make all code slower exclude: ['transform-typeof-symbol'], // https://babeljs.io/docs/en/babel-preset-env#modules modules: false, }, ], ], plugins: [ /** * Extract the helper function. */ [ '@babel/plugin-transform-runtime', { corejs: false, // version: require('@babel/runtime').version, }, ], ], }), ], }, }, };
Running babel on the generated code by esbuild (vite).
The presets and plugins configuration of babel is only suitable for me, you can modify it.
in lib mode, code is generated by rollup & rollup-plugin-typescript other than esbuild when 'vite build' exec
我测试直接用rollup没问题,但在vite中使用不行
// 直接这样试一试,把那些多余的rollup插件去掉
{
build: {
target: ["es2015"]
}
}