Skip to content

Commit b31454f

Browse files
authored
chore(build): better packaging of libraries (#652)
1 parent 269a021 commit b31454f

8 files changed

Lines changed: 832 additions & 1196 deletions

File tree

‎.changeset/lovely-apes-sort.md‎

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
---
2+
'@ts-rest/react-query': patch
3+
'@ts-rest/core': patch
4+
'@ts-rest/express': patch
5+
'@ts-rest/fastify': patch
6+
'@ts-rest/nest': patch
7+
'@ts-rest/next': patch
8+
'@ts-rest/open-api': patch
9+
'@ts-rest/serverless': patch
10+
'@ts-rest/solid-query': patch
11+
'@ts-rest/vue-query': patch
12+
---
13+
14+
All ts-rest libraries are now packaged in a better way to be compatible with as many bundlers as possible. The @tanstack/react-query `No QueryClient set` error should also occur much less now.

‎libs/ts-rest/react-query-v5/rollup.config.js‎

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,7 @@ logger.info = new Proxy(logger.info, {
2121
packageJson['peerDependencies']['@tanstack/react-query'] =
2222
'^4.0.0 || ^5.0.0';
2323

24-
packageJson['exports']['./v5'] = Object.fromEntries(
25-
Object.entries(packageJson['exports']['.']).map(([key, value]) => {
26-
return [key, value.replace('index', 'v5')];
27-
}),
28-
);
29-
3024
fs.writeJsonSync(path.join(v4BuildDir, 'package.json'), packageJson, {
31-
flag: 'w+',
32-
replacer: null,
3325
spaces: 2,
3426
});
3527

‎libs/ts-rest/react-query/project.json‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@
3030
"rollupConfig": "tools/scripts/rollup.config.js",
3131
"generateExportsField": true,
3232
"additionalEntryPoints": [
33-
"libs/ts-rest/react-query/src/tanstack.ts"
33+
"libs/ts-rest/react-query/src/tanstack.ts",
34+
"libs/ts-rest/react-query/src/v5.ts"
3435
]
3536
}
3637
},

‎libs/ts-rest/react-query/src/v5.ts‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
// placeholder for v5 exports
2+
export {};

‎package.json‎

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@
101101
"devDependencies": {
102102
"@babel/core": "^7.14.5",
103103
"@babel/preset-react": "^7.14.5",
104+
"@betit/rollup-plugin-rename-extensions": "0.1.0",
104105
"@cloudflare/workers-types": "^4.20240405.0",
105106
"@docusaurus/module-type-aliases": "2.4.1",
106107
"@nestjs/schematics": "10.0.1",
@@ -174,7 +175,6 @@
174175
"prisma": "^4.5.0",
175176
"qs": "^6.11.0",
176177
"rollup": "^3.10.1",
177-
"rollup-plugin-cleanup": "^3.2.1",
178178
"rollup-plugin-preserve-directives": "^0.4.0",
179179
"sass": "1.55.0",
180180
"sort-package-json": "^2.10.0",
@@ -198,5 +198,10 @@
198198
},
199199
"volta": {
200200
"node": "20.16.0"
201+
},
202+
"pnpm": {
203+
"patchedDependencies": {
204+
"@betit/rollup-plugin-rename-extensions@0.1.0": "patches/@betit__rollup-plugin-rename-extensions@0.1.0.patch"
205+
}
201206
}
202207
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
diff --git a/dist/index.js b/dist/index.js
2+
index 4fc489eb311f53f38264b6659f0bdab4992047d9..48605c84395312a388f75085dfc734718a99bcc4 100644
3+
--- a/dist/index.js
4+
+++ b/dist/index.js
5+
@@ -58,9 +58,11 @@ function getExportSource(node) {
6+
return node.source;
7+
}
8+
function rewrite(input, extensions) {
9+
- var extension = path_1.extname(input);
10+
- if (extensions.hasOwnProperty(extension)) {
11+
- return "" + input.slice(0, -extension.length) + extensions[extension];
12+
+ const extensionMappings = Object.entries(extensions);
13+
+ for (const [originalExtension, replacementExtension] of extensionMappings) {
14+
+ if (input.endsWith(originalExtension)) {
15+
+ return "" + input.slice(0, -originalExtension.length) + replacementExtension;
16+
+ }
17+
}
18+
return false;
19+
}

‎pnpm-lock.yaml‎

Lines changed: 680 additions & 1131 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎tools/scripts/rollup.config.js‎

Lines changed: 109 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,105 @@
1+
const fs = require('fs-extra');
2+
const glob = require('glob');
3+
const path = require('path');
4+
const { logger } = require('@nx/devkit');
5+
const { default: renameExtensions } = require('@betit/rollup-plugin-rename-extensions');
6+
7+
let sortPackageJson;
8+
let builtCompleteFunction;
9+
10+
logger.info = new Proxy(logger.info, {
11+
apply(target, thisArg, args) {
12+
target.apply(thisArg, args);
13+
14+
// nx prints this message after rollup finishes and nx itself has completed building the resulting package.json
15+
if (args[0].includes('Done in')) {
16+
builtCompleteFunction();
17+
}
18+
},
19+
});
20+
21+
(async () => {
22+
sortPackageJson = (await import('sort-package-json')).default;
23+
})();
24+
125
/** @type {import("rollup").RollupOptionsFunction} */
226
const rollupConfig = (config) => {
27+
const outputDir = config.output.dir;
28+
29+
builtCompleteFunction = () => {
30+
// STEP 1: Add @ts-rest/core to peerDependencies of all libs, except core itself
31+
// Can't let changesets handle this for us because it sees peerDependencies updates as a breaking change
32+
const packageJsonPath = path.join(outputDir, 'package.json');
33+
const packageJsonObject = fs.readJsonSync(packageJsonPath);
34+
const splitVersion = packageJsonObject.version.split('.');
35+
splitVersion.splice(-1, 1, '0');
36+
37+
const peerVersion = packageJsonObject.version.includes('-')
38+
? packageJsonObject.version // pre-release needs to use exact version
39+
: `~${splitVersion.join('.')}`;
40+
41+
packageJsonObject.peerDependencies = {
42+
...packageJsonObject.peerDependencies,
43+
'@ts-rest/core': peerVersion,
44+
};
45+
46+
const exportsAndTypesVersions =
47+
Object.entries(packageJsonObject.exports)
48+
.reduce((acc, [key, value]) => {
49+
if (typeof value === 'string') {
50+
acc.exports.push([key, value]);
51+
return acc;
52+
}
53+
54+
const name = value.module.replace(/\.esm\.js$/, '');
55+
56+
acc.exports.push([
57+
key,
58+
{
59+
import: `${name}.esm.mjs`,
60+
require: value.default,
61+
types: `${name}.cjs.d.ts`
62+
}
63+
]);
64+
65+
if (key !== '.') {
66+
acc.typesVersions.push([
67+
key.replace(/^\.\//, ''),
68+
[`${name}.cjs.d.ts`]
69+
]);
70+
}
71+
72+
return acc;
73+
}, { exports: [], typesVersions: [] });
74+
75+
if (exportsAndTypesVersions.exports.length > 0) {
76+
packageJsonObject.exports = Object.fromEntries(exportsAndTypesVersions.exports);
77+
}
78+
79+
if (exportsAndTypesVersions.typesVersions.length > 0) {
80+
packageJsonObject.typesVersions = { '*': Object.fromEntries(exportsAndTypesVersions.typesVersions) };
81+
}
82+
83+
if (packageJsonObject.module) {
84+
packageJsonObject.module = packageJsonObject.module.replace(/\.esm\.js$/, '.esm.mjs');
85+
}
86+
87+
fs.writeJsonSync(packageJsonPath, sortPackageJson(packageJsonObject), { spaces: 2 });
88+
89+
logger.info(
90+
'\nAdded @ts-rest/core to peer dependencies',
91+
);
92+
93+
glob
94+
.sync([
95+
path.join(outputDir, '**/*.cjs.default.js'),
96+
path.join(outputDir, '**/*.cjs.mjs')
97+
])
98+
.forEach((file) => {
99+
fs.rmSync(file);
100+
});
101+
};
102+
3103
return {
4104
...config,
5105
external: (source, importer, isResolved) => {
@@ -8,62 +108,16 @@ const rollupConfig = (config) => {
8108
}
9109
return config.external(source, importer, isResolved);
10110
},
11-
plugins: [...config.plugins]
111+
plugins: [
112+
...config.plugins,
113+
renameExtensions({
114+
include: [`**/*.ts`, `**/*.tsx`],
115+
mappings: {
116+
'.esm.js': '.esm.mjs'
117+
}
118+
}),
119+
]
12120
}
13121
}
14122

15123
module.exports = rollupConfig;
16-
17-
(async() => {
18-
const fs = require('fs-extra');
19-
const path = require('path');
20-
const glob = require('glob');
21-
const {default: sortPackageJson} = await import('sort-package-json');
22-
const { logger } = require('@nx/devkit');
23-
24-
const targetProject = process.env.NX_TASK_TARGET_PROJECT;
25-
const libsProjectJson = glob.sync('libs/ts-rest/*/project.json', {
26-
ignore: [
27-
'libs/ts-rest/core/project.json',
28-
'libs/ts-rest/react-query-v5/project.json',
29-
],
30-
});
31-
32-
let targetBuildPath;
33-
for (const projectJsonPath of libsProjectJson) {
34-
const projectJson = fs.readJsonSync(projectJsonPath);
35-
if (projectJson.name === targetProject) {
36-
targetBuildPath = projectJson.targets.build.options.outputPath;
37-
break;
38-
}
39-
}
40-
41-
if (targetBuildPath) {
42-
logger.info = new Proxy(logger.info, {
43-
apply(target, thisArg, args) {
44-
target.apply(thisArg, args);
45-
46-
if (args[0].includes('Done in')) {
47-
const packageJsonPath = path.join(targetBuildPath, 'package.json');
48-
const packageJsonObject = fs.readJsonSync(packageJsonPath);
49-
const splitVersion = packageJsonObject.version.split('.');
50-
splitVersion.splice(-1, 1, '0');
51-
52-
const peerVersion = packageJsonObject.version.includes('-')
53-
? packageJsonObject.version // pre-release needs to use exact version
54-
: `~${splitVersion.join('.')}`;
55-
56-
packageJsonObject.peerDependencies = {
57-
...packageJsonObject.peerDependencies,
58-
'@ts-rest/core': peerVersion,
59-
};
60-
fs.writeJsonSync(packageJsonPath, sortPackageJson(packageJsonObject), { spaces: 2 });
61-
62-
logger.info(
63-
'\nAdded @ts-rest/core to peer dependencies',
64-
);
65-
}
66-
},
67-
});
68-
}
69-
})();

0 commit comments

Comments
 (0)