我有 webpack + babel 设置。
module: {
rules: [
{
test: /\.(js|jsx)?$/,
use: {
loader: 'babel-loader',
options: babelOptions
}
}
]
}
而且,我正在使用 ProvidePlugin 来填充对象。但是,我希望能够为其编写自定义逻辑,例如,polyfill 方法仅在运行脚本的页面上是自定义的或缺失的(页面可以是随机的,因为它们是客户的)
new webpack.ProvidePlugin({
Object: path.resolve(__dirname, './src/polyfills/object.js'),
})
// content of polyfills/object.js
const { default: isNative } = require('../utils/isNative');
let polyfilledObject = Object;
if (!polyfilledObject || !isNative(polyfilledObject)) {
polyfilledObject = require('core-js/library/fn/object');
}
if (!polyfilledObject.getOwnPropertyDescriptors || !isNative(polyfilledObject.assign)) {
polyfilledObject.getOwnPropertyDescriptors = require('core-js/library/fn/object/get-own-property-descriptors');
}
module.exports = polyfilledObject;
我面临的问题是错误:
_iobject.js:4 Uncaught TypeError: Object is not a function
来自 core-js 文件。
但是,如果我将 ProvidePlugin 中的“Object”更改为“ObjectPoly”,它就可以正常工作,并且在项目内部调用
ObjectPoly
会导致对象具有填充方法(如果缺少或自定义)。
附注我在
_iobject.js:4
设置了一个调试器,当我在 ProvidePlugin 中使用 Object
时,记录 ObjectPolly
会生成“本机代码”。而在 ProvidePlugin 中使用 {}
时仅记录 Object
。
所以看起来原生 Object 是由 babel 或 webpack 重写的
看起来您遇到了一个问题,由于 Webpack 的
Object
和 Babel 的转换,ProvidePlugin
全局被覆盖或未按预期处理。当您直接使用 Object
时,它可能会受到未正确应用的转换或填充的影响。
错误解释:错误
Uncaught TypeError: Object is not a function
表明当Webpack或Babel处理你的代码时,Object
全局要么没有正确填充,要么被覆盖。
与
ObjectPoly
的行为:您提到的解决方法,即使用 ObjectPoly
之类的自定义名称,可以避免此问题,因为它可以确保全局 Object
不会无意中被覆盖或误解。
解决此问题的方法如下:
Object
不要尝试直接对全局
Object
进行多填充,而是考虑对多填充对象使用单独的变量或函数,并确保您的应用程序代码使用此变量。
您可以修改 Webpack 配置以确保正确应用 polyfill,而不会干扰全局
Object
:
const path = require('path');
const webpack = require('webpack');
module.exports = {
// Other configuration settings...
module: {
rules: [
{
test: /\.(js|jsx)?$/,
use: {
loader: 'babel-loader',
options: babelOptions
}
}
]
},
plugins: [
new webpack.ProvidePlugin({
// Define a custom global for your polyfill
CustomObject: path.resolve(__dirname, './src/polyfills/object.js'),
})
]
};
确保您的
object.js
polyfill 文件正确处理 polyfill 逻辑,而不会导致冲突:
const isNative = require('../utils/isNative');
let polyfilledObject = {};
if (!isNative(Object)) {
polyfilledObject = require('core-js/library/fn/object');
} else {
polyfilledObject = Object;
}
if (!polyfilledObject.getOwnPropertyDescriptors || !isNative(polyfilledObject.assign)) {
polyfilledObject.getOwnPropertyDescriptors = require('core-js/library/fn/object/get-own-property-descriptors');
}
module.exports = polyfilledObject;
核心问题可能是由
ProvidePlugin
直接修改 Object
全局引起的,这可能会干扰 Babel 或 Webpack 的转换。通过定义自定义全局变量(如 CustomObject
)并在代码中使用它,您可以避免直接修改 Object
全局变量并降低冲突风险。
此外,请确保您的 Polyfill 文件准确地检查本机实现是否存在,并根据需要正确应用 Polyfill。