ctrlplusb / react-universally

A starter kit for universal react applications.
MIT License
1.7k stars 244 forks source link

Cannot add React-toolbox components #477

Closed PDS42 closed 6 years ago

PDS42 commented 7 years ago

Hello, I've been stuck for a while on this issue! I cloned the branch feature/postcss-sass, and whenever I try to add a react-toolbox component, I get this error . I did not find anything helpful in previous issues or somewhere else on Github/StackOverflow. Can anyone help me on this ?

I'll link my config files if necessary, but I did not touch them yet on this version. What am I missing?

diondirza commented 7 years ago

See this branch, hopefully will solve your issue.

unleashit commented 7 years ago

In addition to the right loader setup, I just figured out from diondriza's repo that you have to whitelist react-toolbox in values.js like:

  nodeExternalsFileTypeWhitelist: [
    /\.(eot|woff|woff2|ttf|otf)$/,
    /\.(svg|png|jpg|jpeg|gif|ico)$/,
    /\.(mp4|mp3|ogg|swf|webp)$/,
    /\.(css|scss|sass|sss|less)$/,
    /react-toolbox/,
  ],

For your loader setup, be aware that the stock post-css/sass feature branch excludes all of node_modules for css modules, which you need for RT. So what I did was exclude the path to RT in it like this:

        // Dont CSS modules on css files from node_modules folder
        ifElse(isClient || isServer)({
          test: /(node_modules.*\.css)$/,
          exclude: path.join(appRootDir.get(), 'node_modules', 'react-toolbox'),
          use: ifProdClient(
            ExtractTextPlugin.extract({
              fallback: 'style-loader',
              use: ['css-loader', 'postcss-loader'],
            }),
            [...ifNode(['css-loader/locals'], ['style-loader', 'css-loader']), 'postcss-loader'],
          ),
        }),

And then added an explicit rule for it elsewhere like:

        // React toolbox needs CSS modules
        ifElse(isClient || isServer)(
          mergeDeep(
            {
              test: /\.css$/,
              include: path.join(appRootDir.get(), 'node_modules', 'react-toolbox'),
            },

            ifDevClient({
              use: [
                'style-loader',
                {
                  loader: 'css-loader',
                  options: {
                    modules: true,
                    sourceMap: true,
                    importLoaders: 1,
                    localIdentName,
                  },
                },
                'postcss-loader',
              ],
            }),

            ifProdClient(() => ({
              use: [
                ...ExtractTextPlugin.extract({
                  fallback: 'style-loader',
                  use: [
                    `css-loader?modules=1&importLoaders=1&localIdentName=${localIdentName}`,
                  ],
                }),
              ],
            })),

            ifNode({
              use: [
                'classnames-loader',
                `css-loader/locals?modules=1&importLoaders=1&localIdentName=${localIdentName}`,
                'postcss-loader',
              ],
            }),
          ),
        ),

You can also do it like @diondirza did (seperate scss and css rules) if that works for you.

Spent at least 6 hours trying to figure this out. Hope this helps!

EDIT: just to be complete, if you're doing it like me you should also exclude RT from the main scss/css test. Here I've excluded the whole node_modules directory, since there's already a test (the one above) for it. This should actually be done anyway.... and I think it might be a bug that it isn't:

            {
              test: /(\.scss|\.css)$/,
              exclude:  /(node_modules.*\.css)$/,
            },
PDS42 commented 7 years ago

Thanks @diondirza, and a big THANK YOU @unleashit ! That's an amazing answer, and I hope it gets referenced because it's simple, well explained, and it works. Really, thanks for your time, I've been stuck on this for a while. I'm so grateful!