Skip to content

Conversation

yanneves
Copy link

I ran into an issue yesterday that stemmed from a wildcard import, e.g. import * as styles from 'some.module.css' and using identity-obj-proxy in Jest config. The problem appeared using Gatsby's default config introduced in v3 where CSS modules are imported as ES modules.

The recommended pattern is to use named imports, e.g. import { wrapper, background } from 'some.module.css' - good news, that works already! I've added a test case import-named-test.js.

But when we try and use a wildcard import, the resulting object in * as object does not become a proxy. If we look under the hood, it's clear why:

import * as styles from 'some.module.css'

becomes

"use strict"

var styles = _interopRequireWildcard(require("./some.module.css"))

function _interopRequireWildcard(obj) {
  if (obj && obj.__esModule) {
    return obj
  }
  
  // ...

  var newObj = {}
  var hasPropertyDescriptor =
    Object.defineProperty && Object.getOwnPropertyDescriptor

  for (var key in obj) {
    if (Object.prototype.hasOwnProperty.call(obj, key)) {
      var desc = hasPropertyDescriptor
        ? Object.getOwnPropertyDescriptor(obj, key)
        : null
      if (desc && (desc.get || desc.set)) {
        Object.defineProperty(newObj, key, desc)
      } else {
        newObj[key] = obj[key]
      }
    }
  }

  newObj["default"] = obj
  return newObj
}

Taking away some cache related code, that sums up to if our dependency is an ES Module obj.__esModule == true it returns it, otherwise it creates a new object using the dependency's exports.

In identity-obj-proxy, we explicitly return obj.__esModule as false for compatibility with other import patterns. And since the proxy doesn't have its own properties, the result will not work as expected.

Changing the following lines in identity-obj-proxy satisfies wildcard imports, but breaks other types of imports.

idObj = new Proxy({}, {
  get: function getter(target, key) {
    if (key === '__esModule') {
      // previously: return false;
      return idObj;
    }
    return key;
  }
});

And that's as far as I got... so I'm curious whether anyone can see another solution that adds support for wildcard imports while preserving support for other import patterns. If not, we could spin off an identity-wildcard-obj-proxy package for this purpose.

It's a subset of a subset of use-cases, but I'm all for saving others derailing from productivity by stuff like this 'just working'. This was an elusive issue in some test failures for me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant