Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React + Webpack + Material UI styling breaking in production

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:

  • https://material-ui.com/getting-started/faq/#why-arent-my-components-rendering-correctly-in-production-builds
  • https://reactjs.org/warnings/invalid-hook-call-warning.html

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.

like image 558
Brett Oberg Avatar asked Jan 23 '20 18:01

Brett Oberg


People also ask

How do I use React components?

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.

What is the Best CSS library for react?

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.

What is react styled-components?

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.

How to inject Sass code into a React component?

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.


Video Answer


1 Answers

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.

like image 131
serraosays Avatar answered Sep 23 '22 14:09

serraosays