如何轻量开发TypeScript ReactJS组件并发布至npm?
我完全懂你想要轻量、不搞复杂配置的心情——毕竟很多教程把简单的React组件发布搞成了大型工程,没必要!下面就给你一套极简但完整的流程,用你说的tsc编译+react-scripts做本地开发,完全不用额外的babel/webpack配置,一步步来:
先创建项目文件夹,然后初始化npm:
mkdir my-react-ts-component cd my-react-ts-component npm init -y
按照你的需求创建目录结构,最终应该是这样:
my-react-ts-component/ ├── components/ # 存放待发布的组件源码(TypeScript/TSX) │ ├── MyComponent.tsx │ └── index.ts # 组件导出入口 ├── public/ # 本地开发测试页面 │ └── index.html ├── dist/ # tsc编译后的产物(自动生成,用于npm发布) ├── node_modules/ ├── .gitignore ├── .npmignore ├── package.json └── tsconfig.json
1. package.json 关键配置
直接替换生成的package.json内容,每个关键字段我都标了作用:
{ "name": "my-react-ts-component", # 你的组件包名(npm上要唯一,重名的话加用户名前缀,比如@your-name/xxx) "version": "1.0.0", "description": "A lightweight React TypeScript component", "main": "dist/index.js", # 编译后的CommonJS入口 "module": "dist/esm/index.js", # 编译后的ES模块入口(支持tree-shaking) "types": "dist/index.d.ts", # TypeScript类型定义文件入口 "files": [ # 指定npm发布时包含的文件/文件夹 "dist" ], "scripts": { "build": "tsc && tsc --project tsconfig.esm.json", # 同时编译CommonJS和ES模块版本 "start": "react-scripts start", # 启动本地开发服务器(用public里的测试页) "test": "react-scripts test", "eject": "react-scripts eject" # 不用管,react-scripts自带的,一般不需要 eject }, "peerDependencies": { # 声明依赖的React版本(避免用户项目重复打包React) "react": "^18.0.0", "react-dom": "^18.0.0" }, "devDependencies": { # 开发依赖,用户安装你的包时不会自动安装 "@types/react": "^18.0.0", "@types/react-dom": "^18.0.0", "react": "^18.0.0", "react-dom": "^18.0.0", "react-scripts": "5.0.1", "typescript": "^5.0.0" }, "browserslist": { # react-scripts需要的浏览器兼容配置 "production": [ ">0.2%", "not dead", "not op_mini all" ], "development": [ "last 1 chrome version", "last 1 firefox version", "last 1 safari version" ] } }
2. tsconfig.json (CommonJS编译配置)
创建tsconfig.json,用于编译成CommonJS格式:
{ "compilerOptions": { "target": "ES6", "module": "CommonJS", "lib": ["ES6", "DOM"], "jsx": "react-jsx", # React 17+的JSX转换,不用手动引入React "declaration": true, # 自动生成类型定义文件(.d.ts) "outDir": "./dist", # 编译产物输出到dist文件夹 "strict": true, "esModuleInterop": true, "skipLibCheck": true, "forceConsistentCasingInFileNames": true, "moduleResolution": "Node", "resolveJsonModule": true, "isolatedModules": true }, "include": ["components/**/*"], # 只编译components里的文件 "exclude": ["node_modules", "dist"] }
3. tsconfig.esm.json (ES模块编译配置)
创建这个文件生成ES模块版本,支持tree-shaking:
{ "extends": "./tsconfig.json", "compilerOptions": { "module": "ES6", "outDir": "./dist/esm" } }
4. .gitignore
添加以下内容,忽略不需要提交到Git的文件:
node_modules/ dist/ .env .env.local .env.development.local .env.test.local .env.production.local npm-debug.log* yarn-debug.log* yarn-error.log*
5. .npmignore
因为我们已经在package.json里用files指定了只发布dist,这个文件其实可选,但如果想更保险,也可以写:
node_modules/ components/ public/ .gitignore tsconfig.json tsconfig.esm.json
1. 编写组件示例
在components/MyComponent.tsx里写一个简单的组件:
import React from 'react'; interface MyComponentProps { title: string; onClick?: () => void; } const MyComponent: React.FC<MyComponentProps> = ({ title, onClick }) => { return ( <button onClick={onClick} style={{ padding: '8px 16px', fontSize: '16px' }}> {title} </button> ); }; export default MyComponent;
然后在components/index.ts统一导出组件:
export { default as MyComponent } from './MyComponent';
2. 本地测试页面
在public/index.html里添加测试页面(react-scripts会自动加载这个页面):
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8" /> <title>My Component Test</title> </head> <body> <div id="root"></div> <script type="module"> import React from 'react'; import ReactDOM from 'react-dom/client'; import { MyComponent } from '../components'; const root = ReactDOM.createRoot(document.getElementById('root')); root.render( <React.StrictMode> <MyComponent title="Click Me!" onClick={() => alert('Hello from My Component!')} /> </React.StrictMode> ); </script> </body> </html>
3. 启动本地开发服务器
运行命令:
npm start
浏览器会自动打开http://localhost:3000,你就能看到你的组件在运行了!
1. 编译组件
先运行编译命令,生成dist文件夹:
npm run build
这时候dist里会有CommonJS版本、ES模块版本,以及对应的类型定义文件。
2. 登录npm
如果你还没登录npm,先运行:
npm login
按照提示输入你的npm账号、密码、邮箱。
3. 发布组件
运行发布命令:
npm publish
如果你的包名是带用户名前缀的私有格式(比如@your-name/xxx),需要加--access public参数发布成公开包:
npm publish --access public
4. 后续更新
如果要更新组件,只需要:
- 修改组件代码
- 升级
package.json里的version字段(遵循语义化版本:小改升patch,功能改升minor,大改升major) - 重新编译:
npm run build - 重新发布:
npm publish
- peerDependencies:一定要声明React和ReactDOM的版本,这样用户安装你的包时,会用他们项目里已有的React版本,不会重复打包,避免版本冲突。
- 类型定义:
declaration: true会自动生成.d.ts文件,用户用TypeScript时能获得完整的类型提示。 - ES模块:生成ES模块版本能让用户的打包工具(比如webpack、Vite)做tree-shaking,减小最终打包体积。
内容的提问来源于stack exchange,提问作者Lukas Bunat

