Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Code splitting: invalid export generated in shared chunk #1252

Closed
nihalgonsalves opened this issue May 5, 2021 · 3 comments
Closed

Code splitting: invalid export generated in shared chunk #1252

nihalgonsalves opened this issue May 5, 2021 · 3 comments

Comments

@nihalgonsalves
Copy link

nihalgonsalves commented May 5, 2021

When building a client library with multiple imports from @apollo/client, I ran into an issue with an invalid export in a shared chunk. I'm not sure if it's related to using multiple entry points from the same package, or just their relation to the shared code as a general code splitting issue.


Here's a minimal reproduction (using esbuild 0.11.18):

mkdir reproduction
cd reproduction
yarn init -y
yarn add esbuild @apollo/client graphql react
yarn esbuild \
  @apollo/client @apollo/client/utilities \
    --outdir=./out \
    --splitting \
    --format=esm \
    --bundle
echo '{"type": "module"}' > out/package.json
node out/client.js

(or in the codesandbox I created here, which has a consistent environment and dependencies).

In the common shared chunk, a dependency (Observable) is exported, but not defined:

file://<parent>/reproduction/out/chunk-UUIPIWOR.js:5315
  Observable,
  ^^^^^^^^^^

SyntaxError: Export 'Observable' is not defined in module

Possible resolution:

Looking at the context around it:

  offsetLimitPagination,
  relayStylePagination,
  import_zen_observable, // <--- ⬅️
  Observable,            // <--- ⬅️
  cloneDeep,
  maybeDeepFreeze,

It looks like the right output would be: import_zen_observable as Observable, but it has been exported on its own instead. Changing the file manually does make the syntax error go away.

@nihalgonsalves
Copy link
Author

nihalgonsalves commented May 5, 2021

Here's another one:

mkdir reproduction
cd reproduction
yarn init -y
yarn add esbuild react react-dom react-redux redux-form
yarn esbuild \
  react-redux redux-form \
    --outdir=./out \
    --splitting \
    --format=esm \
    --bundle
echo '{"type": "module"}' > out/package.json

node out/react-redux.js

# file:///<parent>/reproduction/out/chunk-3VTBGEZC.js:1629
#   unstable_batchedUpdates
#   ^^^^^^^^^^^^^^^^^^^^^^^
# 
# SyntaxError: Export 'unstable_batchedUpdates' is not defined in module
#    at Loader.moduleStrategy (internal/modules/esm/translators.js:145:18)

This one isn't so clear:

// node_modules/react-redux/es/utils/batch.js
function defaultNoopBatch(callback) {
  callback();
}
var batch = defaultNoopBatch; // <-- ⬅️ this is the right export
var setBatch = function setBatch2(newBatch) {
  return batch = newBatch;
};
var getBatch = function getBatch2() {
  return batch;
};

/*... omitted code in between ... */

// node_modules/react-redux/es/index.js
setBatch(import_react_dom.unstable_batchedUpdates); // <-- ⬅️ set here

export {
  require_react_is,
  require_prop_types,
  ReactReduxContext,
  Provider_default,
  _extends,
  _objectWithoutPropertiesLoose,
  require_hoist_non_react_statics_cjs,
  connectAdvanced,
  shallowEqual,
  connect_default,
  createStoreHook,
  useStore,
  createDispatchHook,
  useDispatch,
  createSelectorHook,
  useSelector,
  unstable_batchedUpdates // <-- ⬅️ but not exported here
};

The correct behaviour would to simply export batch without renaming. This is the original file:

import Provider from './components/Provider';
import connectAdvanced from './components/connectAdvanced';
import { ReactReduxContext } from './components/Context';
import connect from './connect/connect';
import { useDispatch, createDispatchHook } from './hooks/useDispatch';
import { useSelector, createSelectorHook } from './hooks/useSelector';
import { useStore, createStoreHook } from './hooks/useStore';
import { setBatch } from './utils/batch';
//       ⬇️ Looks like it's trying to export the original imported name, instead of the alias
import { unstable_batchedUpdates as batch } from './utils/reactBatchedUpdates';
import shallowEqual from './utils/shallowEqual';
setBatch(batch);
export { Provider, connectAdvanced, ReactReduxContext, connect, batch, useDispatch, createDispatchHook, useSelector, createSelectorHook, useStore, createStoreHook, shallowEqual }

(Both these reproductions do not produce errors with v0.9.7, but error on v0.10.0 and latest (v0.11.18))

@evanw
Copy link
Owner

evanw commented May 6, 2021

Thanks for such a detailed report. I can now reproduce the issue myself, so I will investigate.

@eric-burel
Copy link

Hi, just for the record, does library that depends on @apollo/client work ok with you?I have some trouble with named exports like "gql" tag graphql/graphql-js#2721

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

No branches or pull requests

3 participants