-
Notifications
You must be signed in to change notification settings - Fork 1.8k
babel-plugin-relay should support ecmascript module importing #2706
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
Comments
Alright, I got this working locally. I ripped apart The meat of the change is in 'use strict';
function getValidGraphQLTag(path) {
const tag = path.get('tag');
if (!tag.isIdentifier({ name: 'graphql' })) {
return null;
}
const quasis = path.node.quasi.quasis;
if (quasis.length !== 1) {
throw new Error(
'BabelPluginRelay: Substitutions are not allowed in graphql fragments. ' +
'Included fragments should be referenced as `...MyModule_propName`.',
);
}
const text = quasis[0].value.raw;
const match = /^\s*(query|mutation|subscription|fragment)\s*(\w+)/.exec(text);
if (!match) {
throw new Error('Unable to parse ' + text);
}
return { type: match[1], name: match[2] };
}
/**
* Given a graphql`` tagged template literal, replace it with the appropriate
* runtime artifact.
*/
function compileGraphQLTag(t, path, state, type, name) {
return replaceMemoized(t, path, createAST(t, state, path, type, name));
}
function createAST(t, state, path, type, name) {
const isHasteMode = Boolean(state.opts && state.opts.haste);
const isDevVariable = state.opts && state.opts.isDevVariable;
const artifactDirectory = state.opts && state.opts.artifactDirectory;
const buildCommand =
(state.opts && state.opts.buildCommand) || 'relay-compiler';
// Fallback is 'true'
const isDevelopment =
(process.env.BABEL_ENV || process.env.NODE_ENV) !== 'production';
const modernNode = createModernNode(t, path, type, name, state, {
artifactDirectory,
buildCommand,
isDevelopment,
isHasteMode,
isDevVariable,
});
return modernNode;
}
function getTopScope(path) {
let topScope = path.scope;
while (topScope.parent) {
topScope = topScope.parent;
}
return topScope;
}
function replaceMemoized(t, path, ast) {
const topScope = getTopScope(path);
if (path.scope === topScope) {
path.replaceWith(ast);
} else {
const id = topScope.generateDeclaredUidIdentifier('graphql');
path.replaceWith(
t.logicalExpression('||', id, t.assignmentExpression('=', id, ast)),
);
}
}
const GENERATED = './__generated__/';
function createModernNode(t, path, type, definitionName, state, options) {
const requiredFile = definitionName + '.graphql';
const requiredPath = options.isHasteMode
? requiredFile
: options.artifactDirectory
? getRelativeImportPath(state, options.artifactDirectory, requiredFile)
: GENERATED + requiredFile;
const topScope = getTopScope(path);
const nodeVariable = topScope.generateUidIdentifier(definitionName);
const importDefaultSpecifier = t.importDefaultSpecifier(nodeVariable);
const importDeclaration = t.importDeclaration(
[importDefaultSpecifier],
t.stringLiteral(requiredPath),
);
topScope.path.unshiftContainer('body', importDeclaration);
const bodyStatements = [t.returnStatement(nodeVariable)];
return t.functionExpression(null, [], t.blockStatement(bodyStatements));
}
function BabelPluginRelay(context) {
const { types: t } = context;
if (!t) {
throw new Error(
'BabelPluginRelay: Expected plugin context to include "types", but got:' +
String(context),
);
}
const visitor = {
TaggedTemplateExpression(path, state) {
// Convert graphql`` literals
const tag = getValidGraphQLTag(path);
if (tag) {
compileGraphQLTag(t, path, state, tag.type, tag.name);
}
},
};
return {
visitor: {
Program(path, state) {
path.traverse(visitor, state);
},
},
};
}
module.exports = BabelPluginRelay; |
Thanks @ckknight , I was trying this out but |
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. |
Has anyone found a sustainable solution to this? Started a new project with rollup plus snowpack and trying out relay and ran into this exact same issue :( Seems there's only appetite to support bundlers like Webpack for this library. I believe this issue #2445 is also related |
I added eagerESModules option to relay config some time ago. Please try it. |
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. |
When using
babel-plugin-relay
,graphql
template tag calls are converted into a function that usesrequire
to load another file.It would be nice to be able to opt-in to using an ECMAScript module-friendly
import
statement rather than relying on the commonjsrequire
.This would ideally make it easier to integrate into tools like
rollup
.The text was updated successfully, but these errors were encountered: