Rundown of the tooling setup in this library.
There are several module systems currently in use
- ES6 Modules (Node, browsers)
- CommonJS (Node)
- UMD (browsers)
In the past, we also had AMD/RequireJS (now obsolete). By far the best one is ES modules (ESM), as it comes with
- static analysis -> tree shaking
- asyncronous module loading
- compact and terse syntax
- native browser support since 2017
- next gen runtimes (e.g. deno)
When building a library, you need to consider
- application runtime (browser, Node, native, Electron)
- distribution format (ESM, CJS, UMD) and medium (NPM, CDN)
In practice, this means that you need to accommodate different apps (SPA, SSR, PWA) and bundlers (Webpack, Parcel, Rollup).
Realistically, your users will fall into one of the following categories:
-
static website that loads the lib via
<script>
tag from a CDN -
SPA that builds static HTML/CSS/JS assets with Webpack and Babel
-
SSR that outputs isomorphic server (with critial CSS) and client builds
The ultimate goal is to provide the best dev experience. That often means
- convenient & intuitive API
- minimal footprint & runtime cost
- wide cross-browser support
- IDE type-checking & auto-completion
- useful warning messages in dev
For a React component lib that translates into
- named exports with tree shaking
- zero (or few) dependencies, small bundle size
- transpilation for specific browser targets
- TypeScript and/or Flow definitions
- prop-types definitions (stripped in prod)
To provide for different deployment targets, we'll output several builds
cjs
-> CommonJS, practically only used in Node, thus ignores browser targets and uses ESNextesm
-> ES Modules, only consumed by bundlers, only for browsers thus respects browserslist configumd
-> UMD bundle, only used in browsers, no tree shaking
Most libraries and UI kits build CJS and ESM with Babel, and UMD with rollup. Webpack is not used for libraries due to its overhead, but this might change in webpack 5.
To provide for different module formats, we'll expose these package.json
fields
-
main
-> CJS entrypoint and fallback -
module
-> ESM entrypoint -
types
(ortypings
) -> TS declaration file / entrypoint -
unpkg
-> unpkg.com entrypoint file (overwritesmain
)
Because we require CSS to be bundled, we cannot mark the package as side effect free, thus
"sideEffects": [
"*.css"
]