Mormen
Mormen

Reputation: 178

Redux in npm package

I have been working on my own UI lib as npm package and some of components use Redux. I register components to store as usually, but there occur an error, which looks like:

could not find react-redux context value; please ensure the component is wrapped in a <Provider>

For demonstration purposes, I minified that UI lib

// index.js
export * from './store/reducers'
export { default as MyComponent } from './components/MyComponent'
// MyComponent.js
import React from 'react'
import { useSelector, useDispatch } from 'react-redux'
const MyComponent = () => {
    const pageRemounter = useSelector(state => state.pageRemounter)
    const dispatch = useDispatch()
    const handleClick = () => {
        dispatch({type: "PAGE_REMOUNT"})
    }
    return (
        <>
            <button onClick={handleClick}>Click me</button>
            <div>
                {
                    pageRemounter ? "Yes" : "No"
                }
            </div>
        </>
    )
}
export default MyComponent
// reducer.js
export const pageRemounter = (state=false, action) => {
    switch (action.type) {
        case "PAGE_REMOUNT":
            return !state

        default:
            return state
    }
}
// webpack.config.js
module.exports = {
    mode: "development",
    entry: "./src/index.js",
    module: {
        rules: [
            {
                test: /\.(js|jsx)$/,
                exclude: /nodeModules/,
                use: {
                    loader: "babel-loader"
                }
            }
        ]
    },
    externals: {
        react: {
            root: 'React',
            commonjs2: 'react',
            commonjs: 'react',
            amd: 'react'
        },
        'react-dom': {
            root: 'ReactDOM',
            commonjs2: 'react-dom',
            commonjs: 'react-dom',
            amd: 'react-dom'
        }
    },
    resolve: {
        extensions: ['*', '.js', '.jsx']
    },
    output: {
        path: __dirname + '/build',
        publicPath: '/',
        filename: 'index.js',
        libraryTarget: 'commonjs2'
    },
    devServer: {
        contentBase: './build'
    },
    devtool: 'inline-source-maps'
};

In random app which use MyComponent

// store.js
import { createStore, combineReducers } from 'redux'
import { 
    pageRemounter
} from 'mypackage'


const allReducers = combineReducers(
    { 
        pageRemounter
    }
)

const store = createStore(allReducers)

export default store
// index.js
import React from 'react'
import ReactDOM from 'react-dom/client'

import { Provider } from 'react-redux'
import store from './store'

import { MyComponent } from 'myownlib'


const root = ReactDOM.createRoot(document.getElementById('root'))
root.render(
    <React.StrictMode>
        <Provider store={store}>
            <MyComponent />
        </Provider>
    </React.StrictMode>
)

Btw there was problem with hooks, so in webpack.config.js was added extarnals.

Upvotes: 1

Views: 800

Answers (1)

Mormen
Mormen

Reputation: 178

Finally I found solution. Absolutely remove Webpack and just feed Babel.

$ npm install @babel/core @babel/cli @babel/preset-env @babel/preset-react
// babel.config.js
module.exports = {
    presets: [
        [
            "@babel/preset-env",
            {
              "useBuiltIns": "entry"
            }
        ],
        "@babel/preset-react"
    ]
}
$ ./node_modules/.bin/babel src --out-dir dist

Now it's ready to publish into npm registry.

Upvotes: 1

Related Questions