Mirror: The small sibling of the graphql package, slimmed down for client-side libraries.
1import * as path from 'path'; 2import { promises as fs } from 'fs'; 3 4import resolve from '@rollup/plugin-node-resolve'; 5import buble from '@rollup/plugin-buble'; 6import { babel } from '@rollup/plugin-babel'; 7import { terser } from 'rollup-plugin-terser'; 8 9import babelModularGraphQL from 'babel-plugin-modular-graphql'; 10import babelTransformComputedProps from '../babel/transformComputedProps.mjs'; 11import babelTransformDevAssert from '../babel/transformDevAssert.mjs'; 12import babelTransformObjectFreeze from '../babel/transformObjectFreeze.mjs'; 13 14import packageMetadata from './packageMetadata'; 15 16const cwd = process.cwd(); 17const graphqlModule = path.join(cwd, 'node_modules/graphql/'); 18const virtualModule = path.join(cwd, 'virtual/'); 19const aliasModule = path.join(cwd, 'alias/'); 20 21const EXTERNAL = 'graphql'; 22const externalModules = ['dns', 'fs', 'path', 'url']; 23const externalPredicate = new RegExp(`^(${externalModules.join('|')})($|/)`); 24 25const exports = {}; 26const importMap = require('./importMap.json'); 27 28for (const key in importMap) { 29 const { from, local } = importMap[key]; 30 if (/\/jsutils\//g.test(from)) continue; 31 32 const name = from.replace(/^graphql\//, ''); 33 exports[name] = (exports[name] || '') + `export { ${key} } from '${EXTERNAL}'\n`; 34 35 const parts = name.split('/'); 36 for (let i = parts.length - 1; i > 0; i--) { 37 const name = `${parts.slice(0, i).join('/')}/index`; 38 const from = `./${parts.slice(i).join('/')}`; 39 exports[name] = (exports[name] || '') + `export { ${local} } from '${from}'\n`; 40 } 41 42 const index = `export { ${local} } from './${name}'\n`; 43 exports.index = (exports.index || '') + index; 44} 45 46const manualChunks = (id, utils) => { 47 let chunk; 48 if (id.startsWith(graphqlModule)) { 49 chunk = id.slice(graphqlModule.length); 50 } else if (id.startsWith(virtualModule)) { 51 chunk = id.slice(virtualModule.length); 52 } else if (id.startsWith(aliasModule)) { 53 chunk = id.slice(aliasModule.length); 54 } 55 56 if (chunk) { 57 return chunk.replace(/\.m?js$/, ''); 58 } 59 60 const { importers } = utils.getModuleInfo(id); 61 return importers.length === 1 62 ? manualChunks(importers[0], utils) 63 : 'shared'; 64}; 65 66export default { 67 input: 68 Object.keys(exports).reduce((input, key) => { 69 input[key] = path.join('./virtual', key); 70 return input; 71 }, {}), 72 external(id) { 73 return externalPredicate.test(id); 74 }, 75 treeshake: { 76 unknownGlobalSideEffects: false, 77 tryCatchDeoptimization: false, 78 moduleSideEffects: false, 79 }, 80 plugins: [ 81 { 82 async load(id) { 83 if (!id.startsWith(virtualModule)) 84 return null; 85 86 const entry = path.relative(virtualModule, id).replace(/\.m?js$/, ''); 87 return exports[entry] || null; 88 }, 89 90 async resolveId(source, importer) { 91 if (!source.startsWith('.') && !source.startsWith('virtual/')) 92 return null; 93 94 const target = path.join(importer ? path.dirname(importer) : cwd, source); 95 96 const virtualEntry = path.relative(virtualModule, target); 97 if (!virtualEntry.startsWith('../')) { 98 const aliasSource = path.join(aliasModule, virtualEntry); 99 const alias = await this.resolve(aliasSource, undefined, { skipSelf: true }); 100 return alias || target; 101 } 102 103 const graphqlEntry = path.relative(graphqlModule, target); 104 if (!graphqlEntry.startsWith('../')) { 105 const aliasSource = path.join(aliasModule, graphqlEntry); 106 const alias = await this.resolve(aliasSource, undefined, { skipSelf: true }); 107 return alias || target; 108 } 109 110 return null; 111 }, 112 113 async renderStart() { 114 this.emitFile({ 115 type: 'asset', 116 fileName: 'package.json', 117 source: packageMetadata, 118 }); 119 }, 120 121 async renderChunk(_code, { fileName }) { 122 const name = fileName.replace(/\.m?js$/, ''); 123 124 const getContents = async (extension) => { 125 try { 126 const name = fileName.replace(/\.m?js$/, ''); 127 const contents = await fs.readFile(path.join(graphqlModule, name + extension)); 128 return contents; 129 } catch (_error) { 130 return null; 131 } 132 } 133 134 const dts = await getContents('.d.ts'); 135 const flow = await getContents('.js.flow'); 136 137 if (dts) { 138 this.emitFile({ 139 type: 'asset', 140 fileName: name + '.d.ts', 141 source: dts, 142 }); 143 } 144 145 if (flow) { 146 this.emitFile({ 147 type: 'asset', 148 fileName: name + '.js.flow', 149 source: flow, 150 }); 151 } 152 153 return null; 154 }, 155 }, 156 157 resolve({ 158 extensions: ['.mjs', '.js'], 159 mainFields: ['module', 'browser', 'main'], 160 preferBuiltins: false, 161 browser: true, 162 }), 163 164 babel({ 165 babelrc: false, 166 babelHelpers: 'bundled', 167 presets: [], 168 plugins: [ 169 babelTransformDevAssert, 170 babelTransformObjectFreeze, 171 babelTransformComputedProps, 172 babelModularGraphQL, 173 'reghex/babel', 174 ], 175 }), 176 177 buble({ 178 transforms: { 179 unicodeRegExp: false, 180 dangerousForOf: true, 181 dangerousTaggedTemplateString: true, 182 asyncAwait: false, 183 }, 184 objectAssign: 'Object.assign', 185 }), 186 187 terser({ 188 warnings: true, 189 ecma: 5, 190 keep_fnames: true, 191 ie8: false, 192 compress: { 193 pure_getters: true, 194 toplevel: true, 195 booleans_as_integers: false, 196 keep_fnames: true, 197 keep_fargs: true, 198 if_return: false, 199 ie8: false, 200 sequences: false, 201 loops: false, 202 conditionals: false, 203 join_vars: false 204 }, 205 mangle: { 206 module: true, 207 keep_fnames: true, 208 }, 209 output: { 210 beautify: true, 211 braces: true, 212 indent_level: 2 213 } 214 }), 215 ], 216 217 treeshake: 'smallest', 218 shimMissingExports: false, 219 preserveEntrySignatures: 'allow-extension', 220 221 output: [ 222 { 223 chunkFileNames: '[name].js', 224 entryFileNames: '[name].js', 225 dir: './dist', 226 exports: 'named', 227 format: 'cjs', 228 minifyInternalExports: false, 229 hoistTransitiveImports: false, 230 manualChunks, 231 }, 232 { 233 chunkFileNames: '[name].mjs', 234 entryFileNames: '[name].mjs', 235 dir: './dist', 236 exports: 'named', 237 format: 'esm', 238 minifyInternalExports: false, 239 hoistTransitiveImports: false, 240 manualChunks, 241 }, 242 ], 243};