Mirror: Modular GraphQL.js import paths without the hassle.

Initial Commit

kitten.sh d4e46c0c

+2
.gitignore
···
+
import-map.json
+
node_modules
+46
index.js
···
+
export default function({ types: t }) {
+
const importMap = require('./import-map.json');
+
const PKG_NAME = 'graphql';
+
+
return {
+
visitor: {
+
ImportDeclaration: {
+
exit(path) {
+
const { node } = path;
+
if (node.source.value !== PKG_NAME || !node.specifiers.length) return;
+
+
const imports = node.specifiers.reduce((acc, specifier) => {
+
if (t.isImportSpecifier(specifier)) {
+
const imported = specifier.imported.name;
+
const declaration = importMap[imported];
+
const from = declaration ? declaration.from : PKG_NAME;
+
if (!acc[from]) {
+
acc[from] = t.importDeclaration([], t.stringLiteral(from));
+
}
+
+
const localName = specifier.local.name;
+
const newImportedName = declaration ? declaration.local : imported;
+
+
acc[from].specifiers.push(
+
t.importSpecifier(
+
t.identifier(localName),
+
t.identifier(newImportedName)
+
)
+
);
+
}
+
+
return acc;
+
}, {});
+
+
const importFiles = Object.keys(imports);
+
if (
+
importFiles.length &&
+
(importFiles.length !== 1 || importFiles[0] !== PKG_NAME)
+
) {
+
path.replaceWithMultiple(importFiles.map(key => imports[key]));
+
}
+
},
+
},
+
},
+
};
+
}
+20
package.json
···
+
{
+
"name": "babel-plugin-modular-graphql",
+
"version": "0.1.0",
+
"main": "index.js",
+
"license": "MIT",
+
"files": [
+
"import-map.json",
+
"index.js"
+
],
+
"scripts": {
+
"build": "node scripts/generate-import-map.js",
+
"prepublishOnly": "node scripts/generate-import-map.js"
+
},
+
"devDependencies": {
+
"@rollup/plugin-node-resolve": "^7.1.3",
+
"acorn-walk": "^7.1.1",
+
"graphql": "^15.0.0",
+
"rollup": "^2.6.1"
+
}
+
}
+122
scripts/generate-import-map.js
···
+
const fs = require('fs');
+
const path = require('path');
+
+
const { rollup } = require('rollup');
+
+
const cwd = process.cwd();
+
const basepath = path.resolve(cwd, 'node_modules/graphql/');
+
+
function generateImportMapPlugin(opts = {}) {
+
const maxDepth = opts.maxDepth || 2;
+
const filename = opts.filename || 'import-map.json';
+
const map = new Map();
+
+
const resolveFile = (from, to) => {
+
return path.join(from, to);
+
};
+
+
const resolveFromMap = (id, name, depth = 0) => {
+
const exports = map.get(id);
+
if (!exports || !exports.has(name)) return null;
+
+
const declaration = exports.get(name);
+
if (depth >= maxDepth || declaration.from === id) {
+
return declaration;
+
}
+
+
return resolveFromMap(declaration.from, declaration.local, depth + 1)
+
|| declaration;
+
};
+
+
return {
+
name: 'generate-import-map',
+
transform(code, id) {
+
const relative = path.relative(basepath, id);
+
const dirname = path.dirname(relative);
+
const exports = new Map();
+
+
this.parse(code).body
+
.filter(x => x.type === 'ExportNamedDeclaration')
+
.forEach(node => {
+
const source = node.source
+
? resolveFile(dirname, node.source.value)
+
: relative;
+
+
node.specifiers.forEach(specifier => {
+
exports.set(specifier.exported.name, {
+
local: specifier.local.name,
+
from: source
+
});
+
});
+
+
if (node.declaration) {
+
(node.declaration.declarations || [node.declaration])
+
.forEach(declaration => {
+
if (declaration && declaration.id) {
+
const { name } = declaration.id;
+
exports.set(declaration.id.name, {
+
local: name,
+
from: source
+
});
+
}
+
});
+
}
+
});
+
+
map.set(relative, exports);
+
return null;
+
},
+
renderChunk(_code, chunk) {
+
const id = chunk.facadeModuleId;
+
const relative = path.relative(basepath, id);
+
+
if (chunk.isEntry) {
+
const importMap = chunk.exports.reduce((acc, name) => {
+
const declaration = resolveFromMap(relative, name);
+
if (declaration) {
+
const dirname = path.join('graphql/', path.dirname(declaration.from));
+
const filename = path.basename(declaration.from, '.mjs');
+
+
acc[name] = {
+
local: declaration.local,
+
from: path.join(dirname, filename),
+
};
+
}
+
+
return acc;
+
}, {});
+
+
this.emitFile({
+
type: 'asset',
+
filename,
+
name: filename,
+
source: JSON.stringify(importMap, null, 2)
+
});
+
}
+
},
+
};
+
}
+
+
(async () => {
+
const bundle = await rollup({
+
input: path.join(basepath, 'index.mjs'),
+
external: (id) => !/^\.{0,2}\//.test(id),
+
preserveModules: true,
+
plugins: [
+
require('@rollup/plugin-node-resolve')(),
+
generateImportMapPlugin({
+
filename: 'import-map.json'
+
})
+
],
+
});
+
+
const { output } = await bundle.generate({});
+
+
fs.writeFileSync(
+
path.resolve(cwd, 'import-map.json'),
+
output.find(asset => asset.type === 'asset').source
+
);
+
})().catch((err) => {
+
console.error(`${err.name}: ${err.message}`);
+
process.exit(1);
+
});
+128
yarn.lock
···
+
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
+
# yarn lockfile v1
+
+
+
"@rollup/plugin-node-resolve@^7.1.3":
+
version "7.1.3"
+
resolved "https://registry.yarnpkg.com/@rollup/plugin-node-resolve/-/plugin-node-resolve-7.1.3.tgz#80de384edfbd7bfc9101164910f86078151a3eca"
+
integrity sha512-RxtSL3XmdTAE2byxekYLnx+98kEUOrPHF/KRVjLH+DEIHy6kjIw7YINQzn+NXiH/NTrQLAwYs0GWB+csWygA9Q==
+
dependencies:
+
"@rollup/pluginutils" "^3.0.8"
+
"@types/resolve" "0.0.8"
+
builtin-modules "^3.1.0"
+
is-module "^1.0.0"
+
resolve "^1.14.2"
+
+
"@rollup/pluginutils@^3.0.8":
+
version "3.0.9"
+
resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-3.0.9.tgz#aa6adca2c45e5a1b950103a999e3cddfe49fd775"
+
integrity sha512-TLZavlfPAZYI7v33wQh4mTP6zojne14yok3DNSLcjoG/Hirxfkonn6icP5rrNWRn8nZsirJBFFpijVOJzkUHDg==
+
dependencies:
+
"@types/estree" "0.0.39"
+
estree-walker "^1.0.1"
+
micromatch "^4.0.2"
+
+
"@types/estree@0.0.39":
+
version "0.0.39"
+
resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.39.tgz#e177e699ee1b8c22d23174caaa7422644389509f"
+
integrity sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==
+
+
"@types/node@*":
+
version "13.11.1"
+
resolved "https://registry.yarnpkg.com/@types/node/-/node-13.11.1.tgz#49a2a83df9d26daacead30d0ccc8762b128d53c7"
+
integrity sha512-eWQGP3qtxwL8FGneRrC5DwrJLGN4/dH1clNTuLfN81HCrxVtxRjygDTUoZJ5ASlDEeo0ppYFQjQIlXhtXpOn6g==
+
+
"@types/resolve@0.0.8":
+
version "0.0.8"
+
resolved "https://registry.yarnpkg.com/@types/resolve/-/resolve-0.0.8.tgz#f26074d238e02659e323ce1a13d041eee280e194"
+
integrity sha512-auApPaJf3NPfe18hSoJkp8EbZzer2ISk7o8mCC3M9he/a04+gbMF97NkpD2S8riMGvm4BMRI59/SZQSaLTKpsQ==
+
dependencies:
+
"@types/node" "*"
+
+
acorn-walk@^7.1.1:
+
version "7.1.1"
+
resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-7.1.1.tgz#345f0dffad5c735e7373d2fec9a1023e6a44b83e"
+
integrity sha512-wdlPY2tm/9XBr7QkKlq0WQVgiuGTX6YWPyRyBviSoScBuLfTVQhvwg6wJ369GJ/1nPfTLMfnrFIfjqVg6d+jQQ==
+
+
braces@^3.0.1:
+
version "3.0.2"
+
resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107"
+
integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==
+
dependencies:
+
fill-range "^7.0.1"
+
+
builtin-modules@^3.1.0:
+
version "3.1.0"
+
resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-3.1.0.tgz#aad97c15131eb76b65b50ef208e7584cd76a7484"
+
integrity sha512-k0KL0aWZuBt2lrxrcASWDfwOLMnodeQjodT/1SxEQAXsHANgo6ZC/VEaSEHCXt7aSTZ4/4H5LKa+tBXmW7Vtvw==
+
+
estree-walker@^1.0.1:
+
version "1.0.1"
+
resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-1.0.1.tgz#31bc5d612c96b704106b477e6dd5d8aa138cb700"
+
integrity sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==
+
+
fill-range@^7.0.1:
+
version "7.0.1"
+
resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40"
+
integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==
+
dependencies:
+
to-regex-range "^5.0.1"
+
+
fsevents@~2.1.2:
+
version "2.1.2"
+
resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.1.2.tgz#4c0a1fb34bc68e543b4b82a9ec392bfbda840805"
+
integrity sha512-R4wDiBwZ0KzpgOWetKDug1FZcYhqYnUYKtfZYt4mD5SBz76q0KR4Q9o7GIPamsVPGmW3EYPPJ0dOOjvx32ldZA==
+
+
graphql@^15.0.0:
+
version "15.0.0"
+
resolved "https://registry.yarnpkg.com/graphql/-/graphql-15.0.0.tgz#042a5eb5e2506a2e2111ce41eb446a8e570b8be9"
+
integrity sha512-ZyVO1xIF9F+4cxfkdhOJINM+51B06Friuv4M66W7HzUOeFd+vNzUn4vtswYINPi6sysjf1M2Ri/rwZALqgwbaQ==
+
+
is-module@^1.0.0:
+
version "1.0.0"
+
resolved "https://registry.yarnpkg.com/is-module/-/is-module-1.0.0.tgz#3258fb69f78c14d5b815d664336b4cffb6441591"
+
integrity sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE=
+
+
is-number@^7.0.0:
+
version "7.0.0"
+
resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b"
+
integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==
+
+
micromatch@^4.0.2:
+
version "4.0.2"
+
resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.2.tgz#4fcb0999bf9fbc2fcbdd212f6d629b9a56c39259"
+
integrity sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==
+
dependencies:
+
braces "^3.0.1"
+
picomatch "^2.0.5"
+
+
path-parse@^1.0.6:
+
version "1.0.6"
+
resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c"
+
integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==
+
+
picomatch@^2.0.5:
+
version "2.2.2"
+
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad"
+
integrity sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==
+
+
resolve@^1.14.2:
+
version "1.15.1"
+
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.15.1.tgz#27bdcdeffeaf2d6244b95bb0f9f4b4653451f3e8"
+
integrity sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w==
+
dependencies:
+
path-parse "^1.0.6"
+
+
rollup@^2.6.1:
+
version "2.6.1"
+
resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.6.1.tgz#8354e67caa7b8bf24c2488d9e2f64da2be62eebe"
+
integrity sha512-1RhFDRJeg027YjBO6+JxmVWkEZY0ASztHhoEUEWxOwkh4mjO58TFD6Uo7T7Y3FbmDpRTfKhM5NVxJyimCn0Elg==
+
optionalDependencies:
+
fsevents "~2.1.2"
+
+
to-regex-range@^5.0.1:
+
version "5.0.1"
+
resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4"
+
integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==
+
dependencies:
+
is-number "^7.0.0"