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.37k stars 2.66k forks source link

optimism module not defined #4421

Closed Falieson closed 5 years ago

Falieson commented 5 years ago

I upgraded a bunch of packages and then got the below error, so rolled back until I got a working app.

I tried the suggestion in this issue to change my webpack.modules, but that didn't fix my issue. https://github.com/apollographql/apollo-client/issues/3984#issuecomment-433117850

Tested Versions apollo-cache-inmemory

Intended outcome: No problems

Actual outcome on 1.4+ Browser/Runtime error

main.js:18695 Uncaught ReferenceError: module is not defined
    at Module../node_modules/immutable-tuple/dist/tuple.mjs (main.js:18695)
    at __webpack_require__ (main.js:724)
    at fn (main.js:101)
    at Object../node_modules/optimism/lib/index.js (main.js:19866)
    at __webpack_require__ (main.js:724)
    at fn (main.js:101)
    at Module../node_modules/apollo-cache-inmemory/lib/optimism.js (main.js:1579)
    at __webpack_require__ (main.js:724)
    at fn (main.js:101)
    at Module../node_modules/apollo-cache-inmemory/lib/readFromStore.js (main.js:1774)

Compiler error on 1.3.0

[build] [app] ERROR in ./node_modules/apollo-cache-inmemory/src/optimism.ts 1:8
[build] [app] Module parse failed: Unexpected token (1:8)
[build] [app] You may need an appropriate loader to handle this file type.
[build] [app] > declare function require(id: string): any;
[build] [app] | 
[build] [app] | export type OptimisticWrapperFunction<
[build] [app]  @ ./node_modules/apollo-cache-inmemory/lib/optimism.js 1:11-30
[build] [app]  @ ./node_modules/apollo-cache-inmemory/lib/inMemoryCache.js
[build] [app]  @ ./node_modules/apollo-cache-inmemory/lib/index.js
[build] [app]  @ ./src/app/middleware/apollo.tsx
[build] [app]  @ ./src/app/middleware/index.tsx
[build] [app]  @ ./src/app/root/stack.tsx
[build] [app]  @ ./src/app/index.tsx

How to reproduce the issue:

// import { RestLink } from '@tgrx/apollo-link-rest'
import { withClientState } from '@tgrx/apollo-link-state'
import { InMemoryCache } from 'apollo-cache-inmemory'
import { ApolloClient } from 'apollo-client'
import { ApolloLink } from 'apollo-link'
import { onError } from 'apollo-link-error'
import { HttpLink } from 'apollo-link-http'
import * as React from 'react'
import { ApolloProvider } from 'react-apollo'

import { ResolverDefaults,  Resolvers, } from '../gql'

interface IProps {
  graphqlURL: string,
  children: React.ReactChild
}

export default class ApolloClientProvider extends React.Component<IProps> {
  private _apolloClient: ApolloClient<any> // tslint:disable-line:no-any

  private _cache = new InMemoryCache()

  private _stateLink = withClientState({
    cache: this._cache,
    defaults: ResolverDefaults,
    resolvers: Resolvers,
  })

  private _httpLink = new HttpLink({
    uri: this.props.graphqlURL,
  })

  // Create error handler link
  // https://github.com/apollographql/apollo-client/blob/master/docs/source/features/error-handling.md
  private _errorLink = onError(({ graphQLErrors, networkError }) => {
    if (graphQLErrors) {
      graphQLErrors.map(({ message, locations, path }) => {
        console.error(`[GraphQL] Message: ${message}, Location: ${locations}, Path: ${path}`)
      })
    }

    if (networkError) {
      console.error(`[Network] ${networkError}`)
    }
  })

  constructor(props: IProps) {
    super(props)

    const links = [
      // this._restLink(),
      this._stateLink,
      this._errorLink,
      this._httpLink
    ]

    this._apolloClient = new ApolloClient({
      cache: this._cache,
      connectToDevTools: true,
      link: ApolloLink.from(links),
    })
  }

  public render() {
    return <ApolloProvider client={this._apolloClient}>
      {this.props.children}
    </ApolloProvider>
  }

