HOC в веб-пакете выбрасывает необработанное отклонение (TypeError): объект (...) не является функцией - PullRequest
0 голосов
/ 22 октября 2018

Некоторый контекст

  1. У меня есть HOC с названием withCtx.Он предоставляет контекст для базового Comps
  2. У меня есть рабочее решение в конце этого поста, но это слишком много дополнительного кода только для HOC.

Проблема

Я испытываю эту проблему только в моей библиотеке npm, созданной с помощью Webpack 4. В приложении отлично работает точно такой же экспорт HOC.

Необработанный отказ (TypeError): объект (...) не является функцией

Мои догадки:

Webpackкажется, что функции передаются в HOC, в то время как приложение передает объекты (компоненты React).

Так что я предполагаю, что в Webpack отсутствует плагин, или я должен добавить условный оператор в HOC, чтобырендеринг переданного компонента правильным способом.

Вот HOC:

export const withCtx = contextTypes => Component => {
    /* The context is passed as props. This way the component is
   completely decoupled from the context API.
  */

    console.log('typeof ----------', Component);
    const ContextConsumer = (props, context) => <Component {...props} {...context} />;
    ContextConsumer.contextTypes = contextTypes;

    return ContextConsumer;
};

Это НЕ работает с веб-пакетом

export default withCtx({
    nextRouter: PropTypes.object,
    currentRoute: PropTypes.object,
})(Toolbar);

Это НЕ работает с веб-пакетом(почему не выше?)

const Toolbar_Extended = props => {
    const TB = withCtx({
        nextRouter: PropTypes.object,
        currentRoute: PropTypes.object,
    })(Toolbar);
    return <TB {...props} />;
};
export default Toolbar_Extended;

И это тоже работает ...

export const withCtx = contextTypes => Component => {
    /* The context is passed as props. This way the component is
   completely decoupled from the context API.
  */

    let ContextConsumer = (props, context) => <Component {...props} {...context} />;

    ContextConsumer.contextTypes = contextTypes;

    if (typeof Component == 'function') {
        return props => {
            return <ContextConsumer {...props} />;
        };
    }

    return ContextConsumer;
};

// then
export default props => withCtx({
        nextRouter: PropTypes.object,
        currentRoute: PropTypes.object,
    })(Toolbar)(props);

Может ли кто-нибудь просветить меня в этом?

Почему я передаю PropTypes?Потому что я так воспринимаю контекст.Но что бы там ни было, я получаю сообщение об ошибке.С или без PropTypes ...

// Providing HOCs you can easily solve the code fragility problem of the React context. You’ll only need to update one place if the API changes. Let’s illustrate a possible implementation:

const provideContext = 
  (childContextTypes, getChildContext) => (Component) => {
    class ContextProvider extends React.Component {
      static childContextTypes = childContextTypes;
      getChildContext = () => getChildContext(this.props);

      render() {
        return <Component {...this.props} />;
      }
    }
    return ContextProvider;
  };

const consumeContext = (contextTypes) => (Component) => {
  /* The context is passed as props. This way the component is
   completely decoupled from the context API.
  */ 
  const ContextConsumer = (props, context) =>
    <Component {...props} {...context} />;
  ContextConsumer.contextTypes = contextTypes;
  return ContextConsumer;
};

// Then, you can use it as follows:

const Child = ({color}) => (
  <div style={{backgroundColor: color}}>
    Hello context!!!
  </div>
);

const ChildwithContext = consumeContext({
  color: React.PropTypes.string
})(Child);

const MiddleComponent = () => <ChildwithContext />;

const App = provideContext(
  {color: React.PropTypes.string},
  () => ({color: 'red'})
)(MiddleComponent);

А вот мой конфиг webpack

общая конфигурация:

const path = require('path');
const webpack = require('webpack');
const fs = require('fs');

// Is the current build a development build
const IS_DEV = process.env.NODE_ENV === 'development';
var root = __dirname;

// Directories
const dirNode = 'node_modules';
const dirApp = path.join(root, 'src');
const dirAssets = path.join(root, 'assets');

// Optimizations
const dependencies = Object.keys(require('./package.json').dependencies);

const nodeExternals = require('webpack-node-externals');

let config = {
    entry: {
        index: path.resolve(root, './src/index')
    },
    externals: [nodeExternals()],
    resolve: {
        extensions: ['.tsx', '.ts', '.js', '.jsx'],
        modules: [dirNode, dirApp, dirAssets],
        alias: {
            // irrelevant to this question
        }
    },
    target: 'node',
    optimization: {
        splitChunks: {
            chunks: 'async',
            minSize: 30000,
            maxSize: 0,
            minChunks: 1,
            maxAsyncRequests: 5,
            maxInitialRequests: 3,
            automaticNameDelimiter: '~',
            name: true,
            cacheGroups: {
                vendors: {
                    test: /[\\/]node_modules[\\/]/,
                    priority: -10
                },
                default: {
                    minChunks: 2,
                    priority: -20,
                    reuseExistingChunk: true
                }
            }
        }
    },
    plugins: [
        // irrelevant to this question
    ],
    module: {
        rules: [
            // BABEL
            {
                test: /\.(js|jsx)$/,
                loader: 'babel-loader',
                exclude: /(node_modules)/,
                options: {
                    compact: true
                }
            },
            // and much more ...
        ]
    }
};

module.exports = config;

Конфигурация сборки

const path = require('path');
const merge = require('webpack-merge');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const webpackConfig = require('./webpack.config.common');

module.exports = merge(webpackConfig, {
    devtool: 'source-map',
    output: {
        path: path.join(__dirname, './dist'),
        filename: 'index.js',

        libraryTarget: 'umd',
        umdNamedDefine: true,
        globalObject: 'this'
    },

    plugins: [new CleanWebpackPlugin(['dist'])]
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...