diff --git a/package.json b/package.json index 2a8420f..a459b87 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ ], "scripts": { "postinstall": "manypkg check", - "prebuild": "yarn workspace @kablamo/kerosene run build", + "prebuild": "yarn workspace @kablamo/rollup-plugin-resolve-externals run build && yarn workspace @kablamo/kerosene run build", "build": "yarn workspaces run build", "clean": "yarn workspaces run clean", "lint": "eslint .", diff --git a/packages/kerosene-test/package.json b/packages/kerosene-test/package.json index 37f770f..904c64e 100644 --- a/packages/kerosene-test/package.json +++ b/packages/kerosene-test/package.json @@ -1,6 +1,6 @@ { "name": "@kablamo/kerosene-test", - "version": "0.0.14", + "version": "0.0.15", "repository": "https://github.com/KablamoOSS/kerosene/tree/master/packages/kerosene-test", "bugs": { "url": "https://github.com/KablamoOSS/kerosene/issues" @@ -46,7 +46,7 @@ "utils" ], "dependencies": { - "@kablamo/kerosene": "^0.0.38", + "@kablamo/kerosene": "^0.0.39", "@types/lodash": "^4.14.202", "@types/sinon": "^17.0.2", "lodash": "^4.17.21", diff --git a/packages/kerosene-ui/package.json b/packages/kerosene-ui/package.json index c95bebc..68e0061 100644 --- a/packages/kerosene-ui/package.json +++ b/packages/kerosene-ui/package.json @@ -1,6 +1,6 @@ { "name": "@kablamo/kerosene-ui", - "version": "0.0.38", + "version": "0.0.39", "repository": "https://github.com/KablamoOSS/kerosene/tree/master/packages/kerosene-ui", "bugs": { "url": "https://github.com/KablamoOSS/kerosene/issues" @@ -35,14 +35,15 @@ "node": ">=18.12.0" }, "dependencies": { - "@kablamo/kerosene": "^0.0.38", + "@kablamo/kerosene": "^0.0.39", "@types/lodash": "^4.14.202", "esbuild-register": "^3.5.0", "lodash": "^4.17.21", "use-sync-external-store": "^1.2.0" }, "devDependencies": { - "@kablamo/kerosene-test": "^0.0.14", + "@kablamo/kerosene-test": "^0.0.15", + "@kablamo/rollup-plugin-resolve-externals": "^0.0.1", "@optimize-lodash/rollup-plugin": "^4.0.4", "@sinonjs/fake-timers": "^11.2.2", "@tanstack/react-query": "^5.12.2", diff --git a/packages/kerosene-ui/rollup-config.ts b/packages/kerosene-ui/rollup-config.ts index ce20189..32b31f5 100644 --- a/packages/kerosene-ui/rollup-config.ts +++ b/packages/kerosene-ui/rollup-config.ts @@ -1,6 +1,7 @@ +import resolveExternals from "@kablamo/rollup-plugin-resolve-externals"; import { optimizeLodashImports } from "@optimize-lodash/rollup-plugin"; import path from "path"; -import type { RollupOptions, ExternalOption } from "rollup"; +import type { RollupOptions } from "rollup"; import esbuild from "rollup-plugin-esbuild"; import packageJson from "./package.json"; @@ -11,20 +12,20 @@ const input = [ const outputDir = path.dirname(packageJson.main); -const externals = [ - packageJson.dependencies, - packageJson.peerDependencies, -].flatMap(Object.keys); - -const external: ExternalOption = (source) => - externals.includes(source) || - externals.some((mod) => source.startsWith(`${mod}/`)); - -const plugins = [esbuild(), optimizeLodashImports()]; +const plugins = [ + resolveExternals({ + externals: [packageJson.dependencies, packageJson.peerDependencies].flatMap( + Object.keys, + ), + }), + esbuild(), + optimizeLodashImports(), +]; export default [ { input, + makeAbsoluteExternalsRelative: true, output: [ { entryFileNames: "[name].cjs", @@ -38,11 +39,11 @@ export default [ entryFileNames: "[name].mjs", dir: outputDir, format: "es", + interop: "auto", preserveModules: true, sourcemap: true, }, ], - external, plugins, }, ] satisfies RollupOptions[]; diff --git a/packages/kerosene-ui/src/index.ts b/packages/kerosene-ui/src/index.ts index 1ec4bc5..0858cc7 100644 --- a/packages/kerosene-ui/src/index.ts +++ b/packages/kerosene-ui/src/index.ts @@ -29,6 +29,11 @@ export { default as usePrevious } from "./hooks/usePrevious"; export { default as useRafThrottle } from "./hooks/useRafThrottle"; export { default as useRect } from "./hooks/useRect"; export { default as useStableIdentity } from "./hooks/useStableIdentity"; +export { + default as useTimeZone, + TimeZoneProvider, + type TimeZoneProviderProps, +} from "./hooks/useTimeZone"; export { default as useUpdatingRef } from "./hooks/useUpdatingRef"; export { default as ShowWhen } from "./components/ShowWhen"; diff --git a/packages/kerosene/package.json b/packages/kerosene/package.json index 8bbe34f..7881a75 100644 --- a/packages/kerosene/package.json +++ b/packages/kerosene/package.json @@ -1,6 +1,6 @@ { "name": "@kablamo/kerosene", - "version": "0.0.38", + "version": "0.0.39", "repository": "https://github.com/KablamoOSS/kerosene/tree/master/packages/kerosene", "bugs": { "url": "https://github.com/KablamoOSS/kerosene/issues" @@ -37,6 +37,7 @@ "lodash": "^4.17.21" }, "devDependencies": { + "@kablamo/rollup-plugin-resolve-externals": "^0.0.1", "@optimize-lodash/rollup-plugin": "^4.0.4", "@sinonjs/fake-timers": "^11.2.2", "@types/seed-random": "^2.2.4", diff --git a/packages/kerosene/rollup-config.ts b/packages/kerosene/rollup-config.ts index 4d61409..5b360fc 100644 --- a/packages/kerosene/rollup-config.ts +++ b/packages/kerosene/rollup-config.ts @@ -1,6 +1,7 @@ +import resolveExternals from "@kablamo/rollup-plugin-resolve-externals"; import { optimizeLodashImports } from "@optimize-lodash/rollup-plugin"; import path from "path"; -import type { ExternalOption, RollupOptions } from "rollup"; +import type { RollupOptions } from "rollup"; import esbuild from "rollup-plugin-esbuild"; import packageJson from "./package.json"; @@ -8,16 +9,15 @@ const input = path.join(__dirname, "src", "index.ts"); const outputDir = path.dirname(packageJson.main); -const externals = [ - packageJson.dependencies, - packageJson.peerDependencies, -].flatMap(Object.keys); - -const external: ExternalOption = (source) => - externals.includes(source) || - externals.some((mod) => source.startsWith(`${mod}/`)); - -const plugins = [esbuild(), optimizeLodashImports()]; +const plugins = [ + resolveExternals({ + externals: [packageJson.dependencies, packageJson.peerDependencies].flatMap( + Object.keys, + ), + }), + esbuild(), + optimizeLodashImports(), +]; export default [ { @@ -35,11 +35,11 @@ export default [ entryFileNames: "[name].mjs", dir: outputDir, format: "es", + interop: "auto", preserveModules: true, sourcemap: true, }, ], - external, plugins, }, ] satisfies RollupOptions[]; diff --git a/packages/rollup-plugin-resolve-externals/.npmignore b/packages/rollup-plugin-resolve-externals/.npmignore new file mode 100644 index 0000000..e69de29 diff --git a/packages/rollup-plugin-resolve-externals/package.json b/packages/rollup-plugin-resolve-externals/package.json new file mode 100644 index 0000000..0dd796b --- /dev/null +++ b/packages/rollup-plugin-resolve-externals/package.json @@ -0,0 +1,54 @@ +{ + "name": "@kablamo/rollup-plugin-resolve-externals", + "version": "0.0.1", + "repository": "https://github.com/KablamoOSS/kerosene/tree/master/packages/rollup-plugin-resolve-externals", + "bugs": { + "url": "https://github.com/KablamoOSS/kerosene/issues" + }, + "contributors": [ + { + "name": "Kablamo", + "url": "https://www.kablamo.com.au" + }, + { + "name": "Nathan Hardy", + "email": "nathan.hardy@kablamo.com.au", + "url": "https://nhardy.id.au" + } + ], + "homepage": "https://github.com/KablamoOSS/kerosene", + "private": false, + "license": "MIT", + "main": "./dist/index.js", + "types": "./dist/index.d.ts", + "directories": { + "doc": "readme.md" + }, + "publishConfig": { + "access": "public" + }, + "engines": { + "node": ">=18.12.0" + }, + "keywords": [ + "kablamo", + "kerosene", + "rollup", + "plugin", + "externals", + "resolve" + ], + "dependencies": { + "lodash": "^4.17.21" + }, + "devDependencies": { + "rollup": "^4.5.1" + }, + "peerDependencies": { + "rollup": "^4.5.1" + }, + "scripts": { + "build": "tsc", + "clean": "rimraf .dist" + } +} diff --git a/packages/rollup-plugin-resolve-externals/src/index.ts b/packages/rollup-plugin-resolve-externals/src/index.ts new file mode 100644 index 0000000..2253db2 --- /dev/null +++ b/packages/rollup-plugin-resolve-externals/src/index.ts @@ -0,0 +1,79 @@ +import { escapeRegExp } from "lodash"; +import path from "path"; +import type { ExternalOption, Plugin } from "rollup"; + +export interface ResolveExternalsPluginOptions { + /** + * List of external modules + */ + externals: readonly string[]; + /** + * `paths` used by `require.resolve(name, { paths })` to resolve dependencies + */ + paths?: string[]; +} + +export default function resolveExternals({ + externals, + paths = require.main?.paths, +}: ResolveExternalsPluginOptions): Plugin { + const external = ((source) => + externals.includes(source) || + externals.some((mod) => + source.startsWith(`${mod}/`), + )) satisfies ExternalOption; + const deepExternalRegex = new RegExp( + `^(${externals.map((e) => escapeRegExp(e)).join("|")})/(.+)$`, + ); + + return { + name: "@kablamo/rollup-plugin-resolve-externals", + + resolveId(source) { + // Ignore non-externals + if (!external) return null; + + // Match deep imports from a package + const match = deepExternalRegex.exec(source); + if (match) { + const [, mod, importPath] = match; + // eslint-disable-next-line import/no-dynamic-require, global-require, @typescript-eslint/no-var-requires + const pkgJson = require(`${mod}/package.json`) as Record< + string, + unknown + >; + + // If package exports are not defined, we need to resolve the path so that CommonJS files + // can be resolved properly from `.mjs` files + if (!pkgJson.exports) { + // Resolve the module to a path on disk + const resolvedPath = require.resolve(`${mod}/${importPath}`, { + paths, + }); + // Rewrite to a relative path + const rewritten = `${mod}/${path + .relative( + path.dirname( + require.resolve(`${mod}/package.json`, { + paths, + }), + ), + resolvedPath, + ) + // Handle win32 path separators + .split(path.sep) + .join("/")}`; + return { + id: rewritten, + external: true, + }; + } + } + + return { + id: source, + external: true, + }; + }, + }; +} diff --git a/packages/rollup-plugin-resolve-externals/tsconfig.json b/packages/rollup-plugin-resolve-externals/tsconfig.json new file mode 100644 index 0000000..355b9b4 --- /dev/null +++ b/packages/rollup-plugin-resolve-externals/tsconfig.json @@ -0,0 +1,11 @@ +{ + "extends": "../../tsconfig", + "compilerOptions": { + "outDir": "dist", + "noEmit": false, + "allowJs": false, + "declaration": true, + "declarationDir": "dist" + }, + "include": ["src/**/*.ts"] +}