  // setup your `RestLink` with your endpoint
  // private _restLink = () =>  {
  //   return new RestLink({ uri: 'https://api.openweathermap.org/data/2.5/' })
  // }
}

Versions

➜ npx envinfo@latest --preset apollo --clipboard
npx: installed 1 in 0.856s

  System:
    OS: Linux 4.18 Ubuntu 18.10 (Cosmic Cuttlefish)
  Binaries:
    Node: 11.9.0 - ~/.nvm/versions/node/v11.9.0/bin/node
    npm: 6.5.0 - ~/.nvm/versions/node/v11.9.0/bin/npm
  Browsers:
    Chrome: 72.0.3626.96
    Firefox: 65.0
  npmPackages:
    apollo-cache-inmemory: 1.4.2 => 1.4.2
    apollo-client: 2.4.12 => 2.4.12 
    apollo-link: 1.2.8 => 1.2.8 
    apollo-link-error: 1.1.7 => 1.1.7 
    apollo-link-http: 1.5.11 => 1.5.11 
    apollo-utilities: 1.0.22 => 1.0.22 
    react-apollo: 2.4.1 => 2.4.1
benjamn commented 5 years ago

It looks like your Webpack configuration is trying to compile .ts files found in node_modules. Do you have the ability to disable that behavior, at least for certain packages?

JoviDeCroock commented 5 years ago

Shouldn't that be caught by the exclude node_modules in babel/ts loader

yangit commented 5 years ago

I have the same issue. I do not have any config about .ts files

JoviDeCroock commented 5 years ago

What is your resolve in your webpack config. This could be because optimism only exposes a main field and you are filtering that out because you are for example only compiling for browser and module

yangit commented 5 years ago
  resolve: {
    extensions: ['.js', '.jsx', '.json'],
    modules: ['node_modules'],
  },

Could this be causing issue?

yangit commented 5 years ago

Here is more info

