发布TypeScript编写的React组件到NPM后导入出现undefined问题求助
Let’s break down the issues in your setup that are causing this frustrating import error, and fix them one by one.
1. Fix Webpack Loader Conflicts & Add Critical Library Configuration
Your current Webpack config uses both babel-loader and awesome-typescript-loader to process TS/TSX files—this creates compilation conflicts, and awesome-typescript-loader is no longer maintained (with limited support for Webpack 5). Additionally, your output isn’t configured to properly expose your component’s exports for NPM consumption.
Update your webpack.config.js to this:
const path = require('path'); module.exports = { mode: 'production', entry: path.join(__dirname, 'src', 'index.tsx'), target: 'web', resolve: { extensions: ['.ts', '.tsx', '.js', '.jsx', '.css'] }, module: { rules: [ { test: /\.(ts|tsx)$/, use: [ { loader: 'babel-loader', options: { presets: [ '@babel/preset-env', '@babel/preset-react', '@babel/preset-typescript' ] } } ], exclude: /node_modules/, // Use regex here instead of a string }, { test: /\.css$/i, use: ['style-loader', 'css-loader'], }, ], }, output: { filename: 'index.js', path: path.resolve(__dirname, 'dist'), library: { type: 'commonjs2' // Ensures proper CommonJS export for NPM }, clean: true // Auto-cleans dist folder to avoid old file conflicts }, externals: { // Keep React/ReactDOM as external dependencies react: 'react', 'react-dom': 'react-dom' } }
Key changes explained:
- Removed
awesome-typescript-loader—babel-loaderwith the TypeScript preset is sufficient and better supported. - Added
library.type: 'commonjs2'to ensure your component’s exports are properly exposed for NPM imports. - Added
externalsto avoid bundling React into your package (prevents version conflicts and reduces bundle size). - Fixed the
excludevalue to use a regex (the string version was matching unintended paths).
2. Tweak tsconfig.json for Correct Compilation
Your TypeScript config has a few misconfigurations that can break exports and type generation:
{ "compilerOptions": { "outDir": "./dist", "target": "es6", "module": "commonjs", "skipLibCheck": true, "allowSyntheticDefaultImports": true, "noImplicitAny": true, // Enables stricter type checking (recommended) "strictNullChecks": true, // Same as above—catches bugs early "removeComments": true, "declaration": true, "declarationMap": true, "sourceMap": true, "isolatedModules": true, "esModuleInterop": true, "jsx": "react-jsx", // React 17+ syntax, no need to import React in components "typeRoots": [ "node_modules/@types" // Removed dist/index.d.ts—this field points to type directories, not files ] }, "include": [ "./src/**/*" // Matches all files/subdirectories in src, no missed files ], "exclude": [ "node_modules", "dist" ] }
Key changes explained:
- Switched
jsxtoreact-jsx(works with React 17+ and eliminates the need forimport React from 'react'in components). - Fixed
typeRoots—it should point to directories of type definitions, not individual files. - Expanded
includetosrc/**/*to ensure all your component files are compiled. - Enabled stricter type checks to catch potential issues before publishing.
3. Validate Entry File & Export Pattern
Your entry file’s export pattern is okay, but let’s make sure it’s consistent with React conventions and user imports:
// src/index.tsx import SomeComponent from './someComponent'; // Capitalize component names per React standards export { SomeComponent };
Make sure your users import it with the matching named import:
// In user's React project import { SomeComponent } from 'myname';
If you prefer to support default imports instead, adjust your entry file:
import SomeComponent from './someComponent'; export default SomeComponent;
And confirm someComponent.tsx has a valid default export:
const SomeComponent = () => { return <div>My Component</div>; }; export default SomeComponent;
4. Update package.json for Clarity
Tweak these fields to ensure proper tooling support:
{ "main": "dist/index.js", "types": "dist/index.d.ts", // Point directly to the generated type file "module": "dist/index.js", // Supports ES module imports "scripts": { "build": "webpack --config webpack.config.js" // Mode is already set in config } }
Final Test Steps
- Run
npm run buildto generate the updateddistfolder. - Publish a new version:
npm version patch && npm publish. - In your test React project, refresh the package:
npm uninstall myname npm install myname - Import and use your component again—this should resolve the "Element type is invalid" error.
内容的提问来源于stack exchange,提问作者Kyle Mo

