apollographql / apollo-client

:rocket:  A fully-featured, production ready caching GraphQL client for every UI framework and GraphQL server.
https://apollographql.com/client
MIT License
19.38k stars 2.66k forks source link

Import syntax inside node_modules/apollo-client with apollo-client@0.8.1 #1237

Closed HriBB closed 7 years ago

HriBB commented 7 years ago

I might be missing something obvious, but apollo-client@0.8.1 uses import syntax inside node_modules and I get an error

apollo-upload-network-interface bojan$ npm run test

> apollo-upload-network-interface@ test /Users/bojan/www/apollo-upload-network-interface
> mocha --compilers js:babel-core/register ./test/test.js

/Users/bojan/www/apollo-upload-network-interface/node_modules/apollo-client/transport/networkInterface.js:9
import 'whatwg-fetch';
^^^^^^

SyntaxError: Unexpected token import

This is the content of networkInterface.js inside node_modules

var __assign = (this && this.__assign) || Object.assign || function(t) {
    for (var s, i = 1, n = arguments.length; i < n; i++) {
        s = arguments[i];
        for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
            t[p] = s[p];
    }
    return t;
};
import 'whatwg-fetch';
import { print } from 'graphql-tag/printer';
export function printRequest(request) {
    return __assign({}, request, { query: print(request.query) });
}
var HTTPFetchNetworkInterface = (function () {
// ...

I might be missing something obvious, so you can close this issue if it's not valid.

helfer commented 7 years ago

We recently changed the bundle to have UMD, commonjs and es6, so I assume it's related to how you're importing Apollo Client. @kamilkisiela, @calebmer I'm heading out to the mountains today. Can one of you help out here?

kamilkisiela commented 7 years ago

@HriBB First question, which build tool do you use? Webpack, rollup, something different?

About that UMD, CommonJS, ES6 Modules thing.

In package.json we have:

"main": "apollo.umd.js",
"module": "index.js",
"jsnext:main": "index.js",

It means that if your build tool wants to use es6 modules, it looks for the module or the jsnext:main in package.json. Both points to an entry module. Otherwise, it uses just the main field.

Think of apollo.umd.js as a bundle, a one file that contains all the modules. It's compiled to ES5 and supports AMD and CommonJS.

index.js is an entry point for all the modules that are in separate files and use ES6 Modules syntax. They are compiled to ES5 too, just like the UMD bundle.

So why we did that? Thanks to having es6 modules we support, for an example tree-shaking. It's useful to keep your app as small as possible.

I don't know if you're familiar with SystemJS but it requires to specify all the modules / packages manually. It means, that in each defined package you have to define an entry point. If you will put there index.js it will take files that has ES6 Modules so your browser will throw an error about import (SyntaxError: Unexpected token import). You should use apollo.umd.js then, it uses CommonJS. So maybe you have something similar in your project.

kamilkisiela commented 7 years ago

Now I noticed that you use mocha. It suppose to take a file that is defined under main filed in package.json. Could you create a small, separated reproduction?

HriBB commented 7 years ago

I'm using webpack with babel. I fixed it by including apollo-client in babel loader following this issue

module: {
  loaders: [{
    test: /\.js$/,
    loaders: ['babel?cacheDirectory'],
    exclude: /node_modules\/(?!(apollo-client)\/).*/,
    include: [
      path.resolve(__dirname, '..', 'client'),
      path.resolve(__dirname, '..', 'node_modules', 'apollo-client')
    ]
  }
}

I'm not really sure how to handle this in apollo-upload-network-interface, which only uses babel. Should I add module and jsnext:main?

As for the reproduction, just fork apollo-upload-network-interface, run npm install and then npm run test.

kamilkisiela commented 7 years ago

@HriBB Which version of webpack?

HriBB commented 7 years ago

Webpack v1. Need to try out v2 soon. Or maybe rollup.

kamilkisiela commented 7 years ago

@HriBB v2 and rollup works okay, I'm testing all the versions right now. With webpack@2.2 you get es6 support by default :)

kamilkisiela commented 7 years ago

@HriBB Webpack@1 works for me: https://github.com/kamilkisiela/apollo-client-webpack-test

HriBB commented 7 years ago

OK, I guess I'm doing something wrong. Will try to fix this later this week.

ne8il commented 7 years ago

I'm getting this error (SyntaxError: Unexpected token import) in Meteor (1.4.2.3) just by having apollo-client@0.8.1 installed, without requiring it anywhere. This gets output into the modules.js file:

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//                                                                                                                     //
// node_modules/apollo-client/queries/queryTransform.js                                                                //
//                                                                                                                     //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
                                                                                                                       //
import { checkDocument, } from './getFromAST';                                                                         // 1
import { cloneDeep } from '../util/cloneDeep';    

It was working fine previously with apollo-client@0.5.12. Not sure if there's something I need to configure about how it gets loaded or if anyone else on Meteor has fixed this.

kamilkisiela commented 7 years ago

@ne8il works fine Take a look at this. It's a reproduction of your issue.

I also tried out importing apollo-client in the app (imported branch). It takes umd bundle which is a very good thing.

HriBB commented 7 years ago

Hmm ... this is really weird, but for some reason apollo-client works on one project, but does not work on another. Anyway, I'm still having issues with running mocha tests.

/home/bojan/www/apollo-upload-network-interface/node_modules/apollo-client/transport/networkInterface.js:9
import 'whatwg-fetch';
^^^^^^
SyntaxError: Unexpected token import
    at Object.exports.runInThisContext (vm.js:76:16)
    at Module._compile (module.js:528:28)
    at Module._extensions..js (module.js:565:10)

Any ideas on how to convince babel to transpile node_modules/apollo-client when running mocha?

kamilkisiela commented 7 years ago

If you import something from a nested module of 'apollo-client' it uses a file that contains es6 modules (import, export).

An example:

import { abc } from 'apollo-client/nested/module';

It will take /node_modules/apollo-client/nested/module.js, which has import and export.

pon., 6 lut 2017, 15:33 użytkownik Bojan Hribernik notifications@github.com napisał:

Hmm ... this is really weird, but for some reason apollo-client works on one project, but does not work on another. Anyway, I'm still having issues with running mocha tests.

/home/bojan/www/apollo-upload-network-interface/node_modules/apollo-client/transport/networkInterface.js:9 import 'whatwg-fetch'; ^^^^^^ SyntaxError: Unexpected token import at Object.exports.runInThisContext (vm.js:76:16) at Module._compile (module.js:528:28) at Module._extensions..js (module.js:565:10)

Any ideas on how to convince babel to transpile node_modules/apollo-client when running mocha?

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/apollographql/apollo-client/issues/1237#issuecomment-277699012, or mute the thread https://github.com/notifications/unsubscribe-auth/AHyfFv1eTOw1wqSNTYqKXgExkSHS6Lg1ks5rZy8igaJpZM4Lv308 .

HriBB commented 7 years ago

Yeah I fixed it by adding a setup.js that overrides babel-register ignore option.

require('babel-register')({
  ignore: /node_modules\/(?!apollo\-client)/i
});

require('./test.js')

I'm closing this issue, because it's not a bug in apollo-client. Feel free to reopen or comment ...

mimamuh commented 7 years ago

@ne8il I have the same issue with meteor 1.4.2.7 and apollo-client > 0.8.x. Do you found any fix?

ne8il commented 7 years ago

@MiMaMuh I did not. I tried running kamilkisiela's fix listed above. His sample project runs for me fine locally, but importing those deps into my own meteor project doesn't fix it. I kind of put that on the back burner so I will try again and see if anything's changed.

ne8il commented 7 years ago

@MiMaMuh I found that the problem centered around having the atmosphere package apollo at version 0.0.1. If you update that to a newer version it should go away. I'm not entirely sure why it's is an issue. @kamilkisiela if you add that package at that version to your sample project you should see the same issue, but only if you care to, my issue should be fixed. Thanks for looking into it.

mimamuh commented 7 years ago

@ne8il Thx for your information. In my case I don't use the apollo atmosphere package instead I load the apollo-client directly via npm. I have to do some more tests I think.

mimamuh commented 7 years ago

@ne8il I've solved my issue, too. It was due to importing from a subdirectory which caused the build system to ignore the project.json as @stubailo explained it at the meteor forum. It was a old api anyway I've used. Thx for your help!

kctang commented 7 years ago

Posting my scenario & solution here, hope it helps someone with similar situation. Project environment is TypeScript 2.5.2 and Webpack 3.

Scenario: With import ApolloClient from 'apollo-client/ApolloClient', I got this error:

/xxx/node_modules/apollo-client/ApolloClient.js:9
import { createNetworkInterface, } from './transport/networkInterface';
^^^^^^

SyntaxError: Unexpected token import
    at createScript (vm.js:80:10)

Solution: import ApolloClient from 'apollo-client'

No idea why IntelliJ decided to add /ApolloClient when I auto-imported.

bkoltai commented 6 years ago

I was seeing a similar error which was caused by various imports reaching into both apollo-client and react-apollo beyond the root (ex. import Query from "react-apollo/Query")

To fix, just use the named imports from the root module (ex. import { Query } from "react-apollo")

sdwvit commented 5 years ago

Thanks @bkoltai, it helped!

shatodj commented 5 years ago

I had this error:

Uncaught ReferenceError: exports is not defined
    at Module../node_modules/immutable-tuple/dist/tuple.mjs (tuple.mjs:1)
    at __webpack_require__ (bootstrap:782)
    at fn (bootstrap:150)
    at Object../node_modules/optimism/lib/index.js (index.js:5)
    at __webpack_require__ (bootstrap:782)
    at fn (bootstrap:150)
    at Object../node_modules/apollo-cache-inmemory/lib/optimism.js (optimism.js:6)
    at __webpack_require__ (bootstrap:782)
    at fn (bootstrap:150)
    at Object../node_modules/apollo-cache-inmemory/lib/readFromStore.js (readFromStore.js:9)
    at __webpack_require__ (bootstrap:782)
    at fn (bootstrap:150)
    at Object../node_modules/apollo-cache-inmemory/lib/inMemoryCache.js (inMemoryCache.js:15)
    at __webpack_require__ (bootstrap:782)
    at fn (bootstrap:150)
    at Object../node_modules/apollo-cache-inmemory/lib/index.js (index.js:21)

when importing 'apollo-cache-inmemory'

import { InMemoryCache, IntrospectionFragmentMatcher } from 'apollo-cache-inmemory';

Thanks to @HriBB I added 'exclude' property to my babel-loader in webpack.config like this

          {
            test: /\.(js|mjs)$/,
            exclude: /(@babel(?:\/|\\{1,2})runtime)|(node_modules\/(?!(apollo-client)\/).*)/, // <-- nice
            loader: require.resolve('babel-loader'),
            options: {
              babelrc: false,
              configFile: false,
              compact: false,
              // ... etc
          },

...and the issue disappeared Maybe there is a better solution. But for now this saved me.