Using Semantic UI With CSS Modules in Webpack

2020-04-14 07:02发布

问题:

I have import 'semantic-ui-css/semantic.min.css' in index.js, as instructed by Semantic UI.

Before I did yarn eject (to enable CSS modules with create-react-app) everything worked fine, but as soon as I did I got the following error:

Module not found: Can't resolve 'themes/default/assets/fonts/icons.eot' in '[MY_PROJECT_DIR]/node_modules/semantic-ui-css'

I thought that it might be an issue with Webpack's loaders' not dealing with font files, so I found this:

{
    test: /\.(eot|woff|woff2|ttf|svg|png|jpg)$/,
    loader: 'url-loader?limit=30000&name=[name]-[hash].[ext]'
}

I added it to my webpack.config.dev.js in the rules array (after the eslint loader and before the big one with everything else) but nothing changed.

回答1:

Add the following in the rules section:

   const config = {
        entry: {
            vendor: ['semantic-ui-react'],
        },
        ...,
        module: {
            rules: [
                ...,
                {
                    test: [/\.bmp$/, /\.gif$/, /\.jpe?g$/, /\.png$/],
                    loader: require.resolve('url-loader'),
                    options: {
                        limit: 10000,
                        name: 'static/media/[name].[hash:8].[ext]',
                    },
                },
                {
                    test: [/\.eot$/, /\.ttf$/, /\.svg$/, /\.woff$/, /\.woff2$/],
                    loader: require.resolve('file-loader'),
                    options: {
                        name: 'static/media/[name].[hash:8].[ext]',
                    },
                },
            ],
        },
     ...,
    };

    module.exports = config

Hopes it helps !



回答2:

I was having the same issue, I solved it by splitting the webpack's css loader rules into 2:

  1. Will include everything except node_modules, uses css modules. This will deal with internal css modules.
  2. Will only include node_modules, exclude /src. This will deal with semantic-ui and any other third-party library

The resulting rules on webpack.config.dev.js generated by CRA's eject script, would look like this:

// Internal CSS
      // "postcss" loader applies autoprefixer to our CSS.
      // "css" loader resolves paths in CSS and adds assets as dependencies.
      // "style" loader turns CSS into JS modules that inject <style> tags.
      // In production, we use a plugin to extract that CSS to a file, but
      // in development "style" loader enables hot editing of CSS.
      {
        test: /\.css$/,
        exclude: /node_modules/,
        use: [
          require.resolve('style-loader'),
          {
            loader: require.resolve('css-loader'),
            options: {
              importLoaders: 1,
              modules: true,
              localIdentName: '[name]__[local]___[hash:base64:5]'
            },
          },
          {
            loader: require.resolve('postcss-loader'),
            options: {
              // Necessary for external CSS imports to work
              // https://github.com/facebookincubator/create-react-app/issues/2677
              ident: 'postcss',
              plugins: () => [
                require('postcss-flexbugs-fixes'),
                autoprefixer({
                  browsers: [
                    '>1%',
                    'last 4 versions',
                    'Firefox ESR',
                    'not ie < 9', // React doesn't support IE8 anyway
                  ],
                  flexbox: 'no-2009',
                }),
              ],
            },
          },
        ],
      },
// External CSS
      {
        test: /\.css$/,
        include: /node_modules/,
        exclude: /src/,
        use: [
          require.resolve('style-loader'),
          {
            loader: require.resolve('css-loader'),
            options: {
              importLoaders: 1,
            },
          },
          {
            loader: require.resolve('postcss-loader'),
            options: {
              // Necessary for external CSS imports to work
              // https://github.com/facebookincubator/create-react-app/issues/2677
              ident: 'postcss',
              plugins: () => [
                require('postcss-flexbugs-fixes'),
                autoprefixer({
                  browsers: [
                    '>1%',
                    'last 4 versions',
                    'Firefox ESR',
                    'not ie < 9', // React doesn't support IE8 anyway
                  ],
                  flexbox: 'no-2009',
                }),
              ],
            },
          },
        ],
      },

I don't think this answer is optimal, but certainly worked for me. Good luck