Mirror: The highly customizable and versatile GraphQL client with which you add on features like normalized caching as you grow.

(build) - Fix graphql imports for Webpack 5 (#1094)

* Upgrade babel-plugin-modular-graphql

* Merge Rollup build pipelines and move babel-plugin-modular-graphql

* Add changeset

* Fix extension input on makeOutputPlugins for React bundles

* Fix broken exports on preact-urql's hooks/index.ts

* Update changeset with Webpack 5 callout

Changed files
+86 -66
.changeset
packages
preact-urql
src
hooks
scripts
+10
.changeset/thin-rings-tell.md
···
+
---
+
'@urql/preact': patch
+
'@urql/exchange-execute': patch
+
'@urql/exchange-graphcache': patch
+
'@urql/exchange-populate': patch
+
'@urql/core': patch
+
'@urql/introspection': patch
+
---
+
+
Add missing `.mjs` extension to all imports from `graphql` to fix Webpack 5 builds, which require extension-specific import paths for ESM bundles and packages. **This change allows you to safely upgrade to Webpack 5.**
+1 -1
package.json
···
"@typescript-eslint/eslint-plugin": "^4.1.0",
"@typescript-eslint/parser": "^4.1.0",
"babel-plugin-closure-elimination": "^1.3.2",
-
"babel-plugin-modular-graphql": "0.1.3",
+
"babel-plugin-modular-graphql": "1.0.0",
"babel-plugin-transform-async-to-promises": "^0.8.15",
"dotenv": "^8.2.0",
"eslint": "^7.8.1",
+1 -6
packages/preact-urql/src/hooks/index.ts
···
-
export {
-
useQuery,
-
UseQueryArgs,
-
UseQueryResponse,
-
UseQueryState,
-
} from './useQuery';
+
export * from './useQuery';
export * from './useMutation';
export * from './useSubscription';
+5 -1
scripts/rollup/cleanup-plugin.js
···
import { transformSync as transform } from '@babel/core';
import { createFilter } from '@rollup/pluginutils';
+
import babelPluginModularGraphQL from 'babel-plugin-modular-graphql';
function removeEmptyImports({ types: t }) {
return {
···
}
return transform(code, {
-
plugins: [removeEmptyImports],
+
plugins: [
+
[babelPluginModularGraphQL, { extension: opts.extension }],
+
removeEmptyImports
+
],
babelrc: false
});
}
+39 -37
scripts/rollup/config.js
···
import genPackageJson from 'rollup-plugin-generate-package-json';
import { relative, join, dirname, basename } from 'path';
-
import { makePlugins } from './plugins';
+
import { makePlugins, makeOutputPlugins } from './plugins';
import * as settings from './settings';
-
const plugins = makePlugins({ isProduction: false });
+
const plugins = makePlugins();
const input = settings.sources.reduce((acc, source) => {
acc[source.name] = source.source;
···
return acc;
}, {});
-
const config = {
+
const output = ({ format, isProduction }) => {
+
if (typeof isProduction !== 'boolean')
+
throw new Error('Invalid option `isProduction` at output({ ... })');
+
if (format !== 'cjs' && format !== 'esm')
+
throw new Error('Invalid option `format` at output({ ... })');
+
+
const extension = format === 'esm'
+
? (settings.hasReact ? '.es.js' : '.mjs')
+
: '.js';
+
+
return {
+
chunkFileNames: '[hash]' + extension,
+
entryFileNames: '[name]' + extension,
+
dir: './dist',
+
exports: 'named',
+
externalLiveBindings: false,
+
sourcemap: true,
+
esModule: false,
+
indent: false,
+
freeze: false,
+
strict: false,
+
format,
+
plugins: makeOutputPlugins({
+
isProduction,
+
extension: format === 'esm' ? '.mjs' : '.js',
+
})
+
};
+
};
+
+
export default {
input,
external: settings.isExternal,
onwarn() {},
+
plugins,
+
output: [
+
output({ format: 'cjs', isProduction: false }),
+
output({ format: 'esm', isProduction: false }),
+
!settings.isCI && output({ format: 'cjs', isProduction: true }),
+
!settings.isCI && output({ format: 'esm', isProduction: true }),
+
].filter(Boolean),
treeshake: {
unknownGlobalSideEffects: false,
tryCatchDeoptimization: false,
moduleSideEffects: false
}
};
-
-
const output = (format = 'cjs', ext = '.js') => ({
-
chunkFileNames: '[hash]' + ext,
-
entryFileNames: '[name]' + ext,
-
dir: './dist',
-
exports: 'named',
-
externalLiveBindings: false,
-
sourcemap: true,
-
esModule: false,
-
indent: false,
-
freeze: false,
-
strict: false,
-
format,
-
});
-
-
export default [
-
{
-
...config,
-
shimMissingExports: true,
-
plugins,
-
output: [
-
output('cjs', '.js'),
-
output('esm', settings.hasReact ? '.es.js' : '.mjs'),
-
],
-
},
-
!settings.isCI && {
-
...config,
-
plugins: makePlugins({ isProduction: true }),
-
output: [
-
output('cjs', '.min.js'),
-
output('esm', settings.hasReact ? '.min.es.js' : '.min.mjs'),
-
],
-
},
-
].filter(Boolean);
+26 -17
scripts/rollup/plugins.js
···
import * as settings from './settings';
-
export const makePlugins = ({ isProduction } = {}) => [
+
export const makePlugins = () => [
resolve({
dedupe: settings.externalModules,
extensions: ['.js', '.jsx', '.ts', '.tsx'],
···
compilerOptions: {
sourceMap: true,
noEmit: false,
-
declaration: !isProduction,
+
declaration: true,
declarationDir: settings.types,
target: 'esnext',
},
···
babelPluginTransformDebugTarget,
babelPluginTransformPipe,
babelPluginTransformInvariant,
-
'babel-plugin-modular-graphql',
'babel-plugin-closure-elimination',
'@babel/plugin-transform-object-assign',
settings.hasReact && ['@babel/plugin-transform-react-jsx', {
···
}]
].filter(Boolean)
}),
-
isProduction && replace({
-
'process.env.NODE_ENV': JSON.stringify('production')
-
}),
-
!settings.mayReexport && compiler({
-
formatting: 'PRETTY_PRINT',
-
compilation_level: 'SIMPLE_OPTIMIZATIONS'
-
}),
-
cleanup(),
-
isProduction ? terserMinified : terserPretty,
-
isProduction && settings.isAnalyze && visualizer({
-
filename: path.resolve(settings.cwd, 'node_modules/.cache/analyze.html'),
-
sourcemap: true,
-
}),
-
].filter(Boolean);
+
];
+
+
export const makeOutputPlugins = ({ isProduction, extension }) => {
+
if (typeof isProduction !== 'boolean')
+
throw new Error('Missing option `isProduction` on makeOutputPlugins({ ... })');
+
if (extension !== '.mjs' && extension !== '.js')
+
throw new Error('Missing option `extension` on makeOutputPlugins({ ... })');
+
+
return [
+
isProduction && replace({
+
'process.env.NODE_ENV': JSON.stringify('production')
+
}),
+
!settings.mayReexport && compiler({
+
formatting: 'PRETTY_PRINT',
+
compilation_level: 'SIMPLE_OPTIMIZATIONS'
+
}),
+
cleanup({ extension }),
+
isProduction ? terserMinified : terserPretty,
+
isProduction && settings.isAnalyze && visualizer({
+
filename: path.resolve(settings.cwd, 'node_modules/.cache/analyze.html'),
+
sourcemap: true,
+
}),
+
].filter(Boolean);
+
};
const terserPretty = terser({
warnings: true,
+4 -4
yarn.lock
···
dependencies:
babel-helper-is-void-0 "^0.4.3"
-
babel-plugin-modular-graphql@0.1.3:
-
version "0.1.3"
-
resolved "https://registry.yarnpkg.com/babel-plugin-modular-graphql/-/babel-plugin-modular-graphql-0.1.3.tgz#23d474daab2278229bfc9a9f2491f3e1d9f555f1"
-
integrity sha512-13QBZm1sqPTHVBlG79p0jswR+FdNIIaxRrg1tNjpfGYU4U9M8bEDVQ51QK9+cZ6zUBQ0k2mh0iRvCjZt+856pg==
+
babel-plugin-modular-graphql@1.0.0:
+
version "1.0.0"
+
resolved "https://registry.yarnpkg.com/babel-plugin-modular-graphql/-/babel-plugin-modular-graphql-1.0.0.tgz#f8575e746895cf9652ec1ad804661791f520d56c"
+
integrity sha512-yyj8KcO1YU4LfaUGOyP1DY9y3CdqRhc5WhTWYD2XNx8jX4OBLVED+QBY1QmCNLsVqyXyfsv86C2BnwaMnFfDKQ==
babel-plugin-named-asset-import@^0.3.1:
version "0.3.6"