Webpack + Typscript 库导入在 React 项目中未定义

Webpack + Typscript library import is undefined in React project

我正在尝试使用 Typescript、Webpack 和 Babel 创建一个 React 库,但是我 运行 遇到了问题。如果我构建然后将库导入 React 项目,那么我的导入是 'undefined'(请参阅以下错误)。我认为这是因为在 bundle.js 中没有 module.exports 代表我的 class 的变量只有 __webpack_exports__["default"] = (ExampleComponent); (但是我不确定这是什么在实践中确实如此,所以我可能是错的。)

我特别遇到了这个错误:

Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.

我尝试过的:

版本:

代码:

React 项目:

import React from "react";
import { ExampleComponent } from "test-lib";

// This is always undefined
console.log(ExampleComponent);

function App() {
    return <ExampleComponent />;
}

export default App;

图书馆项目:

index.ts:

import ExampleComponent from './ExampleComponent'

export { ExampleComponent }

ExampleComponent.tsx

import * as React from 'react'
import './ExampleComponent.css'

interface Props {
    text: string
}

// prettier-ignore
const ExampleComponent: React.FC<Props> = ({ text }) => (
    <h1 className="example-text">{text}</h1>
)

export default ExampleComponent

库配置:

tsconfig.json:

{
    "compilerOptions": {
        "outDir": "dist",
        "module": "esnext",
        "lib": ["dom", "esnext"],
        "moduleResolution": "node",
        "jsx": "react",
        "sourceMap": true,
        "declaration": true,
        "esModuleInterop": true,
        "noImplicitReturns": true,
        "noImplicitThis": true,
        "noImplicitAny": true,
        "strictNullChecks": true,
        "suppressImplicitAnyIndexErrors": true,
        "noUnusedLocals": true,
        "noUnusedParameters": true,
        "allowSyntheticDefaultImports": true,
        "target": "es5",
        "allowJs": true,
        "skipLibCheck": true,
        "strict": true,
        "forceConsistentCasingInFileNames": true,
        "resolveJsonModule": true
    },
    "include": ["src", "tests"],
    "exclude": ["node_modules", "dist", "example"]
}

.babelrc:

{
    "presets": [
        [
            "@babel/preset-env",
            {
                "debug": true,
                "useBuiltIns": "usage",
                "corejs": 3
            }
        ],
        "@babel/preset-react",
        "@babel/preset-typescript"
    ]
}

Webpack 配置:

const path = require('path')
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin')

module.exports = {
    entry: {
        bundle: './src/index.ts',
    },

    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: '[name].js',
    },

    resolve: {
        extensions: ['.tsx', '.ts', '.js', '.json'],
    },

    devtool: 'source-map',

    module: {
        rules: [
            {
                test: /\.tsx?$/,
                exclude: /node_modules/,
                use: [{ loader: 'babel-loader' }, { loader: 'ts-loader' }],
            },

            {
                test: /\.css$/,
                loaders: ['style-loader', 'css-loader'],
            },

            {
                test: /\.(gif|png|jpe?g|svg)$/,
                use: [
                    'file-loader',
                    {
                        loader: 'image-webpack-loader',
                        options: {
                            disable: true,
                        },
                    },
                ],
            },

            {
                test: /\.js$/,
                enforce: 'pre',
                loader: 'source-map-loader',
            },
        ],
    },

    plugins: [new ForkTsCheckerWebpackPlugin()],
}

如果您想在此处查看完整代码,请从 link 到 Github Repo

根据 Scovy 的评论,我可以使用 output.libraryTarget and output.globalObject 输出选项来实现此功能。

现在我在 webpack.base.config.js 中的输出条目如下所示:

output: {
    path: path.resolve(__dirname, 'dist'),
    filename: '[name].js',
    libraryTarget: 'umd',
    globalObject: 'this',
},

更新:

上述更改并没有在 100% 的时间内正常工作,所以我找到了一个名为 esm-webpack-plugin 的库,它最终完美地工作了。

所以webpack配置中输出入口的最终代码是:

output: {
    path: path.resolve(__dirname, 'dist'),
    filename: '[name].js',
    library: 'LIB',
    libraryTarget: 'var',
},

我还添加了插件:

plugins: [new ForkTsCheckerWebpackPlugin(), new EsmWebpackPlugin()],