Skip to content

Commit cc3a291

Browse files
committed
feat: migrate build system to Rolldown and improve TypeScript configuration
- Replace Rollup + ESBuild with Rolldown for faster, simpler builds - Remove redundant type declarations, leverage TypeScript inference - Modernize TypeScript config (ES2020 target, bundler resolution) - Simplify build scripts and configuration files - Add ES module support with "type": "module" - Reduce build dependencies from 7 packages to just Rolldown Build performance: ~90ms with Rolldown (native TypeScript support) All 70 tests passing successfully
1 parent f8dfaaf commit cc3a291

File tree

9 files changed

+272
-726
lines changed

9 files changed

+272
-726
lines changed
File renamed without changes.

package.json

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -40,15 +40,14 @@
4040
"main": "lib/index.js",
4141
"module": "lib/index.es.js",
4242
"types": "lib/index.d.ts",
43+
"type": "module",
4344
"files": [
4445
"lib",
4546
"resources"
4647
],
4748
"scripts": {
48-
"build": "yarn build:main && yarn build:serverless",
49-
"build:main": "rm -rf lib && rollup -c rollup.config.cjs && yarn build:types",
50-
"build:serverless": "rollup -c rollup.config.serverless.cjs",
51-
"build:types": "tsc --declaration --emitDeclarationOnly --outDir lib --declarationMap",
49+
"build": "rm -rf lib && rolldown -c && yarn build:types",
50+
"build:types": "tsc --emitDeclarationOnly",
5251
"check": "biome check .",
5352
"format": "biome format --write .",
5453
"lint": "biome lint .",
@@ -58,9 +57,8 @@
5857
"prepublishOnly": "yarn build",
5958
"release": "semantic-release",
6059
"release:dry": "semantic-release --dry-run",
61-
"test": "jest",
62-
"watch": "rm -rf lib && rollup -cw rollup.config.cjs",
63-
"watch:serverless": "rollup -cw rollup.config.serverless.cjs"
60+
"test": "NODE_OPTIONS='--experimental-vm-modules' jest",
61+
"watch": "rm -rf lib && rolldown -c --watch"
6462
},
6563
"config": {
6664
"commitizen": {
@@ -83,21 +81,15 @@
8381
},
8482
"devDependencies": {
8583
"@biomejs/biome": "^2.2.2",
86-
"@rollup/plugin-commonjs": "^28.0.6",
87-
"@rollup/plugin-json": "^6.1.0",
88-
"@rollup/plugin-node-resolve": "^16.0.1",
89-
"@rollup/plugin-terser": "^0.4.4",
9084
"@types/bson": "^4.2.4",
9185
"@types/jest": "^30.0.0",
9286
"@types/node": "^24.3.0",
9387
"@types/shelljs": "^0.8.17",
94-
"esbuild": "^0.25.9",
9588
"husky": "^9.1.7",
9689
"jest": "^30.1.3",
9790
"lint-staged": "^16.1.6",
9891
"prettier": "^3.6.2",
99-
"rollup": "^4.50.0",
100-
"rollup-plugin-esbuild": "^6.2.1",
92+
"rolldown": "^1.0.0-beta.34",
10193
"shelljs": "^0.10.0",
10294
"ts-jest": "^29.4.1",
10395
"tslib": "^2.8.1",

rolldown.config.js

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
import { readFileSync } from 'node:fs'
2+
import { defineConfig } from 'rolldown'
3+
4+
const pkg = JSON.parse(readFileSync('./package.json', 'utf-8'))
5+
6+
// External dependencies - don't bundle these
7+
const external = [
8+
...Object.keys(pkg.dependencies || {}),
9+
...Object.keys(pkg.peerDependencies || {}),
10+
]
11+
12+
// Main library build (with external dependencies)
13+
export default defineConfig([
14+
// Main build - CommonJS and ESM
15+
{
16+
input: 'src/index.ts',
17+
output: [
18+
{
19+
file: 'lib/index.js',
20+
format: 'cjs',
21+
},
22+
{
23+
file: 'lib/index.es.js',
24+
format: 'es',
25+
},
26+
],
27+
external,
28+
resolve: {
29+
extensions: ['.ts', '.js', '.json'],
30+
},
31+
},
32+
// Serverless build - Bundle everything
33+
{
34+
input: 'src/index.serverless.ts',
35+
output: [
36+
{
37+
file: 'lib/serverless.cjs.js',
38+
format: 'cjs',
39+
exports: 'named',
40+
},
41+
{
42+
file: 'lib/serverless.esm.js',
43+
format: 'es',
44+
},
45+
{
46+
file: 'lib/serverless.umd.js',
47+
format: 'umd',
48+
name: 'PhoneNumberValidator',
49+
exports: 'named',
50+
},
51+
],
52+
resolve: {
53+
extensions: ['.ts', '.js', '.json'],
54+
},
55+
},
56+
// Serverless minified builds
57+
{
58+
input: 'src/index.serverless.ts',
59+
output: [
60+
{
61+
file: 'lib/serverless.esm.min.js',
62+
format: 'es',
63+
minify: true,
64+
},
65+
{
66+
file: 'lib/serverless.umd.min.js',
67+
format: 'umd',
68+
name: 'PhoneNumberValidator',
69+
exports: 'named',
70+
minify: true,
71+
},
72+
],
73+
resolve: {
74+
extensions: ['.ts', '.js', '.json'],
75+
},
76+
},
77+
])

rollup.config.cjs

Lines changed: 0 additions & 32 deletions
This file was deleted.

rollup.config.serverless.cjs

Lines changed: 0 additions & 96 deletions
This file was deleted.

src/index.serverless.ts

Lines changed: 16 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { type LRU, lru } from 'tiny-lru'
66
import type { CarrierLocale, GeocoderLocale } from './locales'
77

88
const DEFAULT_CACHE_SIZE = 100
9-
let codeDataCache: LRU<Document> = lru<Document>(DEFAULT_CACHE_SIZE)
9+
let codeDataCache = lru<Document>(DEFAULT_CACHE_SIZE)
1010

1111
// Resource loader interface - platforms must implement this
1212
export interface ResourceLoader {
@@ -21,7 +21,7 @@ export function setResourceLoader(loader: ResourceLoader) {
2121
resourceLoader = loader
2222
}
2323

24-
async function getCodeAsync(dataPath: string, nationalNumber: string): Promise<string | null> {
24+
async function getCodeAsync(dataPath: string, nationalNumber: string) {
2525
if (!dataPath || !nationalNumber || !resourceLoader) {
2626
return null
2727
}
@@ -52,7 +52,7 @@ async function getCodeAsync(dataPath: string, nationalNumber: string): Promise<s
5252
return null
5353
}
5454

55-
function getCodeSync(dataPath: string, nationalNumber: string): string | null {
55+
function getCodeSync(dataPath: string, nationalNumber: string) {
5656
if (!dataPath || !nationalNumber || !resourceLoader || !resourceLoader.loadResourceSync) {
5757
return null
5858
}
@@ -87,8 +87,8 @@ async function getLocalizedDataAsync(
8787
resourceType: 'geocodes' | 'carrier',
8888
phonenumber: PhoneNumber | undefined,
8989
locale: string,
90-
fallbackLocale: string = 'en'
91-
): Promise<string | null> {
90+
fallbackLocale = 'en'
91+
) {
9292
if (!phonenumber) {
9393
return null
9494
}
@@ -119,8 +119,8 @@ function getLocalizedDataSync(
119119
resourceType: 'geocodes' | 'carrier',
120120
phonenumber: PhoneNumber | undefined,
121121
locale: string,
122-
fallbackLocale: string = 'en'
123-
): string | null {
122+
fallbackLocale = 'en'
123+
) {
124124
if (!phonenumber) {
125125
return null
126126
}
@@ -151,20 +151,18 @@ function getLocalizedDataSync(
151151
export async function geocoderAsync(
152152
phonenumber: PhoneNumber | undefined,
153153
locale: GeocoderLocale = 'en'
154-
): Promise<string | null> {
154+
) {
155155
return getLocalizedDataAsync('geocodes', phonenumber, locale, 'en')
156156
}
157157

158158
export async function carrierAsync(
159159
phonenumber: PhoneNumber | undefined,
160160
locale: CarrierLocale = 'en'
161-
): Promise<string | null> {
161+
) {
162162
return getLocalizedDataAsync('carrier', phonenumber, locale, 'en')
163163
}
164164

165-
export async function timezonesAsync(
166-
phonenumber: PhoneNumber | undefined
167-
): Promise<string[] | null> {
165+
export async function timezonesAsync(phonenumber: PhoneNumber | undefined) {
168166
if (!phonenumber || !phonenumber.number) {
169167
return null
170168
}
@@ -186,21 +184,15 @@ export async function timezonesAsync(
186184
}
187185

188186
// Sync versions (requires sync resource loader)
189-
export function geocoder(
190-
phonenumber: PhoneNumber | undefined,
191-
locale: GeocoderLocale = 'en'
192-
): string | null {
187+
export function geocoder(phonenumber: PhoneNumber | undefined, locale: GeocoderLocale = 'en') {
193188
return getLocalizedDataSync('geocodes', phonenumber, locale, 'en')
194189
}
195190

196-
export function carrier(
197-
phonenumber: PhoneNumber | undefined,
198-
locale: CarrierLocale = 'en'
199-
): string | null {
191+
export function carrier(phonenumber: PhoneNumber | undefined, locale: CarrierLocale = 'en') {
200192
return getLocalizedDataSync('carrier', phonenumber, locale, 'en')
201193
}
202194

203-
export function timezones(phonenumber: PhoneNumber | undefined): string[] | null {
195+
export function timezones(phonenumber: PhoneNumber | undefined) {
204196
if (!phonenumber || !phonenumber.number) {
205197
return null
206198
}
@@ -221,15 +213,15 @@ export function timezones(phonenumber: PhoneNumber | undefined): string[] | null
221213
return null
222214
}
223215

224-
export function clearCache(): void {
216+
export function clearCache() {
225217
codeDataCache.clear()
226218
}
227219

228-
export function getCacheSize(): number {
220+
export function getCacheSize() {
229221
return codeDataCache.size
230222
}
231223

232-
export function setCacheSize(size: number): void {
224+
export function setCacheSize(size: number) {
233225
const oldCache = codeDataCache
234226
codeDataCache = lru<Document>(size)
235227

0 commit comments

Comments
 (0)