1import dts from 'rollup-plugin-dts';
2
3import * as fs from 'fs/promises';
4import { relative, join, dirname, basename } from 'path';
5
6import { makePlugins, makeBasePlugins, makeOutputPlugins } from './plugins.mjs';
7import cleanup from './cleanup-plugin.mjs';
8import * as settings from './settings.mjs';
9
10const plugins = makePlugins();
11const isCI = !!process.env.CI;
12
13const chunkFileNames = extension => {
14 let hasDynamicChunk = false;
15 return chunkInfo => {
16 if (
17 chunkInfo.isDynamicEntry ||
18 chunkInfo.isEntry ||
19 chunkInfo.isImplicitEntry
20 ) {
21 return `[name]${extension}`;
22 } else if (!hasDynamicChunk) {
23 hasDynamicChunk = true;
24 return `${settings.name}-chunk${extension}`;
25 } else {
26 return `[name]-chunk${extension}`;
27 }
28 };
29};
30
31const input = settings.sources.reduce((acc, source) => {
32 acc[source.name] = source.source;
33 if (source.name !== settings.name) {
34 const rel = relative(source.dir, process.cwd());
35 plugins.push({
36 async writeBundle() {
37 const packageJson = JSON.stringify(
38 {
39 name: source.name,
40 private: true,
41 version: '0.0.0',
42 main: join(rel, dirname(source.main), basename(source.main, '.js')),
43 module: join(rel, source.module),
44 types: join(rel, source.types),
45 source: join(rel, source.source),
46 exports: {
47 '.': {
48 types: join(rel, source.types),
49 import: join(rel, source.module),
50 require: join(rel, source.main),
51 source: join(rel, source.source),
52 },
53 './package.json': './package.json',
54 },
55 },
56 null,
57 2
58 ).trim();
59
60 await fs.mkdir(source.dir, { recursive: true });
61 await fs.writeFile(
62 join(source.dir, 'package.json'),
63 packageJson + '\n'
64 );
65 },
66 });
67 }
68
69 return acc;
70}, {});
71
72const output = ({ format, isProduction }) => {
73 if (typeof isProduction !== 'boolean')
74 throw new Error('Invalid option `isProduction` at output({ ... })');
75 if (format !== 'cjs' && format !== 'esm')
76 throw new Error('Invalid option `format` at output({ ... })');
77
78 let extension =
79 format === 'esm'
80 ? settings.hasReact && !settings.hasNext
81 ? '.es.js'
82 : '.mjs'
83 : '.js';
84 if (isProduction) {
85 extension = '.min' + extension;
86 }
87
88 return {
89 entryFileNames: `[name]${extension}`,
90 chunkFileNames: chunkFileNames(extension),
91 dir: './dist',
92 exports: 'named',
93 sourcemap: true,
94 banner: chunk => (chunk.name === 'urql-next' ? '"use client"' : undefined),
95 sourcemapExcludeSources: isCI,
96 hoistTransitiveImports: false,
97 indent: false,
98 freeze: false,
99 strict: false,
100 format,
101 plugins: makeOutputPlugins({
102 isProduction,
103 extension: format === 'esm' ? '.mjs' : '.js',
104 }),
105 // NOTE: All below settings are important for cjs-module-lexer to detect the export
106 // When this changes (and terser mangles the output) this will interfere with Node.js ESM intercompatibility
107 esModule: format !== 'esm',
108 externalLiveBindings: format !== 'esm',
109 interop(id) {
110 if (format === 'esm') {
111 return 'esModule';
112 } else if (id === 'react') {
113 return 'esModule';
114 } else {
115 return 'auto';
116 }
117 },
118 generatedCode: {
119 preset: 'es5',
120 reservedNamesAsProps: false,
121 objectShorthand: false,
122 constBindings: false,
123 },
124 };
125};
126
127const commonConfig = {
128 input,
129 external: settings.isExternal,
130 onwarn() {},
131 treeshake: {
132 unknownGlobalSideEffects: false,
133 tryCatchDeoptimization: false,
134 moduleSideEffects: false,
135 },
136};
137
138export default [
139 {
140 ...commonConfig,
141 plugins,
142 output: [
143 output({ format: 'cjs', isProduction: false }),
144 output({ format: 'esm', isProduction: false }),
145 !isCI && output({ format: 'cjs', isProduction: true }),
146 !isCI && output({ format: 'esm', isProduction: true }),
147 ].filter(Boolean),
148 },
149 {
150 ...commonConfig,
151 plugins: [
152 ...makeBasePlugins(),
153 dts({
154 compilerOptions: {
155 preserveSymlinks: false,
156 },
157 }),
158 ],
159 output: {
160 minifyInternalExports: false,
161 entryFileNames: '[name].d.ts',
162 chunkFileNames: chunkFileNames('.d.ts'),
163 dir: './dist',
164 plugins: [cleanup()],
165 },
166 },
167];