polkadot-js / common

Utilities and base libraries for use across polkadot-js for Polkadot and Substrate. Includes base libraries, crypto helpers and cross-environment helpers.
Apache License 2.0
254 stars 145 forks source link

Webpack4 and polkadot configuration in web worker #1435

Closed nepoche closed 2 years ago

nepoche commented 2 years ago

I am in the process of updating a react-app from polkadot.js api: 6.9.2 -> 7.12.1. Following some advice in the docs: https://polkadot.js.org/docs/usage/FAQ/, I updated my customize-cra application with some babel plugins and webpack loaders. I am running import { u8aToHex } from '@polkadot/util' in a web worker. I am wondering if something is wrong with my configuration.

After upgrading and adding the babel plugins and webpack loaders, I hit the following error. The code does not hit this issue in polkadot 6.9.2.

Uncaught ReferenceError: window is not defined
getAbsoluteUrl  @   packageInfo.js:8
../../node_modules/@polkadot/x-global/packageInfo.js    @   packageInfo.js:24
__webpack_require__ @   bootstrap:167
(anonymous) @   index.js:1
../../node_modules/@polkadot/x-global/index.js  @   index.js:17
__webpack_require__ @   bootstrap:167
../../node_modules/@polkadot/x-textdecoder/browser.js   @   browser.js:1
__webpack_require__ @   bootstrap:167
../../node_modules/@polkadot/util/detectOther.js    @   detectOther.js:1
__webpack_require__ @   bootstrap:167
../../node_modules/@polkadot/util/detectPackage.js  @   detectPackage.js:1
__webpack_require__ @   bootstrap:167
../../node_modules/@polkadot/util/index.js  @   index.js:1
__webpack_require__ @   bootstrap:167

Babel plugins and webpack loaders:

  removeBuiltInBabelConfig,
  ...addBabelPresets(
    '@babel/preset-typescript',
    ['@babel/preset-react', { development: false, runtime: 'automatic' }],
    ['@babel/preset-env', { loose: true, modules: 'commonjs', targets: { browsers: '>0.25% and last 2 versions and not ie 11 and not OperaMini all', node: '12' } }]
  ),
  addBabelPlugin('@babel/plugin-proposal-nullish-coalescing-operator'),
  addBabelPlugin('@babel/plugin-proposal-numeric-separator'),
  addBabelPlugin('@babel/plugin-proposal-optional-chaining'),
  addBabelPlugin(['@babel/plugin-transform-runtime', { "useESModules": false }]),
  addBabelPlugin('@babel/plugin-syntax-bigint'),
  addBabelPlugin('@babel/plugin-transform-react-jsx'),
  addBabelPlugin('@babel/plugin-syntax-top-level-await'),
  addBabelPlugin('babel-plugin-styled-components'),
  addBabelPlugin(['@babel/plugin-proposal-class-properties', { "loose": true }]),
  addBabelPlugin(['@babel/plugin-proposal-private-methods', { "loose": true }]),
  addBabelPlugin(['@babel/plugin-proposal-private-property-in-object', { "loose": true }]),
  addExternalBabelPlugin(['@babel/plugin-proposal-class-properties', { "loose": true }]),
  addExternalBabelPlugin(['@babel/plugin-proposal-private-methods', { "loose": true }]),
  addExternalBabelPlugin(['@babel/plugin-proposal-private-property-in-object', { "loose": true }]),

-----

config.module.rules.push({
      test: /\.js$/,
      loader: require.resolve('@open-wc/webpack-import-meta-loader'),
    })
jacogr commented 2 years ago

That is weird, the x-global package explicitly tests for self before window - and this is the only way the libs ever access globals. See

https://github.com/polkadot-js/common/blob/120d5304f1053551eaa7863b9ed6bff9bb5f7f6e/packages/x-global/src/index.ts#L16-L26

Have not tried in a worker for some time this could be the way the WP4 meta compat polyfills it (which is my guess here). if it is due to the WP4 plug-in, nothing that I can do to address it. (WP5 has native support)

jacogr commented 2 years ago

Indeed, looked at the code for the @open-wc/webpack-import-meta-loader and they do the following (copied so formatting is slightly off) -

function getAbsoluteUrl(relativeUrl) {
        const publicPath = __webpack_public_path__;

        let url = '';

        if (!publicPath || publicPath.indexOf('://') < 0) {
          url += window.location.protocol + '//' + window.location.host;
        }

        if (publicPath) {
          url += publicPath;
        } else {
          url += '/';
        }

        return url + relativeUrl;
      }

My reading from the above if that I'm not sure there is a solution without the bundler natively supporting import.meta. You could possibly get away with a window alias injection in your webpack config (but not sure self contains location either).

So my TL;DR - it will "just work" on WP5, on WP4 you may need to hack around with some pain.

EDIT: Maybe explicitly defining the publicPath in the WP config should do the trick since it does a check against that? (If it has a protocol://path form)

nepoche commented 2 years ago

Thank you for your response! As for this issue, I attempted your work arounds, but have not had any luck. The inclusion of the package in the webworker was small - so I decided to replace it with source code instead.

polkadot-js-bot commented 2 years ago

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue if you think you have a related problem or query.