Skip to content

Commit c1b7b6b

Browse files
committed
fix(pg-cloudflare): use conditional export to support bundlers that don't know about cloudflare:sockets
1 parent 411869d commit c1b7b6b

File tree

12 files changed

+882
-16
lines changed

12 files changed

+882
-16
lines changed

packages/pg-bundler-test/package.json

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
{
2+
"name": "pg-bundler-test",
3+
"version": "0.0.0",
4+
"description": "Test bundlers with pg-cloudflare, https://github.com/brianc/node-postgres/issues/3452",
5+
"license": "MIT",
6+
"private": true,
7+
"type": "module",
8+
"devDependencies": {
9+
"pg-cloudflare": "^1.2.5",
10+
"webpack": "^5.99.9",
11+
"webpack-cli": "^6.0.1",
12+
"rollup": "^4.41.1",
13+
"@rollup/plugin-node-resolve": "^16.0.1",
14+
"@rollup/plugin-commonjs": "^28.0.3",
15+
"vite": "^6.3.5"
16+
},
17+
"scripts": {
18+
"test": "yarn webpack && yarn rollup && yarn vite",
19+
"webpack": "webpack --config webpack-empty.config.js && webpack --config webpack-cloudflare.config.js",
20+
"rollup": "rollup --config rollup-empty.config.js --failAfterWarnings && rollup --config rollup-cloudflare.config.js --failAfterWarnings",
21+
"vite": "vite build --config vite-empty.config.js && vite build --config vite-cloudflare.config.js"
22+
}
23+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { defineConfig } from 'rollup'
2+
import { nodeResolve } from '@rollup/plugin-node-resolve'
3+
import commonjs from '@rollup/plugin-commonjs'
4+
5+
const config = defineConfig({
6+
input: 'src/index.js',
7+
output: {
8+
file: 'dist/rollup-cloudflare.js',
9+
format: 'es',
10+
},
11+
plugins: [nodeResolve({ exportConditions: ['import', 'cloudflare'], preferBuiltins: true }), commonjs()],
12+
external: ['cloudflare:sockets'],
13+
})
14+
15+
export default config
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { defineConfig } from 'rollup'
2+
import { nodeResolve } from '@rollup/plugin-node-resolve'
3+
import commonjs from '@rollup/plugin-commonjs'
4+
5+
const config = defineConfig({
6+
input: 'src/index.js',
7+
output: {
8+
file: 'dist/rollup-empty.js',
9+
format: 'es',
10+
},
11+
plugins: [nodeResolve(), commonjs()],
12+
})
13+
14+
export default config

packages/pg-bundler-test/src/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
import 'pg-cloudflare'
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { dirname, resolve } from 'node:path'
2+
import { fileURLToPath } from 'node:url'
3+
import { defineConfig } from 'vite'
4+
import commonjs from '@rollup/plugin-commonjs'
5+
6+
const __dirname = dirname(fileURLToPath(import.meta.url))
7+
8+
export default defineConfig({
9+
build: {
10+
emptyOutDir: false,
11+
lib: {
12+
entry: resolve(__dirname, 'src/index.js'),
13+
fileName: 'vite-cloudflare',
14+
formats: ['es'],
15+
},
16+
rollupOptions: {
17+
external: ['cloudflare:sockets'],
18+
},
19+
},
20+
resolve: {
21+
conditions: ['import', 'cloudflare'],
22+
},
23+
plugins: [commonjs()],
24+
})
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { dirname, resolve } from 'node:path'
2+
import { fileURLToPath } from 'node:url'
3+
import { defineConfig } from 'vite'
4+
5+
const __dirname = dirname(fileURLToPath(import.meta.url))
6+
7+
export default defineConfig({
8+
build: {
9+
lib: {
10+
emptyOutDir: false,
11+
entry: resolve(__dirname, 'src/index.js'),
12+
fileName: 'vite-empty',
13+
formats: ['es'],
14+
},
15+
},
16+
})
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import webpack from 'webpack'
2+
3+
export default {
4+
mode: 'production',
5+
output: {
6+
filename: 'webpack-cloudflare.js',
7+
},
8+
resolve: { conditionNames: ['import', 'cloudflare'] },
9+
plugins: [
10+
// ignore cloudflare:sockets imports
11+
new webpack.IgnorePlugin({
12+
resourceRegExp: /^cloudflare:sockets$/,
13+
}),
14+
],
15+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
export default {
2+
mode: 'production',
3+
output: {
4+
filename: 'webpack-empty.js',
5+
},
6+
}

packages/pg-cloudflare/README.md

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,43 @@
1010
npm i --save-dev pg-cloudflare
1111
```
1212

13+
The package uses conditional exports to support bundlers that don't know about
14+
`cloudflare:sockets`, so the consumer code by default imports an empty file. To
15+
enable the package, resolve to the `cloudflare` condition in your bundler's
16+
config. For example:
17+
18+
- `webpack.config.js`
19+
```js
20+
resolve: { conditionNames: [..., "cloudflare"] },
21+
plugins: [
22+
// ignore cloudflare:sockets imports
23+
new webpack.IgnorePlugin({
24+
resourceRegExp: /^cloudflare:sockets$/,
25+
}),
26+
],
27+
```
28+
- `vite.config.js`
29+
```js
30+
resolve: {
31+
conditions: [..., "cloudflare"],
32+
},
33+
build: {
34+
...,
35+
// don't try to bundle cloudflare:sockets
36+
rollupOptions: {
37+
external: [..., 'cloudflare:sockets'],
38+
},
39+
},
40+
```
41+
- `rollup.config.js`
42+
```js
43+
plugins: [..., nodeResolve({ exportConditions: [..., 'cloudflare'] })],
44+
// don't try to bundle cloudflare:sockets
45+
external: [..., 'cloudflare:sockets'],
46+
```
47+
48+
The concrete examples can be found in `packages/pg-bundler-test`.
49+
1350
## How to use conditionally, in non-Node.js environments
1451

1552
As implemented in `pg` [here](https://github.com/brianc/node-postgres/commit/07553428e9c0eacf761a5d4541a3300ff7859578#diff-34588ad868ebcb232660aba7ee6a99d1e02f4bc93f73497d2688c3f074e60533R5-R13), a typical use case might look as follows, where in a Node.js environment the `net` module is used, while in a non-Node.js environment, where `net` is unavailable, `pg-cloudflare` is used instead, providing an equivalent interface:
@@ -21,15 +58,14 @@ module.exports.getStream = function getStream(ssl = false) {
2158
return net.Socket()
2259
}
2360
const { CloudflareSocket } = require('pg-cloudflare')
24-
return new CloudflareSocket(ssl);
61+
return new CloudflareSocket(ssl)
2562
}
2663
```
2764

2865
## Node.js implementation of the Socket API proposal
2966

3067
If you're looking for a way to rely on `connect()` as the interface you use to interact with raw sockets, but need this interface to be available in a Node.js environment, [`@arrowood.dev/socket`](https://github.com/Ethan-Arrowood/socket) provides a Node.js implementation of the Socket API.
3168

32-
3369
### license
3470

3571
The MIT License (MIT)

packages/pg-cloudflare/package.json

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,11 @@
1111
},
1212
"exports": {
1313
".": {
14-
"import": "./esm/index.mjs",
15-
"require": "./dist/index.js",
16-
"default": "./dist/index.js"
14+
"cloudflare": {
15+
"import": "./esm/index.mjs",
16+
"require": "./dist/index.js"
17+
},
18+
"default": "./dist/empty.js"
1719
}
1820
},
1921
"scripts": {

packages/pg-esm-test/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
"main": "index.js",
66
"type": "module",
77
"scripts": {
8-
"test": "node --test"
8+
"test": "node --test --conditions=cloudflare"
99
},
1010
"keywords": [
1111
"postgres",

0 commit comments

Comments
 (0)