ProvidePlugin对象方法polyfill问题

问题描述 投票:0回答:1

我有 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 重写的

javascript webpack babeljs polyfills core-js
1个回答
0
投票

看起来您遇到了一个问题,由于 Webpack 的

Object
和 Babel 的转换,
ProvidePlugin
全局被覆盖或未按预期处理。当您直接使用
Object
时,它可能会受到未正确应用的转换或填充的影响。

问题细分

  1. 错误解释:错误

    Uncaught TypeError: Object is not a function
    表明当Webpack或Babel处理你的代码时,
    Object
    全局要么没有正确填充,要么被覆盖。

  2. ObjectPoly
    的行为:您提到的解决方法,即使用
    ObjectPoly
    之类的自定义名称,可以避免此问题,因为它可以确保全局
    Object
    不会无意中被覆盖或误解。

解决方法

解决此问题的方法如下:

1. 避免覆盖全局
Object

不要尝试直接对全局

Object
进行多填充,而是考虑对多填充对象使用单独的变量或函数,并确保您的应用程序代码使用此变量。

2. 调整Webpack配置

您可以修改 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'),
    })
  ]
};

3. 更新您的 Polyfill 文件

确保您的

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。

© www.soinside.com 2019 - 2024. All rights reserved.