Skip to content

Commit 45b3275

Browse files
authored
build: Migrate from tsdx to Rollup for modern build tooling (#973)
1 parent afe3aab commit 45b3275

File tree

12 files changed

+27963
-37494
lines changed

12 files changed

+27963
-37494
lines changed

.eslintrc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
"lib/**",
2121
"postcss.config.js",
2222
"scripts/**",
23-
"tsdx.config.js",
23+
"rollup.config.mjs",
2424
"webpack.config.*"
2525
],
2626
"rules": {

.npmignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,4 @@ src/
1818
.eslintrc
1919
.prettierignore
2020
.prettierrc
21-
tsdx.config.js
21+
rollup.config.js

lint-staged.config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
module.exports = {
22
'./**/*.{js,jsx,ts,tsx,md,mdx,json,css,scss,less}': ['prettier --write'],
3-
'*.{js,jsx,ts,tsx': ['tsdx lint'],
3+
'./**/*.{js,jsx,ts,tsx}': ['npx eslint --format codeframe --fix'],
44
}

package-lock.json

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

package.json

Lines changed: 13 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44
"version": "28.7.2",
55
"repository": "https://github.com/Doist/reactist",
66
"homepage": "https://github.com/Doist/reactist#readme",
7+
"bugs": {
8+
"url": "https://github.com/Doist/reactist/issues"
9+
},
710
"author": {
811
"name": "Henning Muszynski",
912
"email": "henning@doist.com",
@@ -32,9 +35,9 @@
3235
"postinstall": "patch-package",
3336
"setup": "npm install && npm run validate",
3437
"validate": "npm run lint && npm run type-check && npm run test",
35-
"start": "tsdx watch --onSuccess \"./scripts/organize-styles.sh\"",
38+
"start": "ON_SUCCESS=\"./scripts/organize-styles.sh\" rollup -c --watch --no-watch.clearScreen",
3639
"prestart:yalc": "npm run clean && yalc publish",
37-
"start:yalc": "tsdx watch --tsconfig tsconfig.dist.json --onSuccess=\"npm run start:yalc:success\"",
40+
"start:yalc": "ON_SUCCESS=\"npm run start:yalc:success\" rollup -c --watch --no-watch.clearScreen",
3841
"poststart:yalc": "yalc installations clean",
3942
"start:yalc:success": "./scripts/organize-styles.sh && yalc push --sig",
4043
"build": "scripts/build.sh",
@@ -71,7 +74,10 @@
7174
"@doist/prettier-config": "^3.0.5",
7275
"@doist/tsconfig": "^1.0.0",
7376
"@geometricpanda/storybook-addon-badges": "^0.2.2",
74-
"@rollup/plugin-typescript": "11.1.6",
77+
"@rollup/plugin-commonjs": "28.0.9",
78+
"@rollup/plugin-node-resolve": "16.0.3",
79+
"@rollup/plugin-terser": "0.4.4",
80+
"@rollup/plugin-typescript": "12.3.0",
7581
"@storybook/addon-actions": "^6.5.3",
7682
"@storybook/addon-controls": "^6.5.3",
7783
"@storybook/addon-docs": "^6.5.3",
@@ -103,7 +109,7 @@
103109
"chromatic": "^6.11.4",
104110
"classnames": "^2.2.5",
105111
"css-loader": "^4.2.2",
106-
"cssnano": "^4.1.10",
112+
"cssnano": "^5.0.16",
107113
"eslint": "^8.16.0",
108114
"eslint-config-prettier": "^8.5.0",
109115
"eslint-formatter-codeframe": "^7.32.1",
@@ -134,15 +140,13 @@
134140
"react-svg-loader": "^3.0.3",
135141
"react-test-renderer": "^17.0.2",
136142
"rimraf": "^3.0.2",
137-
"rollup": "2.79.1",
138-
"rollup-plugin-postcss": "3.1.8",
139-
"rollup-plugin-styles": "^3.14.1",
143+
"rollup": "2.79.2",
144+
"rollup-plugin-styles": "4.0.0",
140145
"style-loader": "^0.23.1",
141146
"svg-url-loader": "^6.0.0",
142147
"ts-loader": "^8.0.2",
143-
"tsdx": "0.14.1",
144148
"tslib": "^2.0.0",
145-
"typescript": "^4.6.4",
149+
"typescript": "^4.8.3",
146150
"webpack": "^4.43.0"
147151
},
148152
"dependencies": {
@@ -154,13 +158,5 @@
154158
"react-keyed-flatten-children": "^1.3.0",
155159
"react-markdown": "^5.0.3",
156160
"use-callback-ref": "^1.3.0"
157-
},
158-
"overrides": {
159-
"typescript": "^4.6.4",
160-
"@rollup/plugin-typescript": "11.1.6",
161-
"rollup": "2.79.1"
162-
},
163-
"bugs": {
164-
"url": "https://github.com/Doist/reactist/issues"
165161
}
166162
}
Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
diff --git a/node_modules/rollup-plugin-styles/dist/index.js b/node_modules/rollup-plugin-styles/dist/index.js
2-
index 29d5266..8f89c09 100644
2+
index b6a7426..901e861 100644
33
--- a/node_modules/rollup-plugin-styles/dist/index.js
44
+++ b/node_modules/rollup-plugin-styles/dist/index.js
5-
@@ -756,7 +756,7 @@ var generateScopedNameDefault = ((placeholder = "[name]_[local]__[hash:8]") => (
5+
@@ -772,7 +772,7 @@ var generateScopedNameDefault = ((placeholder = "[name]_[local]__[hash:8]") => (
66
name,
77
base
8-
} = path__default['default'].parse(file);
8+
} = path__default["default"].parse(file);
99
- const hash = hasher(`${base}:${css}`);
1010
+ const hash = hasher(`${base}:${css}:${local}`);
1111
const match = hashRe.exec(placeholder);
1212
const hashLen = match && Number.parseInt(match[1]);
13-
return pluginutils.makeLegalIdentifier(placeholder.replace("[dir]", path__default['default'].basename(dir)).replace("[name]", name).replace("[local]", local).replace(hashRe, hashLen ? hash.slice(0, hashLen) : hash));
14-
@@ -899,7 +899,7 @@ const loader = {
13+
return pluginutils.makeLegalIdentifier(placeholder.replace("[dir]", path__default["default"].basename(dir)).replace("[name]", name).replace("[local]", local).replace(hashRe, hashLen ? hash.slice(0, hashLen) : hash));
14+
@@ -915,7 +915,7 @@ const loader$4 = {
1515
const config = await loadConfig(this.id, options.config);
1616
const plugins = [];
1717
const autoModules = ensureAutoModules(options.autoModules, this.id);
@@ -21,10 +21,10 @@ index 29d5266..8f89c09 100644
2121
const postcssOpts = { ...config.options,
2222
...options.postcss,
2323
diff --git a/node_modules/rollup-plugin-styles/dist/index.mjs b/node_modules/rollup-plugin-styles/dist/index.mjs
24-
index 703a54f..aaf3657 100644
24+
index 793150d..2376996 100644
2525
--- a/node_modules/rollup-plugin-styles/dist/index.mjs
2626
+++ b/node_modules/rollup-plugin-styles/dist/index.mjs
27-
@@ -740,7 +740,7 @@ var generateScopedNameDefault = ((placeholder = "[name]_[local]__[hash:8]") => (
27+
@@ -756,7 +756,7 @@ var generateScopedNameDefault = ((placeholder = "[name]_[local]__[hash:8]") => (
2828
name,
2929
base
3030
} = path.parse(file);
@@ -33,7 +33,7 @@ index 703a54f..aaf3657 100644
3333
const match = hashRe.exec(placeholder);
3434
const hashLen = match && Number.parseInt(match[1]);
3535
return makeLegalIdentifier(placeholder.replace("[dir]", path.basename(dir)).replace("[name]", name).replace("[local]", local).replace(hashRe, hashLen ? hash.slice(0, hashLen) : hash));
36-
@@ -883,7 +883,7 @@ const loader = {
36+
@@ -899,7 +899,7 @@ const loader$4 = {
3737
const config = await loadConfig(this.id, options.config);
3838
const plugins = [];
3939
const autoModules = ensureAutoModules(options.autoModules, this.id);

rollup.config.mjs

Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
import typescript from '@rollup/plugin-typescript'
2+
import resolve from '@rollup/plugin-node-resolve'
3+
import commonjs from '@rollup/plugin-commonjs'
4+
import styles from 'rollup-plugin-styles'
5+
import terser from '@rollup/plugin-terser'
6+
import { exec } from 'child_process'
7+
8+
const isWatchMode = process.env.ROLLUP_WATCH === 'true'
9+
const onSuccessCallback = process.env.ON_SUCCESS
10+
11+
const external = [
12+
'react',
13+
'react-dom',
14+
'classnames',
15+
'prop-types',
16+
'@ariakit/react',
17+
'aria-hidden',
18+
'dayjs',
19+
'dayjs/plugin/localizedFormat',
20+
'react-focus-lock',
21+
'react-keyed-flatten-children',
22+
'use-callback-ref',
23+
'tslib',
24+
]
25+
26+
const basePlugins = [resolve(), commonjs()]
27+
28+
const baseStylesConfig = {
29+
autoModules: /\.module\.css$/,
30+
modules: {
31+
mode: 'local',
32+
generateScopedName: '[hash:8]',
33+
},
34+
mode: 'extract',
35+
url: { inline: true },
36+
}
37+
38+
const baseTypescriptConfig = {
39+
tsconfig: './tsconfig.dist.json',
40+
}
41+
42+
// Plugin to run a command after successful build
43+
function onSuccess(command) {
44+
return {
45+
name: 'on-success',
46+
closeBundle() {
47+
if (command) {
48+
exec(command, (error, stdout, stderr) => {
49+
if (error) {
50+
console.error(`Error executing command: ${error}`)
51+
return
52+
}
53+
if (stdout) console.log(stdout)
54+
if (stderr) console.error(stderr)
55+
})
56+
}
57+
},
58+
}
59+
}
60+
61+
// Build configurations for es/, lib/, and dist/ folders
62+
function createConfig({
63+
format,
64+
outputDir,
65+
outputFile,
66+
preserveModules,
67+
withDeclarations,
68+
withMinification,
69+
onSuccessCommand,
70+
}) {
71+
return {
72+
input: 'src/index.ts',
73+
output: {
74+
...(outputFile ? { file: outputFile } : { dir: outputDir }),
75+
format,
76+
sourcemap: true,
77+
...(preserveModules && {
78+
preserveModules: true,
79+
preserveModulesRoot: 'src',
80+
assetFileNames: '[name][extname]',
81+
}),
82+
...(format === 'cjs' && { exports: 'named' }),
83+
},
84+
external,
85+
plugins: [
86+
...basePlugins,
87+
styles({
88+
...baseStylesConfig,
89+
...(withMinification && { minimize: true }),
90+
}),
91+
typescript({
92+
...baseTypescriptConfig,
93+
compilerOptions: {
94+
outDir: outputDir || 'dist',
95+
...(withDeclarations
96+
? { declaration: true, declarationMap: false }
97+
: { declaration: false, declarationMap: false, declarationDir: undefined }),
98+
},
99+
}),
100+
...(withMinification ? [terser()] : []),
101+
...(onSuccessCommand ? [onSuccess(onSuccessCommand)] : []),
102+
],
103+
}
104+
}
105+
106+
// ESM unbundled build (es/ folder)
107+
const es = createConfig({
108+
format: 'esm',
109+
outputDir: 'es',
110+
preserveModules: true,
111+
})
112+
113+
// CJS unbundled build with TypeScript declarations (lib/ folder)
114+
const lib = createConfig({
115+
format: 'cjs',
116+
outputDir: 'lib',
117+
preserveModules: true,
118+
withDeclarations: true,
119+
...(isWatchMode && onSuccessCallback && { onSuccessCommand: onSuccessCallback }),
120+
})
121+
122+
// Generate dist/index.js proxy file
123+
const distIndex = {
124+
input: 'src/index.ts',
125+
external: () => true,
126+
output: {
127+
file: 'dist/index.js',
128+
format: 'cjs',
129+
},
130+
plugins: [
131+
{
132+
name: 'write-dist-index',
133+
generateBundle(_, bundle) {
134+
for (const fileName in bundle) {
135+
delete bundle[fileName]
136+
}
137+
138+
this.emitFile({
139+
type: 'asset',
140+
fileName: 'index.js',
141+
source: `'use strict'
142+
143+
if (process.env.NODE_ENV === 'production') {
144+
module.exports = require('./reactist.cjs.production.min.js')
145+
} else {
146+
module.exports = require('./reactist.cjs.development.js')
147+
}
148+
`,
149+
})
150+
},
151+
},
152+
],
153+
}
154+
155+
// Bundled CJS development build (dist/ folder)
156+
const distDev = createConfig({
157+
format: 'cjs',
158+
outputFile: 'dist/reactist.cjs.development.js',
159+
})
160+
161+
// Bundled CJS production build - minified (dist/ folder)
162+
const distProd = createConfig({
163+
format: 'cjs',
164+
outputFile: 'dist/reactist.cjs.production.min.js',
165+
withMinification: true,
166+
})
167+
168+
export default isWatchMode ? [es, lib, distIndex] : [es, lib, distDev, distProd]

scripts/build.sh

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,8 @@
33
# Clean & Build
44
# We use a separate tsconfig that excludes mocks and tests
55
npm run clean
6-
tsdx build --tsconfig tsconfig.dist.json # The non-bundled ESM build (in es/) and CJS build (in lib/)
7-
BUNDLED_OUTPUT=true tsdx build --tsconfig tsconfig.dist.json --target browser --format cjs # The bundled UMD build (in dist/)
8-
rimraf dist/assets dist/index.js
6+
npx rollup -c # Builds all 4 configs: es/, lib/, and dist/ (development + production)
7+
rimraf dist/assets
98

109
# Reorganize Styles
1110
# We delete duplicate styles in dist/ & lib/

scripts/organize-styles.sh

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,16 @@
11
#!/usr/bin/env sh
22

3-
mv es/index.css es/reactist.css
3+
# Rename the main index CSS file to reactist.css
4+
[ -f es/index.css ] && mv es/index.css es/reactist.css
5+
6+
# Create styles directory
47
mkdir -p styles
5-
find es -iname '*.css' -type f -exec mv {} styles/ \;
6-
find dist -iname '*.css' -type f -exec rm {} \;
7-
find lib -iname '*.css' -type f -exec rm {} \;
8+
9+
# Move all CSS files from es/ to styles/
10+
[ -d es ] && find es -iname '*.css' -type f -exec mv {} styles/ \;
11+
12+
# Delete CSS files from dist/ and lib/ (we only keep them in styles/)
13+
[ -d dist ] && find dist -iname '*.css' -type f -exec rm {} \;
14+
[ -d lib ] && find lib -iname '*.css' -type f -exec rm {} \;
15+
16+
printf "\n💅 Styles reorganization finished successfully.\n\n"

src/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
/// <reference types="../types/css" />
2+
/// <reference types="../types/less" />
3+
14
import './styles/design-tokens.css'
25

36
// layout components

0 commit comments

Comments
 (0)