webpack config ``` import appRootDir from 'app-root-dir'; import debug from 'debug'; import fs from 'fs-extra'; import path from 'path'; import cssnano from 'cssnano'; import AssetsPlugin from 'assets-webpack-plugin'; import CopyWebpackPlugin from 'copy-webpack-plugin'; import MiniCssExtractPlugin from 'mini-css-extract-plugin'; import TerserPlugin from 'terser-webpack-plugin'; import OptimizeCSSAssetsPlugin from 'optimize-css-assets-webpack-plugin'; import SimpleProgressWebpackPlugin from 'simple-progress-webpack-plugin'; import safeParser from 'postcss-safe-parser'; import webpack from 'webpack'; import { ReactLoadablePlugin } from 'react-loadable/webpack'; import config from '@lite/config'; import constants from '@lite/constants'; import { gitRevision, isDev, isProd, isVerbose, ifDev, ifProd, lessLoaders } from './utils'; import { babelClientEnvironment } from './babel.options'; const dir = process.env.DIR; const publicPath = constants.publicPath || config.get('PUBLIC_PATH'); if (!dir) { throw new Error('Define directory.'); } const [serviceName] = dir.split('/'); const log = debug(`build:${serviceName}`); const buildPath = `./services/${serviceName}/build/client`; // Make sure build path is exist, if not create it log(`> Cleaning output folder ${buildPath} ...`); fs.emptyDirSync(path.resolve(appRootDir.get(), buildPath)); if (isDev) { log(`> Copying static file...`); fs.copy(path.resolve(appRootDir.get(), 'services', serviceName, 'static'), path.resolve(appRootDir.get(), buildPath)); } const defaultLoaders = [ { test: /\.jsx?$/, exclude: /node_modules/, use: [ { loader: 'thread-loader', }, { loader: 'babel-loader', options: babelClientEnvironment, }, ], }, { test: /\.(graphql|gql)$/, exclude: /node_modules/, use: ['graphql-tag/loader'], }, { test: /\.less$/, exclude: /node_modules/, use: lessLoaders({ paths: [path.resolve(appRootDir.get(), 'services', dir, 'styles')] }), }, { test: /\.(eot|ttf|woff|woff2)$/, use: [ { loader: 'url-loader', options: { limit: 1024, }, }, ], }, ]; const fallbackLoader = { exclude: [/\.jsx?$/, /\.html$/, /\.json$/], use: [ { loader: 'file-loader', options: { limit: 1024, name: ifDev('[name].[ext]', '[hash:8].[ext]'), publicPath, }, }, ], }; const webpackConfig = { /** * Output target to web */ target: 'web', /** * Fail out if there is a single error in production mode */ bail: isProd, /** * The base directory * for resolving entry point */ context: path.resolve(appRootDir.get(), 'services', dir), /** * Define mode to let webpack * determine what plugin should be activated */ mode: ifProd('production', 'development'), /** * Source map setting */ devtool: ifDev('cheap-module-source-map', 'hidden-source-map'), /** * Entry files * Use custom polyfills */ entry: { mobile: [ 'intersection-observer', 'url-polyfill', ifDev('react-hot-loader/patch'), path.resolve(appRootDir.get(), 'services', dir, 'index.js'), ].filter(Boolean), }, /** * Output config * Buildpath and output name */ output: { path: path.resolve(appRootDir.get(), buildPath), publicPath, filename: ifDev('[name].js', '[name].[chunkhash:8].js'), chunkFilename: ifDev('chunk.[name].js', 'chunk.[name].[chunkhash:8].js'), crossOriginLoading: 'anonymous', }, /** * Webpack 4 configuration * Auto minified in production, auto common chunk * the default is production */ optimization: { splitChunks: { cacheGroups: { vendor: { test: /node_modules/, chunks: 'initial', filename: ifDev('vendor.js', 'vendor.[chunkhash].js'), }, }, }, minimizer: ifProd([ new TerserPlugin({ cache: true, parallel: true, sourceMap: true, terserOptions: { ecma: 8, mangle: { safari10: true, }, output: { ascii_only: true, }, }, }), new OptimizeCSSAssetsPlugin({ cssProcessor: cssnano, cssProcessorOptions: { parser: safeParser, }, cssProcessorPluginOptions: { preset: ['default', { discardComments: { removeAll: true } }], }, canPrint: false, }), ]), }, resolve: { extensions: ['.js', '.jsx', '.json'], modules: ['node_modules'], }, module: { // Makes missing export becomes compile error strictExportPresence: true, rules: [ { oneOf: [ ...defaultLoaders, // fallback loader, any file that doesn't need specific loader use file-loader fallbackLoader, ], }, ], }, plugins: [ /** * Define environment variable from process.env */ new webpack.EnvironmentPlugin({ NODE_ENV: 'development', DIR: serviceName, }), /** * Default plugin * Used in all environtment * DefinePlugin, CommonsChunkPlugin, AssetsPlugin */ new webpack.DefinePlugin({ __DEV__: isDev, __PROD__: isProd, __CLIENT__: true, __SERVER__: false, __DEVTOOLS__: isVerbose, // DISABLE redux-devtools __GITREV__: gitRevision, }), /** * Webpack progress plugin to see build progress */ new SimpleProgressWebpackPlugin(), /** * Extract asset pathname */ new AssetsPlugin({ filename: 'assets.json', path: path.resolve(appRootDir.get(), buildPath), }), new ReactLoadablePlugin({ filename: path.resolve(appRootDir.get(), buildPath, 'react-loadable.json'), }), /** * Copy static assets * These copied folders will be deployed to S3 (Tokopedia CDN) */ new CopyWebpackPlugin([ { from: path.resolve(appRootDir.get(), 'services', serviceName, 'static'), to: path.resolve(appRootDir.get(), buildPath, '../static'), flatten: true, }, ]), /** * Webpack production plugin * These plugin only used in production env. */ ifProd( new MiniCssExtractPlugin({ filename: ifDev('[name].css', '[name].[hash].css'), chunkFilename: ifDev('[id].css', '[id].[hash].css'), }), ), ].filter(Boolean), node: { dgram: 'empty', fs: 'empty', net: 'empty', tls: 'empty', child_process: 'empty', }, }; export { buildPath, defaultLoaders, fallbackLoader, serviceName }; export default webpackConfig; ```
package.json ``` { "name": "kratos", "version": "1.0.36", "description": "", "main": "server/index.js", "scripts": { "dev:server": "nodemon --watch server server/index", "dev:client": "tail -f /dev/null" }, "author": "", "license": "ISC", "dependencies": { "@babel/polyfill": "7.0.0", "@material-ui/core": "3.9.2", "@material-ui/icons": "3.0.2", "ansi-html": "0.0.7", "ansi-to-html": "0.6.10", "apollo-boost": "0.1.27", "apollo-cache-inmemory": "1.4.2", "apollo-client": "2.4.12", "apollo-link": "1.2.8", "apollo-link-http": "1.5.11", "apollo-link-state": "0.4.2", "apollo-server": "2.4.0", "app-root-dir": "1.0.2", "axios": "0.18.0", "bluebird": "3.5.3", "case-sensitive-paths-webpack-plugin": "2.2.0", "console.table": "0.10.0", "easy-table": "1.1.1", "graphql": "14.1.1", "graphql-subscriptions": "1.0.0", "graphql-tag": "2.10.1", "graphql-tools": "4.0.4", "handlebars": "4.0.12", "highland": "2.13.0", "immutable-tuple": "0.4.10", "koa": "2.6.2", "koa-router": "7.4.0", "koa-views": "6.1.4", "left-pad": "1.3.0", "lodash": "4.17.11", "moment": "2.22.2", "mongoose": "5.3.15", "nodemon": "1.18.7", "optimism": "0.7.1", "pnp-webpack-plugin": "1.2.1", "promise-retry": "1.1.1", "react": "16.8.1", "react-apollo": "2.4.1", "react-dev-utils": "7.0.1", "react-dom": "16.8.1", "react-router": "4.3.1", "react-router-dom": "4.3.1", "semver-compare": "1.0.0", "shelljs": "0.8.3", "socket.io": "2.2.0", "socket.io-client": "2.2.0", "source-map-support": "0.5.9", "strip-ansi": "5.0.0", "subscriptions-transport-ws": "0.9.15", "uuid": "3.3.2", "webpack-dev-server": "3.1.14", "webpack-manifest-plugin": "2.0.4" }, "devDependencies": { "@lite/tools": "1.3.3" } } ```
yangit commented 5 years ago

