Skip to content

Commit

Permalink
Merge pull request #5541 from apollographql/fix/react-import
Browse files Browse the repository at this point in the history
[V3] Create @apollo/client/core bundle
  • Loading branch information
hwillson authored Nov 12, 2019
2 parents ab0bbe2 + 1a5ba28 commit 94f3b84
Show file tree
Hide file tree
Showing 14 changed files with 223 additions and 160 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@
- The `gql` template tag should now be imported from the `@apollo/client` package, rather than the `graphql-tag` package. Although the `graphql-tag` package still works for now, future versions of `@apollo/client` may change the implementation details of `gql` without a major version bump. <br/>
[@hwillson](https://github.com/hwillson) in [#5451](https://github.com/apollographql/apollo-client/pull/5451)

- `@apollo/client/core` can be used to import the Apollo Client core, which includes everything the main `@apollo/client` package does, except for all React related functionality. <br/>
[@kamilkisiela](https://github.com/kamilkisiela) in [#5541](https://github.com/apollographql/apollo-client/pull/5541)

### Breaking Changes

- Removed `graphql-anywhere` since it's no longer used by Apollo Client. <br/>
Expand Down Expand Up @@ -65,6 +68,8 @@
- The `ObservableQuery#getCurrentResult` method no longer falls back to reading from the cache, so calling it immediately after `client.watchQuery` will consistently return a `loading: true` result. When the `fetchPolicy` permits cached results, those results will be delivered via the `next` method of the `ObservableQuery`, and can be obtained by `getCurrentResult` after they have been delivered. This change prevents race conditions where the initial behavior of one query could depend on the timing of cache writes associated with other queries. </br>
[@benjamn](https://github.com/benjamn) in [#5565](https://github.com/apollographql/apollo-client/pull/5565)

- The `QueryOptions`, `MutationOptions`, and `SubscriptionOptions` React Apollo interfaces have been renamed to `QueryDataOptions`, `MutationDataOptions`, and `SubscriptionDataOptions` (to avoid conflicting with similarly named and exported Apollo Client interfaces).

## Apollo Client (2.6.4)

### Apollo Client (2.6.4)
Expand Down
73 changes: 62 additions & 11 deletions config/prepareDist.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,23 @@
// The Apollo Client source that is published to npm is located in the
// "dist" directory. This utility script is called just before deploying
// Apollo Client, to make sure the "dist" directory is prepared for publishing.
// "dist" directory. This utility script is called when building Apollo Client,
// to make sure the "dist" directory is prepared for publishing.
//
// This script will:
//
// - Copy the current root package.json into "dist" after adjusting it for
// publishing.
// - Copy the supporting files from the root into "dist" (e.g. `README.MD`,
// `LICENSE`, etc.)
// `LICENSE`, etc.).
// - Create a new `package.json` for each sub-set bundle we support, and
// store it in the appropriate dist sub-directory.

const packageJson = require('../package.json');
const fs = require('fs');
const recast = require('recast');


/* @apollo/client */

const packageJson = require('../package.json');

// The root package.json is marked as private to prevent publishing
// from happening in the root of the project. This sets the package back to
Expand All @@ -25,13 +32,14 @@ delete packageJson.bundlesize;
// on-going package development (e.g. running tests, supporting npm link, etc.).
// When publishing from "dist" however, we need to update the package.json
// to point to the files within the same directory.
const distPackageJson = JSON.stringify(
packageJson,
(_key, value) => (
typeof value === 'string' ? value.replace(/\.\/dist\//, '') : value
),
2
);
const distPackageJson = JSON.stringify(packageJson, (_key, value) => {
if (typeof value === 'string' && value.startsWith('./dist/')) {
const parts = value.split('/');
parts.splice(1, 1); // remove dist
return parts.join('/');
}
return value;
}, 2) + "\n";

// Save the modified package.json to "dist"
fs.writeFileSync(`${__dirname}/../dist/package.json`, distPackageJson);
Expand All @@ -41,3 +49,46 @@ const srcDir = `${__dirname}/..`;
const destDir = `${srcDir}/dist`;
fs.copyFileSync(`${srcDir}/README.md`, `${destDir}/README.md`);
fs.copyFileSync(`${srcDir}/LICENSE`, `${destDir}/LICENSE`);


/* @apollo/client/core */

function buildPackageJson(bundleName) {
return JSON.stringify({
name: `@apollo/client/${bundleName}`,
main: `${bundleName}.cjs.js`,
module: 'index.js',
types: 'index.d.ts',
}, null, 2) + "\n";
}

// Create a `core` bundle package.json, storing it in the dist core
// directory. This helps provide a way for Apollo Client to be used without
// React, via `@apollo/client/core`.
fs.writeFileSync(
`${__dirname}/../dist/core/package.json`,
buildPackageJson('core')
);

// Build a new `core.cjs.js` entry point file, that includes everything
// except the exports listed in `src/react/index.ts`. Copy this file into
// the `dist/core` directory, to allow Apollo Client core only imports
// using `@apollo/client/core`.

const reactIndexSrc = fs.readFileSync(`${__dirname}/../dist/react/index.js`);
const reactExports = [];
recast.visit(recast.parse(reactIndexSrc), {
visitExportSpecifier(path) {
reactExports.push(path.value.exported.name);
return false;
},
});

fs.writeFileSync(`${__dirname}/../dist/core/core.cjs.js`, [
"const allExports = require('../apollo-client.cjs');",
`const reactExportNames = new Set(${JSON.stringify(reactExports)});`,
"Object.keys(allExports).forEach(name => {",
" if (!reactExportNames.has(name)) exports[name] = allExports[name];",
"});",
"",
].join('\n'));
46 changes: 23 additions & 23 deletions config/rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import packageJson from '../package.json';
const distDir = './dist';

const globals = {
'tslib': 'tslib',
tslib: 'tslib',
'ts-invariant': 'invariant',
'symbol-observable': '$$observable',
'graphql/language/printer': 'print',
Expand All @@ -21,7 +21,7 @@ const globals = {
'@wry/equality': 'wryEquality',
graphql: 'graphql',
react: 'React',
'zen-observable': 'Observable'
'zen-observable': 'Observable',
};

const hasOwn = Object.prototype.hasOwnProperty;
Expand All @@ -30,12 +30,12 @@ function external(id) {
return hasOwn.call(globals, id);
}

function prepareESM() {
function prepareESM(input, outputDir) {
return {
input: packageJson.module,
input,
external,
output: {
dir: distDir,
dir: outputDir,
format: 'esm',
sourcemap: true,
},
Expand All @@ -58,39 +58,39 @@ function prepareESM() {
}),
cjs({
namedExports: {
'graphql-tag': ['gql']
}
'graphql-tag': ['gql'],
},
}),
]
],
};
}

function prepareCJS() {
function prepareCJS(input, output) {
return {
input: packageJson.module,
input,
external,
output: {
file: packageJson.main,
file: output,
format: 'cjs',
sourcemap: true,
exports: 'named'
exports: 'named',
},
plugins: [
nodeResolve(),
cjs({
namedExports: {
'graphql-tag': ['gql']
}
'graphql-tag': ['gql'],
},
}),
]
}
],
};
}

