I am trying to create a reusable React component with Material UI and npm link
it to a different application. The component and application are being bundled using webpack. The application renders the component fine in development, but when I bundle the application the component starts breaking the material-ui styling.
Some of the solutions I have tried include:
I thought defining @material/core
in the peerDependencies
would solve it, but every time I use a Material-UI component the application throws the Invalid Hook Call Warning.
Nothing seems to work ☹️
component's package.json:
{
"name": "component",
"version": "1.0.0",
"description": "",
"main": "build/index.js",
"scripts": {
"test": "jest",
"start": "webpack --watch",
"build": "webpack --optimize-minimize -p",
"dist": "npm run build"
},
"peerDependencies": {
"@material-ui/core": "^3.2.0 || ^4.0.0",
"react": ">=16.8.0",
"react-dom": ">=16.8.0"
},
"devDependencies": {
"@babel/core": "^7.2.2",
"@babel/plugin-proposal-class-properties": "^7.5.0",
"@babel/preset-env": "^7.5.4",
"@babel/preset-react": "^7.0.0",
"@material-ui/core": "^4.9.0",
"@material-ui/icons": "^3.0.2",
"babel-cli": "^6.26.0",
"babel-core": "^7.0.0-bridge.0",
"babel-eslint": "^7.2.3",
"babel-jest": "^23.6.0",
"babel-loader": "^8.0.5",
"babel-plugin-transform-object-rest-spread": "^6.26.0",
"babel-plugin-transform-react-jsx": "^6.24.1",
"babel-plugin-transform-runtime": "^6.23.0",
"babel-runtime": "^6.26.0",
"enzyme": "^3.7.0",
"enzyme-adapter-react-16": "^1.7.0",
"eslint": "^4.19.1",
"eslint-config-airbnb": "^16.1.0",
"eslint-loader": "^1.7.1",
"eslint-plugin-import": "^2.1.0",
"eslint-plugin-jsx-a11y": "^6.1.2",
"eslint-plugin-react": "^7.7.0",
"faker": "^4.1.0",
"husky": "^1.3.1",
"jest": "^23.6.0",
"jest-styled-components": "^6.3.1",
"react": "^16.12.0",
"react-dom": "^16.12.0",
"sinon": "^7.2.2",
"webpack": "^4.39.2",
"webpack-cli": "^3.3.7"
},
"dependencies": {
"clsx": "^1.0.4",
"prop-types": "^15.6.2"
}
}
component's webpack.config.js
const path = require('path');
module.exports = {
entry: './src/index.jsx',
mode: 'production',
output: {
path: path.resolve(__dirname, 'build'),
filename: 'index.js',
libraryTarget: 'commonjs2',
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
include: path.resolve(__dirname, 'src'),
exclude: /(node_modules|bower_components|build)/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/env'],
},
},
},
],
},
resolve: { extensions: ['*', '.js', '.jsx'] },
externals: {
react: 'react',
},
optimization: {
minimize: true,
},
};
Any help would be much appreciated! Thanks in advance.
Using the components is simple. Just import the component from the library and render it like any other React component. The nice thing about the components is that they all contain their own styles, so there isn't a global CSS file that you have to worry about.
Sometimes you may want even more CSS structure and organization, though, and turn to a library like Semantic UI or Material UI for React. Each Material UI component has built-in styles but also allows these basic styles to be extended or overwritten by styles passed down through props.
The philosophy behind React’s styled-components is the idea that all code relating to a component should live within a single file, including the styling code. In styled-components, the CSS is written in its own section inside the component’s JavaScript file.
The Sass code that is to be injected as styles into a React component is in the ./src folder. The Sass code is expected to be alongside the component that imports it.
This actually makes perfect sense if you check out the docs on npm link
:
First, npm link in a package folder will create a symlink in the global folder {prefix}/lib/node_modules/ that links to the package where the npm link command was executed.
Note that the command only makes a symlink locally so when you build/deploy, it would logically follow the package can't be found.
My advice would be to create a scoped package for your custom component. Create an npm account, upload your package and then add it to your project like this:
npm install @brettoberg/reusable-component
Now, webpack and any other system should be able to find it because it's published.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With