Apollo-client: Cannot set property default of #<Object> which has only a getter

Created on 22 May 2019  ·  17Comments  ·  Source: apollographql/apollo-client

Intended outcome:

I just tried to import the apolo boost in a node js environment that uses typescript.

import {ApolloClient} from 'apollo-boost'

Actual outcome:

TypeError: Cannot set property default of #<Object> which has only a getter
    at Object.<anonymous> (h:\Private#2019\Project\_local\article-glow\core\node_modules\apollo-boost\lib\bundle.cjs.js:158:17)
    at Module._compile (internal/modules/cjs/loader.js:722:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:733:10)
    at Module.load (internal/modules/cjs/loader.js:620:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:560:12)
    at Function.Module._load (internal/modules/cjs/loader.js:552:3)
    at Module.require (internal/modules/cjs/loader.js:658:17)
    at require (internal/modules/cjs/helpers.js:22:18)
    at Object.<anonymous> (h:\Private#2019\Project\_local\article-glow\core\src\Backend\Sequence\After.ts:5:1)
    at Module._compile (internal/modules/cjs/loader.js:722:30)

How to reproduce the issue:

install apollo-boost and trying import

npm install --save apollo-boost

Versions

  System:
    OS: Windows 10
  Binaries:
    Node: 11.3.0 - C:\Program Files\nodejs\node.EXE
    Yarn: 1.12.3 - ~\AppData\Roaming\npm\yarn.CMD
    npm: 6.7.0 - C:\Program Files\nodejs\npm.CMD
  Browsers:
    Edge: 41.16299.15.0
  npmPackages:
    apollo-boost: ^0.4.0 => 0.4.0
    apollo-cache-inmemory: ^1.6.0 => 1.6.0
    apollo-link-http: ^1.5.14 => 1.5.14
    apollo-server: ^2.4.8 => 2.5.0
    apollo-server-express: ^2.4.8 => 2.5.0
dependencies ⛑ TypeScript ✔ confirmed 🐞 bug 🙃 upstream 🛠 tooling

Most helpful comment

This should be fixed in [email protected] (just released).

All 17 comments

I am having this issue as well using 0.4.0. Reverting back to 0.3.1 resolved my issue for the time being.

I'm having a similar issue with Next.js & Apollo Client configuration ~ next-apollo, reverting back to old versions solved my issues for now.

Also having this issue with new ApolloClient() with an TypeScript + ReactNative + Expo setup. The import import ApolloClient from 'apollo-boost' alone does not cause any error. Reverting to 0.3.1 does not help for me. Perhaps it's an issue with TypeScript imports.

Using the isolated packages / imports works for me:

import { ApolloClient } from 'apollo-client'
import { InMemoryCache } from 'apollo-cache-inmemory'
import { HttpLink } from 'apollo-link-http'

const client = new ApolloClient({
  cache: new InMemoryCache(),
  link: new HttpLink({
    uri: '...'
  })
})

image

Also having this issue when updating:

  • apollo-boost to 0.4.0
  • apollo-client to 2.6.0
  • react-apollo to 2.5.6

Had the issue with apollo-boost -> 0.4.0 and went back to 0.3.1 per @musemind's post and it fixed the issue. I tried multiple config options, and even no config at all and the issue still remained.

I have a similar issue after updating to 0.4.0

I had the exact same issue with 0.4.0, then I downgraded to 0.3.1 then everything worked fine

Same for me. Downgrading fixed it.

Temporary workaround import ApolloClient from "apollo-boost/lib/index";

If downgrade it, we'd lose the basic configuration that apollo-boost bring with 0.4.0. The exporting of DefaultClient is wrong in bundle file, The @vomchik workaround could work for now.

This appears to be an upstream bug in the Rollup CommonJS output for apollo-boost/lib/bundle.cjs.js.

In order to compile

export * from "apollo-client"
export default class DefaultClient { ... }

Rollup generates the following code:

var ApolloClient__default = require('apollo-client');

Object.keys(ApolloClient__default).forEach(function (key) {
    Object.defineProperty(exports, key, {
        enumerable: true,
        get: function () {
            return ApolloClient__default[key];
        }
    });
});

exports.default = DefaultClient;

However, because apollo-client also has a default export, that default export is mistakenly defined on exports in the forEach loop by Object.defineProperty in a way that cannot simply be overridden by the exports.default = DefaultClient assignment. That's why you're seeing the error

Cannot set property default of #<Object> which has only a getter

According to the ECMAScript specification, the default export should actually be excluded when doing export * from "apollo-client". When I first learned about this gotcha, it surprised me too, but the TC39 committee (including myself) have reached a firm consensus on this behavior, and Rollup is violating the specification by copying over all exported properties of apollo-client.

I will open other issues in the appropriate places, but I wanted to give everyone an update here first.

For reference, here's how Babel compiles the code above:

"use strict";

exports.__esModule = true;
var _exportNames = {};
exports.default = void 0;

var _apolloClient = require("apollo-client");

Object.keys(_apolloClient).forEach(function (key) {
  if (key === "default" || key === "__esModule") return;
  if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
  exports[key] = _apolloClient[key];
});

var DefaultClient = function DefaultClient() {};

exports.default = DefaultClient;

Here's a link to a REPL you can play with.

This should be fixed in [email protected] (just released).

This should be fixed in [email protected] (just released).

I just installed 0.4.1 and it fixed the issue (Y)

This issue happened to me because I had apollo-boost: 0.3.1 as a dependency, but apollo-boost has apollo-client: ^2.5.1 as it's dependency, so it pulled in [email protected] which breaks. Upgrading boost to 0.4.1 fixed it for me, but it might be a good idea to not use carats in the dependencies in order to avoid this.

Just to expand on what @mattschoch suggested above, it might be a good idea to use ~ instead of ^, since ^2.5.1 matches 2.6.1, but ~2.5.1 only matches 2.5.x versions.

Just to expand on what @mattschoch suggested above, it might be a good idea to use ~ instead of ^, since ^2.5.1 matches 2.6.1, but ~2.5.1 only matches 2.5.x versions.

Just to expand on this, coming from ruby community, using ~ is the most common way...although, if you're using semantic versioning, minor and patch version bumps _should not_ break anything, so ^ seems to make more sense...

Was this page helpful?
0 / 5 - 0 ratings