xiaohongshu
xiaohongshu
library-bundler
Configure build systems, optimize bundle size, manage exports for ESM/CJS/UMD, and publish packages to NPM with proper versioning
Full skill instructions
Expert skill for building, bundling, and publishing component libraries to NPM. Specializes in modern build tools (tsup, Vite, Rollup), bundle optimization, multi-format exports, and package publishing workflows.
Analyze Project Structure
Choose Build Tool
Configure package.json
Tree-Shaking Setup
Bundle Size Analysis
Code Splitting
Version Management
Pre-publish Checks
Publish to NPM
// tsup.config.ts
import { defineConfig } from 'tsup'
export default defineConfig({
entry: ['src/index.ts'],
format: ['cjs', 'esm'],
dts: true,
splitting: false,
sourcemap: true,
clean: true,
treeshake: true,
minify: true,
external: ['react', 'react-dom'],
esbuildOptions(options) {
options.banner = {
js: '"use client"', // For React Server Components
}
},
})
// vite.config.ts
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import { resolve } from 'path'
import dts from 'vite-plugin-dts'
export default defineConfig({
plugins: [
react(),
dts({
insertTypesEntry: true,
}),
],
build: {
lib: {
entry: resolve(__dirname, 'src/index.ts'),
name: 'MyLibrary',
formats: ['es', 'cjs', 'umd'],
fileName: (format) => `my-library.${format}.js`,
},
rollupOptions: {
external: ['react', 'react-dom'],
output: {
globals: {
react: 'React',
'react-dom': 'ReactDOM',
},
},
},
sourcemap: true,
minify: 'esbuild',
},
})
// rollup.config.mjs
import resolve from '@rollup/plugin-node-resolve'
import commonjs from '@rollup/plugin-commonjs'
import typescript from '@rollup/plugin-typescript'
import { terser } from 'rollup-plugin-terser'
import peerDepsExternal from 'rollup-plugin-peer-deps-external'
import postcss from 'rollup-plugin-postcss'
export default {
input: 'src/index.ts',
output: [
{
file: 'dist/index.cjs.js',
format: 'cjs',
sourcemap: true,
},
{
file: 'dist/index.esm.js',
format: 'esm',
sourcemap: true,
},
{
file: 'dist/index.umd.js',
format: 'umd',
name: 'MyLibrary',
sourcemap: true,
globals: {
react: 'React',
'react-dom': 'ReactDOM',
},
},
],
plugins: [
peerDepsExternal(),
resolve(),
commonjs(),
typescript({
tsconfig: './tsconfig.json',
declaration: true,
declarationDir: 'dist',
}),
postcss({
extensions: ['.css'],
minimize: true,
inject: false,
extract: 'styles.css',
}),
terser(),
],
external: ['react', 'react-dom'],
}
{
"name": "@myorg/ui-library",
"version": "1.0.0",
"description": "Modern React component library",
"type": "module",
"main": "./dist/index.cjs",
"module": "./dist/index.js",
"types": "./dist/index.d.ts",
"exports": {
".": {
"types": "./dist/index.d.ts",
"import": "./dist/index.js",
"require": "./dist/index.cjs"
},
"./button": {
"types": "./dist/button.d.ts",
"import": "./dist/button.js",
"require": "./dist/button.cjs"
},
"./package.json": "./package.json"
},
"files": [
"dist",
"README.md",
"LICENSE"
],
"sideEffects": false,
"scripts": {
"build": "tsup",
"dev": "tsup --watch",
"prepublishOnly": "npm run build && npm test",
"publish:dry": "npm publish --dry-run"
},
"peerDependencies": {
"react": "^18.0.0",
"react-dom": "^18.0.0"
},
"devDependencies": {
"@types/react": "^18.2.0",
"react": "^18.2.0",
"tsup": "^8.0.0",
"typescript": "^5.3.0"
},
"publishConfig": {
"access": "public"
},
"repository": {
"type": "git",
"url": "https://github.com/myorg/ui-library"
},
"keywords": [
"react",
"components",
"ui",
"library"
],
"author": "Your Name",
"license": "MIT"
}
{
"name": "my-library",
"version": "1.0.0",
"type": "module",
"exports": {
".": {
"import": {
"types": "./dist/index.d.ts",
"default": "./dist/index.js"
},
"require": {
"types": "./dist/index.d.cts",
"default": "./dist/index.cjs"
}
}
},
"main": "./dist/index.cjs",
"module": "./dist/index.js",
"types": "./dist/index.d.ts"
}
{
"name": "@myorg/ui-components",
"private": false,
"version": "1.0.0",
"exports": {
"./button": {
"types": "./dist/button.d.ts",
"import": "./dist/button.js"
},
"./input": {
"types": "./dist/input.d.ts",
"import": "./dist/input.js"
}
},
"typesVersions": {
"*": {
"button": ["./dist/button.d.ts"],
"input": ["./dist/input.d.ts"]
}
}
}
{
"compilerOptions": {
"target": "ES2020",
"module": "ESNext",
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"jsx": "react-jsx",
"declaration": true,
"declarationMap": true,
"sourceMap": true,
"outDir": "./dist",
"rootDir": "./src",
"removeComments": true,
"strict": true,
"moduleResolution": "bundler",
"allowImportingTsExtensions": false,
"resolveJsonModule": true,
"isolatedModules": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"noUncheckedIndexedAccess": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true
},
"include": ["src"],
"exclude": ["node_modules", "dist", "**/*.test.ts", "**/*.test.tsx"]
}
// package.json
{
"sideEffects": false
}
// Or specify files with side effects
{
"sideEffects": ["*.css", "*.scss"]
}
// Use named exports (tree-shakeable)
export { Button } from './Button'
export { Input } from './Input'
// Avoid default exports for libraries
// ❌ export default { Button, Input }
// tsup.config.ts
export default defineConfig({
entry: {
index: 'src/index.ts',
button: 'src/components/Button/index.ts',
input: 'src/components/Input/index.ts',
},
format: ['esm', 'cjs'],
splitting: true, // Enable code splitting
dts: true,
})
# Install bundle analyzer
npm install -D rollup-plugin-visualizer
# Add to rollup config
import { visualizer } from 'rollup-plugin-visualizer'
plugins: [
visualizer({
filename: './dist/stats.html',
open: true,
}),
]
// Don't bundle these (keep as peerDependencies)
external: [
'react',
'react-dom',
'framer-motion',
'@radix-ui/react-*',
]
// Regex pattern for dynamic externals
external: (id) => {
return /^react/.test(id) || /^@radix-ui/.test(id)
}
// esbuild (fastest)
minify: true
// Terser (best compression)
import { terser } from 'rollup-plugin-terser'
plugins: [
terser({
compress: {
drop_console: true,
drop_debugger: true,
},
format: {
comments: false,
},
}),
]
# Patch: Bug fixes (1.0.0 → 1.0.1)
npm version patch
# Minor: New features, backwards compatible (1.0.0 → 1.1.0)
npm version minor
# Major: Breaking changes (1.0.0 → 2.0.0)
npm version major
# Pre-release
npm version prerelease --preid=beta
# 1.0.0 → 1.0.1-beta.0
# Install conventional-changelog
npm install -D conventional-changelog-cli
# Generate changelog
npx conventional-changelog -p angular -i CHANGELOG.md -s
{
"scripts": {
"prepublishOnly": "npm run lint && npm test && npm run build",
"prepack": "cp README.md LICENSE dist/"
}
}
# Dry run (test without publishing)
npm publish --dry-run
# Publish to npm
npm publish
# Publish scoped package
npm publish --access public
# Publish with tag
npm publish --tag beta
# Publish specific folder
cd dist && npm publish
# Publish with provenance (requires GitHub Actions)
npm publish --provenance
# .github/workflows/publish.yml
name: Publish Package
on:
push:
tags:
- 'v*'
jobs:
publish:
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: '18'
registry-url: 'https://registry.npmjs.org'
- run: npm ci
- run: npm test
- run: npm run build
- run: npm publish --provenance --access public
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
{
"scripts": {
"dev": "tsup --watch",
"build": "tsup",
"build:analyze": "tsup && rollup-plugin-visualizer",
"type-check": "tsc --noEmit",
"clean": "rm -rf dist"
}
}
{
"scripts": {
"ci:build": "npm run clean && npm run build",
"ci:test": "npm run type-check && npm test",
"ci:publish": "npm run ci:test && npm run ci:build && npm publish"
}
}
# Create tarball
npm pack
# Install in test project
cd ../test-project
npm install ../my-library/my-library-1.0.0.tgz
# In library
npm link
# In consuming project
npm link my-library
// test.mjs
import * as lib from 'my-library'
console.log(Object.keys(lib))
// test.cjs
const lib = require('my-library')
console.log(Object.keys(lib))
// turbo.json
{
"pipeline": {
"build": {
"dependsOn": ["^build"],
"outputs": ["dist/**"]
},
"dev": {
"cache": false,
"persistent": true
}
}
}
// packages/ui/package.json
{
"name": "@myorg/ui",
"version": "1.0.0",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
"exports": {
".": {
"import": "./dist/index.js",
"types": "./dist/index.d.ts"
}
}
}
// apps/docs/package.json
{
"dependencies": {
"@myorg/ui": "workspace:*"
}
}
Dual Package Hazard
// Ensure consistent resolution
// Use exports field properly
{
"exports": {
".": {
"import": "./dist/index.js",
"require": "./dist/index.cjs"
}
}
}
Missing Type Declarations
// Check tsconfig.json
{
"compilerOptions": {
"declaration": true,
"declarationMap": true
}
}
// Check package.json
{
"types": "./dist/index.d.ts",
"exports": {
".": {
"types": "./dist/index.d.ts"
}
}
}
Large Bundle Size
# Analyze bundle
npm run build:analyze
# Check for duplicate dependencies
npm dedupe
# Externalize peer dependencies
external: ['react', 'react-dom']
CJS/ESM Compatibility
// Use conditional exports
{
"exports": {
".": {
"import": "./dist/index.js",
"require": "./dist/index.cjs"
}
}
}
// Add "type": "module" to package.json
// Name CJS files with .cjs extension
Activate this skill when you need to:
When configuring builds, provide:
Always optimize for modern standards (ESM-first) while maintaining backwards compatibility where needed.
xiaohongshu
technical spec
product ux expert
database patterns
Conduct multi-agent task orchestration and workflow coordination.
Initialize project with Conductor artifacts (product definition,
Expert in web animations, transitions, and motion design using Framer Motion and CSS
Creates Mermaid and ASCII diagrams for flowcharts, architecture, ERDs, state machines, mindmaps, and more. Use when user mentions diagram, flowchart, mermaid, ASCII diagram, text diagram, terminal diagram, visualize, C4, mindmap, architecture diagram, sequence diagram, ERD, or needs visual docume...
PostgreSQL bindings for H3 hexagonal grid system. Use when working with H3 cells in Postgres, including spatial indexing, geometry/geography integration, and raster analysis.
Context-Driven Development skill for projects using Conductor. Use this skill when you detect a `conductor/` directory in the project, when working on tasks defined in a `plan.md` file, or when the user asks about tracks, specs, or plans. Automatically applies TDD workflow, tracks task completion...
Display project status, active tracks, and next actions
Official Stakpak application containerization standard operating procedure, a step-by-step guidline to properly dockerize applications. This is a rule book curated by the Stakpak Team.
Generate, edit, and beat-sync AI video with leading models in one workspace.
The world's fastest calendar for remote work
Transform Your Design with AI Designer by ImgCreator.ai
Revolutionizing Video Production with AI-Powered Creativity
Extend an image past the frame and let AI fill the new aspect ratio.
Discover your celebrity doppelgänger with StarByFace!
ChainClarity explains 700+ crypto whitepapers in plain English, with layered summaries, comparisons, research tools, alerts, and a $4.99 Pro plan.
Opus.ai: Revolutionize Your Web Experience