function prepareCJSMinified() {
function prepareCJSMinified(input) {
return {
input: packageJson.main,
input,
output: {
file: packageJson.main.replace('.js', '.min.js'),
file: input.replace('.js', '.min.js'),
format: 'cjs',
},
plugins: [
Expand Down Expand Up @@ -141,10 +141,10 @@ function prepareTesting() {

function rollup() {
return [
prepareESM(),
prepareCJS(),
prepareCJSMinified(),
prepareTesting()
prepareESM(packageJson.module, distDir),
prepareCJS(packageJson.module, packageJson.main),
prepareCJSMinified(packageJson.main),
prepareTesting(),
];
}

Expand Down
6 changes: 3 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
"scripts": {
"prebuild": "npm run clean",
"build": "npx tsc",
"postbuild": "npm run bundle",
"postbuild": "npm run bundle && npm run prepdist",
"watch": "npx tsc-watch --onSuccess \"npm run postbuild\"",
"clean": "npx rimraf -r dist coverage lib",
"test": "jest --config ./config/jest.config.js",
Expand All @@ -41,7 +41,7 @@
"coverage:upload": "npx codecov",
"bundlesize": "npm run build && bundlesize",
"prepdist": "node ./config/prepareDist.js",
"predeploy": "npm run build && npm run prepdist",
"predeploy": "npm run build",
"deploy": "cd dist && npm publish --tag beta"
},
"bundlesize": [
Expand Down Expand Up @@ -89,6 +89,7 @@
"prop-types": "15.7.2",
"react": "^16.11.0",
"react-dom": "^16.11.0",
"recast": "^0.18.5",
"rimraf": "^3.0.0",
"rollup": "1.21.2",
"rollup-plugin-commonjs": "^10.1.0",
Expand Down
85 changes: 85 additions & 0 deletions src/core/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
/* Core */

export {
ApolloClient,
ApolloClientOptions,
DefaultOptions
} from '../ApolloClient';
export {
ObservableQuery,
FetchMoreOptions,
UpdateQueryOptions,
ApolloCurrentQueryResult,
} from '../core/ObservableQuery';
export {
QueryBaseOptions,
QueryOptions,
WatchQueryOptions,
MutationOptions,
SubscriptionOptions,
FetchPolicy,
WatchQueryFetchPolicy,
ErrorPolicy,
FetchMoreQueryOptions,
SubscribeToMoreOptions,
MutationUpdaterFn,
} from '../core/watchQueryOptions';
export { NetworkStatus } from '../core/networkStatus';
export * from '../core/types';
export {
Resolver,
FragmentMatcher as LocalStateFragmentMatcher,
} from '../core/LocalState';
export { isApolloError, ApolloError } from '../errors/ApolloError';

/* Cache */

export { Transaction, ApolloCache } from '../cache/core/cache';
export { Cache } from '../cache/core/types/Cache';
export { DataProxy } from '../cache/core/types/DataProxy';
export {
InMemoryCache,
InMemoryCacheConfig,
} from '../cache/inmemory/inMemoryCache';
export { defaultDataIdFromObject } from '../cache/inmemory/policies';
export * from '../cache/inmemory/types';

/* Link */

export { empty } from '../link/core/empty';
export { from } from '../link/core/from';
export { split } from '../link/core/split';
export { concat } from '../link/core/concat';
export { execute } from '../link/core/execute';
export { ApolloLink } from '../link/core/ApolloLink';
export * from '../link/core/types';
export {
parseAndCheckHttpResponse,
ServerParseError
} from '../link/http/parseAndCheckHttpResponse';
export {
serializeFetchParameter,
ClientParseError
} from '../link/http/serializeFetchParameter';
export {
HttpOptions,
fallbackHttpConfig,
selectHttpOptionsAndBody,
UriFunction
} from '../link/http/selectHttpOptionsAndBody';
export { checkFetcher } from '../link/http/checkFetcher';
export { createSignalIfSupported } from '../link/http/createSignalIfSupported';
export { selectURI } from '../link/http/selectURI';
export { createHttpLink } from '../link/http/createHttpLink';
export { HttpLink } from '../link/http/HttpLink';
export { fromError } from '../link/utils/fromError';
export { ServerError, throwServerError } from '../link/utils/throwServerError';

/* Utilities */

export { Observable } from '../utilities/observables/Observable';
export { getMainDefinition } from '../utilities/graphql/getFromAST';

/* Supporting */

export { default as gql } from 'graphql-tag';
Loading

0 comments on commit 94f3b84

Please sign in to comment.