使用 @rollup/plugin-babel 的 vite/rollup 在设置为 IE 时不会去除模板文字反引号 >= 11



试图在库模式下使用Vite将ES6.js文件编译成捆绑的ES5.js文件,该文件将在Internet Explorer 11中运行。在我的实际应用程序中,有几个文件使用ESM导入/导出,但我已经验证了我可以用一个简化的示例文件重现问题。我将在下面包括。

下面是我的配置:

//vite.config.js
const path = require('path');
const { defineConfig } = require('vite');
import { babel } from '@rollup/plugin-babel';
module.exports = defineConfig({
esbuild: false,
plugins: [
babel({
babelHelpers: 'bundled',
presets: [['@babel/preset-env', { targets: { browsers: 'defaults, ie >= 11' } }]],
}),
],
build: {
outDir: 'javascript',
lib: {
entry: path.resolve(__dirname, 'js-src/index.js'),
name: 'MyLib',
fileName: (format) => 'my-lib.js',
},
},
});

测试文件:

const aWord = 'World';
const multiLineString = `
Hello ${aWord}
`;
console.log(multiLineString);

结果输出文件:

(function(n){typeof define=="function"&&define.amd?define(n):n()})(function(){"use strict";var n=`
Hello `.concat(aWord,`
`);console.log(n)});

请注意编译后的代码是如何向下移动到ES5的(参见var而不是const),但它并没有删除模板文字反引号并将它们转换为Internet Explorer 11安全的其他类型的字符串。但它只发生在多行模板字面值字符串上。单行模板文字将被更改为具有"字符的字符串。

寻找一种解决方案来强制babel删除这些反划字符并将它们转换为支持的字符串类型(同时保留换行符)

我找到了罪魁祸首。它不是Babel,而是Esbuild。

当Babel在正确编译所有内容(我检查过,它确实)方面做得很好之后,优化开始了,Esbuild(默认情况下)"优化"了。那些新到的换行符"n"返回到更细的(字符式)多行字符串。

我看到你试图禁用Esbuild与esbuild = false,但也许这不是正确的配置选项"回到"(在11月21日),以防止Esbuild搞乱你的结果。

为了阻止Esbuild重新编译带有换行符的字符串,你有两个选项

  • 禁用最小化:build.minify = false
  • 或setbuild.target = 'ie11'

一旦将build.target设置为ie11,构建过程将开始抱怨Esbuild没有准备好将您的代码的相当一部分转换为IE11规范。我认为这是因为Esbuild在插件运行之前运行,然后再运行最后的优化。

所以使用@vite/babel不再是一个选择,新的巴别塔方式通过@rollup/plugin-babel

以下是我的工作vite.config.js或至少是它的重要部分:

// vite.config.js
import { defineConfig } from 'vite'
import { getBabelOutputPlugin } from '@rollup/plugin-babel'
export default defineConfig({
build: {
target: 'ie11',
lib: {
/* your vite lib mode params */
},
rollupOptions: {
// make sure to externalize deps that shouldn't be bundled
// into your library
external: [],
output: {
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',
{
targets: '> 0.25%, not dead, IE 11',
useBuiltIns: false, // Default:false
// // https://babeljs.io/docs/en/babel-preset-env#modules
modules: false
},
]
]
}),
]
},
plugins: [...]
}
}
})

你可以使用@vitejs/plugin-legacy来支持ie11。

我用一个简单的Vite项目和香草JavaScript进行测试,并添加像你这样的测试文件代码。我首先运行npm i -D @vitejs/plugin-legacy,然后使用vite.config.js文件如下:

import legacy from '@vitejs/plugin-legacy'
export default {
plugins: [
legacy({
targets: ['ie >= 11'],
additionalLegacyPolyfills: ['regenerator-runtime/runtime']
})
]
}

然后我运行npm run build,生成的js文件在dist文件夹如下图所示,支持IE 11:

System.register([],(function(){"use strict";return{execute:function(){var e="n  Hello ".concat("World","n");console.log(e)}}}));

最新更新