<head>
<script>
this.globalThis || (this.globalThis = this);
// or
// if (globalThis === undefined) {
// var globalThis = window;
// }
</script>
...
</head>
(function() {
if (typeof globalThis === "object") return;
Object.defineProperty(Object.prototype, "__magic__", {
get: function() {
return this;
},
configurable: true // This makes it possible to `delete` the getter later.
});
__magic__.globalThis = __magic__; // lolwat
delete Object.prototype.__magic__;
})();
// Your code can use `globalThis` now.
console.log(globalThis);
// vite.config.js
import legacy from https://github.com/vitejs/vite/tree/master/packages/plugin-legacy;
export default defineConfig({
// For production build environments only
build: {
target: 'es2015',
},
plugins: [
// For production build environments only
legacy({
targets: ['chrome >= 64', 'edge >= 79', 'safari >= 11.1', 'firefox >= 67'],
ignoreBrowserslistConfig: true,
renderLegacyChunks: false,
/**
* Polyfills required by modern browsers
*
* Since some low-version modern browsers do not support the new syntax
* You need to load polyfills corresponding to the syntax to be compatible
* At build, all required polyfills are packaged according to the target browser version range
* But when the page is accessed, only the required part is loaded depending on the browser version
*
* Two configuration methods:
*
* 1. true
* - Automatically load all required polyfills based on the target browser version range
* - Demerit: will introduce polyfills that are not needed by modern browsers in higher versions,
* as well as more aggressive polyfills.
*
* 2、string[]
* - Add low-version browser polyfills as needed
* - Demerit: It needs to be added manually, which is inflexible;
* it will be discovered after the production is deployed, resulting in production failure! ! !
*/
modernPolyfills: ['es/global-this'],
// or
// modernPolyfills: true,
}),
],
});
推荐 3 解决方案。
vite 构建打包的底层是依赖于 rollup 的,rollup 针对 top-level this 的赋值时有个配置项 context,默认值是 undefined。但 vite build 的包却是 globalThis。原因找到了,可以看链接。vite 重新赋值为 globalThis 了。
因此还有一种解决方案,其实不用添加针对 globalThis 的垫片。
// input
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
// output
var __assign = function() {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p2 in s)
if (Object.prototype.hasOwnProperty.call(s, p2))
t[p2] = s[p2];
}
return t;
};
return __assign.apply(this, arguments);
};
问题现象
在使用 vite 工具打包应用程序的时候,出现了
glolbaThis is not defined
的错误。出现问题的设备信息如下:
问题原因
经查相关资料,globalThis 的特性是 chrome 71 版本后才支持的。 因此,如果需要支持低于 71 版本的浏览器,需要添加对应的垫片处理。
解决方案
方案1
在
html
文件头部添加弊端在于:修改Object,Object.defineProperty或Object.prototype . defineGetter可能会破坏 polyfill。
方案2
安装
globalThis
的 npm 包在
main.js
文件里添加以下代码方案3
在 vite 的插件
@vitejs/plugin-legacy
里添加配置推荐 3 解决方案。
vite 构建打包的底层是依赖于 rollup 的,rollup 针对
top-level this
的赋值时有个配置项context
,默认值是undefined
。但 vite build 的包却是globalThis
。原因找到了,可以看链接。vite 重新赋值为globalThis
了。 因此还有一种解决方案,其实不用添加针对globalThis
的垫片。参考