从本地 npm 包导入 React 组件 return 空对象
Import React component from local npm package return empty object
我正在构建我的第一个 react 组件的 npm 包。
在我用webpack构建成功后,我尝试用npm link
测试它。
已连接但组件未加载。它给了我一堆这样的错误
Uncaught Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.
Check the render method of `App`.
所以我尝试 console.log()
这个组件。它 returns 一个空 Object
.
我为此苦苦挣扎了 2 天,不知道出了什么问题。
这里是一些配置
webpack.config.js
var path = require("path");
const isDevelopment = process.env.NODE_ENV === 'development'
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
module.exports = {
mode: "production",
entry: {
index: path.join(__dirname, 'src', 'index.tsx')
},
plugins: [
new MiniCssExtractPlugin({
filename: isDevelopment ? '[name].css' : '[name].[hash].css',
chunkFilename: isDevelopment ? '[id].css' : '[id].[hash].css'
})
],
module: {
rules: [
{
test: /\.tsx?$/,
loader: 'ts-loader',
exclude: /node_modules/,
options: { allowTsInNodeModules: true }
},
{
test: /\.css$/i,
use: ["style-loader", "css-loader"],
},
{
test: /\.module\.s[ac]ss$/,
use: [
isDevelopment ? 'style-loader': MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
options: {
modules: true,
sourceMap: isDevelopment
}
},
{
loader: 'sass-loader',
options: {
sourceMap: isDevelopment
}
}
]
},
{
test: /\.s[ac]ss$/i,
exclude: /\.module.(s[ac]ss)$/,
use: [
// Creates `style` nodes from JS strings
isDevelopment ? 'style-loader': MiniCssExtractPlugin.loader,
// to generate a .d.ts module
"css-modules-typescript-loader",
// Translates CSS into CommonJS
{loader: "css-loader", options: {modules: true}},
// Compiles Sass to CSS
{loader: "sass-loader", options: {sourceMap: isDevelopment}},
],
},
]
},
resolve: {
extensions: [".ts", ".tsx", ".js", ".css", ".scss"]
},
output: {
filename: '[name].js',
path: path.resolve(__dirname, 'dist'),
},
}
tsconfig.json
{
"compilerOptions": {
"outDir": "./dist/",
"target": "es5",
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"allowJs": true,
"declaration": true,
"declarationMap": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"noFallthroughCasesInSwitch": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"removeComments": true,
"noImplicitAny": true,
"noEmit": false,
"jsx": "react-jsx",
"sourceMap": true,
"plugins": [{"name": "typescript-plugin-css-modules"}]
},
"include": [
"src"
]
}
package.json
{
"name": "react-dissolve",
"version": "1.0.0",
"description": "A color and image animated dissolve effect.",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
"files": [
"dist",
"src"
],
"scripts": {
"build": "webpack"
},
"author": "jack szeto",
"license": "MIT",
"devDependencies": {
"@babel/core": "^7.16.5",
"@babel/preset-env": "^7.16.5",
"@babel/preset-react": "^7.16.5",
"@testing-library/jest-dom": "^5.16.1",
"@testing-library/react": "^12.1.2",
"@testing-library/user-event": "^13.5.0",
"@types/color-string": "^1.5.2",
"@types/jest": "^27.0.3",
"@types/node": "^16.11.15",
"@types/node-sass": "^4.11.2",
"@types/react": "^17.0.37",
"@types/react-dom": "^17.0.11",
"color-string": "^1.9.0",
"css-loader": "^6.5.1",
"css-modules-typescript-loader": "^4.0.1",
"mini-css-extract-plugin": "^2.4.5",
"node-sass": "^7.0.1",
"rc-slider": "^9.7.5",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-p5": "^1.3.24",
"react-scripts": "5.0.0",
"sass": "^1.45.1",
"sass-loader": "^12.4.0",
"simplex-noise": "^3.0.0",
"style-loader": "^3.3.1",
"ts-loader": "^9.2.6",
"typescript": "^4.5.4",
"web-vitals": "^2.1.2",
"webpack": "^5.65.0",
"webpack-cli": "^4.9.1"
},
"peerDependencies": {
"react": "^17.0.2",
"react-p5": "^1.3.24",
"simplex-noise": "^3.0.0",
"color-string": "^1.9.0",
"rc-slider": "^9.7.5",
"sass": "^1.45.1"
},
"dependencies": {}
}
构建被放入 dist
文件夹中,似乎在 dist 中完美构建成功。
截图:
最小复制案例:
使用上面相同的配置。我创建了一个测试项目(见下面的结构)。
我 运行 npm run build
使用 webpack.
构建组件
然后npm link
把测试项目link改成一个新的ts React项目。试图导入,但它产生了同样的错误。
用例
import Test from 'npm-test';
...
<Test />
文件结构
npm-test/
dist/
node_modules/
src/
declarations.d.ts
index.tsx
style.module.scss
.babelrc
.gitgnore
.npmignore
package.json
tsconfig.json
webpack.config.js
index.tsx
import React, { CSSProperties } from 'react'
import styles from './style.module.scss';
interface TestProps {
className?: string,
style?: CSSProperties,
}
const Test = ({className, style}:TestProps) => {
return (
<div className={`${styles.test} ${className}`}
style={{...style}}
>
Test
</div>
)
}
export default Test;
出口index.d.ts
import { CSSProperties } from 'react';
interface TestProps {
className?: string;
style?: CSSProperties;
}
declare const Test: ({ className, style }: TestProps) => JSX.Element;
export default Test;
//# sourceMappingURL=index.d.ts.map
感谢阅读长文post!
我已经解决了这个问题。感谢@JaredSmith 帮助我。
我搞砸了 webpack 但最后,我决定继续使用 rollup,它更容易使用。
找到了 Rollup tutorial by Portexe,它很有帮助。
所以我把文件结构改成这样
npm-test-hellow-world/
src/
component/
hello-world.tsx
index.ts
.babelrc
.gitgnore
.npmignore
package.json
tsconfig.json
rollup.config.js
因为在 hello-world.tsx
中函数组件被默认导出
declare const HelloWorld: React.FC<HelloWorldProps>;
export default HelloWorld;
不知何故,编译器没有导出组件。所以我把它放在 src/component/
文件夹中并从 src/index.ts
中导出
export {default} from './component/hello-world';
// notice:
// export * from './component/hello-world';
// didn't work
而且有效!不太确定为什么。如果有人能解释一下,我将不胜感激。
如果您想查看更多详细信息,可以查看the GitHub repo
我正在构建我的第一个 react 组件的 npm 包。
在我用webpack构建成功后,我尝试用npm link
测试它。
已连接但组件未加载。它给了我一堆这样的错误
Uncaught Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports. Check the render method of `App`.
所以我尝试 console.log()
这个组件。它 returns 一个空 Object
.
我为此苦苦挣扎了 2 天,不知道出了什么问题。
这里是一些配置
webpack.config.js
var path = require("path");
const isDevelopment = process.env.NODE_ENV === 'development'
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
module.exports = {
mode: "production",
entry: {
index: path.join(__dirname, 'src', 'index.tsx')
},
plugins: [
new MiniCssExtractPlugin({
filename: isDevelopment ? '[name].css' : '[name].[hash].css',
chunkFilename: isDevelopment ? '[id].css' : '[id].[hash].css'
})
],
module: {
rules: [
{
test: /\.tsx?$/,
loader: 'ts-loader',
exclude: /node_modules/,
options: { allowTsInNodeModules: true }
},
{
test: /\.css$/i,
use: ["style-loader", "css-loader"],
},
{
test: /\.module\.s[ac]ss$/,
use: [
isDevelopment ? 'style-loader': MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
options: {
modules: true,
sourceMap: isDevelopment
}
},
{
loader: 'sass-loader',
options: {
sourceMap: isDevelopment
}
}
]
},
{
test: /\.s[ac]ss$/i,
exclude: /\.module.(s[ac]ss)$/,
use: [
// Creates `style` nodes from JS strings
isDevelopment ? 'style-loader': MiniCssExtractPlugin.loader,
// to generate a .d.ts module
"css-modules-typescript-loader",
// Translates CSS into CommonJS
{loader: "css-loader", options: {modules: true}},
// Compiles Sass to CSS
{loader: "sass-loader", options: {sourceMap: isDevelopment}},
],
},
]
},
resolve: {
extensions: [".ts", ".tsx", ".js", ".css", ".scss"]
},
output: {
filename: '[name].js',
path: path.resolve(__dirname, 'dist'),
},
}
tsconfig.json
{
"compilerOptions": {
"outDir": "./dist/",
"target": "es5",
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"allowJs": true,
"declaration": true,
"declarationMap": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"noFallthroughCasesInSwitch": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"removeComments": true,
"noImplicitAny": true,
"noEmit": false,
"jsx": "react-jsx",
"sourceMap": true,
"plugins": [{"name": "typescript-plugin-css-modules"}]
},
"include": [
"src"
]
}
package.json
{
"name": "react-dissolve",
"version": "1.0.0",
"description": "A color and image animated dissolve effect.",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
"files": [
"dist",
"src"
],
"scripts": {
"build": "webpack"
},
"author": "jack szeto",
"license": "MIT",
"devDependencies": {
"@babel/core": "^7.16.5",
"@babel/preset-env": "^7.16.5",
"@babel/preset-react": "^7.16.5",
"@testing-library/jest-dom": "^5.16.1",
"@testing-library/react": "^12.1.2",
"@testing-library/user-event": "^13.5.0",
"@types/color-string": "^1.5.2",
"@types/jest": "^27.0.3",
"@types/node": "^16.11.15",
"@types/node-sass": "^4.11.2",
"@types/react": "^17.0.37",
"@types/react-dom": "^17.0.11",
"color-string": "^1.9.0",
"css-loader": "^6.5.1",
"css-modules-typescript-loader": "^4.0.1",
"mini-css-extract-plugin": "^2.4.5",
"node-sass": "^7.0.1",
"rc-slider": "^9.7.5",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-p5": "^1.3.24",
"react-scripts": "5.0.0",
"sass": "^1.45.1",
"sass-loader": "^12.4.0",
"simplex-noise": "^3.0.0",
"style-loader": "^3.3.1",
"ts-loader": "^9.2.6",
"typescript": "^4.5.4",
"web-vitals": "^2.1.2",
"webpack": "^5.65.0",
"webpack-cli": "^4.9.1"
},
"peerDependencies": {
"react": "^17.0.2",
"react-p5": "^1.3.24",
"simplex-noise": "^3.0.0",
"color-string": "^1.9.0",
"rc-slider": "^9.7.5",
"sass": "^1.45.1"
},
"dependencies": {}
}
构建被放入 dist
文件夹中,似乎在 dist 中完美构建成功。
截图:
最小复制案例:
使用上面相同的配置。我创建了一个测试项目(见下面的结构)。
我 运行 npm run build
使用 webpack.
然后npm link
把测试项目link改成一个新的ts React项目。试图导入,但它产生了同样的错误。
用例
import Test from 'npm-test';
...
<Test />
文件结构
npm-test/
dist/
node_modules/
src/
declarations.d.ts
index.tsx
style.module.scss
.babelrc
.gitgnore
.npmignore
package.json
tsconfig.json
webpack.config.js
index.tsx
import React, { CSSProperties } from 'react'
import styles from './style.module.scss';
interface TestProps {
className?: string,
style?: CSSProperties,
}
const Test = ({className, style}:TestProps) => {
return (
<div className={`${styles.test} ${className}`}
style={{...style}}
>
Test
</div>
)
}
export default Test;
出口index.d.ts
import { CSSProperties } from 'react';
interface TestProps {
className?: string;
style?: CSSProperties;
}
declare const Test: ({ className, style }: TestProps) => JSX.Element;
export default Test;
//# sourceMappingURL=index.d.ts.map
感谢阅读长文post!
我已经解决了这个问题。感谢@JaredSmith 帮助我。
我搞砸了 webpack 但最后,我决定继续使用 rollup,它更容易使用。
找到了 Rollup tutorial by Portexe,它很有帮助。
所以我把文件结构改成这样
npm-test-hellow-world/
src/
component/
hello-world.tsx
index.ts
.babelrc
.gitgnore
.npmignore
package.json
tsconfig.json
rollup.config.js
因为在 hello-world.tsx
中函数组件被默认导出
declare const HelloWorld: React.FC<HelloWorldProps>;
export default HelloWorld;
不知何故,编译器没有导出组件。所以我把它放在 src/component/
文件夹中并从 src/index.ts
export {default} from './component/hello-world';
// notice:
// export * from './component/hello-world';
// didn't work
而且有效!不太确定为什么。如果有人能解释一下,我将不胜感激。
如果您想查看更多详细信息,可以查看the GitHub repo