The issue seems to be with immutable-tuple module

tuple.mjs:1 Uncaught ReferenceError: module is not defined
    at Module.../../../node_modules/optimism/node_modules/immutable-tuple/dist/tuple.mjs (tuple.mjs:1)
    at __webpack_require__ (bootstrap:781)
    at fn (bootstrap:149)
    at Object.../../../node_modules/optimism/lib/index.js (index.js:4)
    at __webpack_require__ (bootstrap:781)
    at fn (bootstrap:149)
    at Module.../../../node_modules/apollo-cache-inmemory/lib/inMemoryCache.js (inMemoryCache.js:1)
    at __webpack_require__ (bootstrap:781)
    at fn (bootstrap:149)
    at Module.../../../node_modules/apollo-cache-inmemory/lib/index.js (index.js:1)
JoviDeCroock commented 5 years ago

Could you try adding this to your webpack module rules:

       {
          test: /\.mjs$/,
          include: /node_modules/,
          type: 'javascript/auto',
        },

I'll get back to this thread tonight

yangit commented 5 years ago

OMG! That helped. I do not know how I overlooked it. Thanks a lot!

Falieson commented 5 years ago

Thanks for everyone's additions to this thread. I tried the a-im-c 1.4.2 again and it worked. A different change I made to webpack must resolving the same issue. I'm glad that workarounds/info is being surfaced for others

danilobuerger commented 5 years ago

Closing as issue seems to be resolved.

Falieson commented 5 years ago

Actually @danilobuerger - I forgot that the issue was a runtime build error. It wasn't resolved randomly. I added @JoviDeCroock 's snippet

       {
          test: /\.mjs$/,
          include: /node_modules/,
          type: 'javascript/auto',
        },

and that resolved it!

chrisdrackett commented 5 years ago

@danilobuerger I had to do this as well and I'm not 100% sure why. It seems odd that I need to update my webpack config to use something installed in node_modules.