Skip to content

Commit c7fec38

Browse files
committed
test: verify CJS/UMD export contract after every build
lib/cjs.ts instructs verifying the module.exports===Draggable shape with a runtime require() check, but nothing enforced it — the historical CJS dual-export contract (PR #254/#266) and the UMD global could regress invisibly and only surface when a consumer installs the package. Add scripts/verify-build.cjs: requires the built CJS and asserts root===Draggable, root===.default, and .DraggableCore present; asserts the UMD bundle exposes global ReactDraggable. Wired into the Makefile build target's recipe so it runs after build-lib + build-web on both `yarn build` and `make build`. Verified it fails on a corrupted export shape. Not build-order-coupled to the unit-test matrix.
1 parent 0ea337f commit c7fec38

2 files changed

Lines changed: 64 additions & 0 deletions

File tree

Makefile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,10 @@ lint:
1919
# tsup emits cjs + esm + dts into build/cjs (and rewrites build/cjs/cjs.js to the
2020
# legacy module.exports === Draggable shape). webpack emits the UMD global bundle.
2121
# Both depend on `clean` so the dir is reset first even under parallel make (-j).
22+
# The recipe runs after both prerequisites complete and verifies the published
23+
# CJS/UMD contracts (see scripts/verify-build.cjs).
2224
build: build-lib build-web
25+
@node scripts/verify-build.cjs
2326

2427
build-lib: clean $(BIN)
2528
$(BIN)/tsup

scripts/verify-build.cjs

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
#!/usr/bin/env node
2+
'use strict';
3+
4+
// Post-build contract verification.
5+
//
6+
// The published artifacts carry two historical public contracts that the build
7+
// toolchain (tsup for CJS/ESM, webpack for UMD) must preserve. They are easy to
8+
// break invisibly — a wrong export-interop shape or a missing global only shows
9+
// up when a consumer installs the package. This script asserts both right after
10+
// the build, so a regression fails CI instead of shipping. It is wired into the
11+
// Makefile `build` target (runs after build-lib + build-web).
12+
13+
const assert = require('node:assert/strict');
14+
const fs = require('node:fs');
15+
const path = require('node:path');
16+
17+
const root = path.resolve(__dirname, '..');
18+
19+
// ── Contract 1: CJS export shape (PR #254 / issue #266) ──────────────────────
20+
// require('react-draggable') returns the Draggable class ITSELF (not a namespace
21+
// object), and also exposes .default and .DraggableCore. All three access
22+
// patterns are part of the public API.
23+
const cjsPath = path.join(root, 'build', 'cjs', 'cjs.js');
24+
assert.ok(
25+
fs.existsSync(cjsPath),
26+
`Missing CJS build at ${cjsPath} — run \`yarn build\` first.`
27+
);
28+
29+
// eslint-disable-next-line global-require, import/no-dynamic-require
30+
const cjs = require(cjsPath);
31+
assert.equal(
32+
typeof cjs,
33+
'function',
34+
`CJS root export must be the Draggable component, got ${typeof cjs}`
35+
);
36+
assert.equal(
37+
cjs.name,
38+
'Draggable',
39+
`CJS root export should be Draggable, got "${cjs.name}"`
40+
);
41+
assert.equal(cjs, cjs.default, 'require("react-draggable") must === .default');
42+
assert.equal(
43+
typeof cjs.DraggableCore,
44+
'function',
45+
'require("react-draggable").DraggableCore must be exported'
46+
);
47+
48+
// ── Contract 2: UMD global ───────────────────────────────────────────────────
49+
// The unpkg bundle exposes the library as global `ReactDraggable`, with react /
50+
// react-dom consumed as the external globals React / ReactDOM.
51+
const umdPath = path.join(root, 'build', 'web', 'react-draggable.min.js');
52+
assert.ok(fs.existsSync(umdPath), `Missing UMD build at ${umdPath}`);
53+
const umd = fs.readFileSync(umdPath, 'utf8');
54+
assert.ok(
55+
umd.includes('ReactDraggable'),
56+
'UMD bundle must expose the global `ReactDraggable`'
57+
);
58+
59+
console.log(
60+
'✓ build contract OK: CJS module.exports===Draggable (+.default, .DraggableCore); UMD global ReactDraggable'
61+
);

0 commit comments

Comments
 (0)