Having issue using CSS modules in Semantic ui css react typescript
Hi, im trying to enable CSS modules in react, i am encountering this error
ERROR in ./node_modules/css-loader?{"modules":true,"importLoaders":1,"localIdentName":"[name]__[local]___[hash:base64:5]"}!./node_modules/semantic-ui-css/semantic.min.css
Module not found: Error: Can't resolve 'themes/default/assets/fonts/icons.woff2' in 'D:\REACT PROJECTS\TS\fromscratch\node_modules\semantic-ui-css'
@ ./node_modules/css-loader?{"modules":true,"importLoaders":1,"localIdentName":"[name]__[local]___[hash:base64:5]"}!./node_modules/semantic-ui-css/semantic.min.css 6:264315-264365
@ ./node_modules/semantic-ui-css/semantic.min.css
@ ./src/index.tsx
@ multi (webpack)-dev-server/client?http://localhost:3000 index.tsx
ERROR in ./node_modules/css-loader?{"modules":true,"importLoaders":1,"localIdentName":"[name]__[local]___[hash:base64:5]"}!./node_modules/semantic-ui-css/semantic.min.css
Module not found: Error: Can't resolve 'themes/default/assets/images/flags.png' in 'D:\REACT PROJECTS\TS\fromscratch\node_modules\semantic-ui-css'
@ ./node_modules/css-loader?{"modules":true,"importLoaders":1,"localIdentName":"[name]__[local]___[hash:base64:5]"}!./node_modules/semantic-ui-css/semantic.min.css 6:202659-202708
@ ./node_modules/semantic-ui-css/semantic.min.css
@ ./src/index.tsx
@ multi (webpack)-dev-server/client?http://localhost:3000 index.tsx
This is my webpack config
const webpack = require('webpack')
const path = require('path')
module.exports = {
// put sourcemaps inline
devtool: 'eval',
// entry point of our application, within the `src` directory (which we add to resolve.modules below):
entry: [
'index.tsx'
],
// configure the output directory and publicPath for the devServer
output: {
filename: 'app.js',
publicPath: 'dist',
path: path.resolve('dist')
},
// configure the dev server to run
devServer: {
port: 3000,
historyApiFallback: true,
inline: true,
},
// tell Webpack to load TypeScript files
resolve: {
// Look for modules in .ts(x) files first, then .js
extensions: ['.ts', '.tsx', '.js'],
// add 'src' to the modules, so that when you import files you can do so with 'src' as the relative route
modules: ['src', 'node_modules']
},
module: {
rules: [
{
test: /\.tsx?$/,
use: [
{
loader: 'babel-loader'
},
{
loader: 'ts-loader'
}
]
},
{
test: /\.css$/,
include: /node_modules/,
use: [
{
loader: 'style-loader'
},
{
loader: 'css-loader',
options: {
modules: true,
importLoaders: 1,
localIdentName: "[name]__[local]___[hash:base64:5]"
}
}
]
},
{
test: /\.(png|jpg|gif|svg|eot|ttf|woff|woff2)$/,
use: {
loader: 'url-loader',
options: {
limit: 100000,
},
},
},
]
}
}
So currently i'm getting around this by allowing global imports in the webpack config:
rules: [{
test: /\.css$/,
oneOf: [{
resourceQuery: /^\?global$/,
use: [
require.resolve('style-loader'),
require.resolve('css-loader')
]
}, {
use: [
require.resolve('style-loader'),
{
loader: require.resolve('css-loader'),
options: {
importLoaders: 1,
modules: true,
localIdentName: '[name]__[local]___[hash:base64:5]'
}
},
require('./postcss-loader')
]
}]
}]
which then allows me to import global CSS files and do
import 'semantic-ui-css/semantic.min.css?global';
That gives me the styling from semantic without this error you specified.
However, now Semantic-UI is overriding ALL of my styles. I'm trying to find a way to limit Semantic's styles to the component I want it to be in, but if anyone finds a way before me then please let me know...
I'd love for there to be a fix that doesn't involve me needing to allow global CSS in the first place. Maybe something similar to what React Transition Group does which allows you to pass in a classNames={{}} prop to define css. I'm not sure if that makes sense in this context though.
@dnorth did you ever have any luck trying to limit Semantic's styles to just a single component?
I've been struggling with this for a while. I managed to get css modules and semantic ui css (or any external library css) working together in the end.
First add an alias for themes/default/assets
resolve: {
extensions: ['.js', '.css'],
alias: {
'themes/default/assets': path.resolve(__dirname, '../node_modules/semantic-ui-css/themes/default/assets')
}
}
Because you're using css modules, webpack is looking for the relative url in the semantic ui css as a module and can't find it.
Now the issue will be that all the semantic ui class names in your bundled css will be reformatted to [name]__[local]___[hash:base64:5]
I used the getLocalIdent function to use the normal class name if it's coming from the semantic ui css otherwise use the internal css-loader function with your localIdentName pattern.
const getLocalIdent = require('css-loader/lib/getLocalIdent');
{
loader: 'css-loader',
options: {
modules: true,
localIdentName: '[path][name]__[local]--[hash:base64:5]',
getLocalIdent: (loaderContext, localIdentName, localName, options) => {
return loaderContext.resourcePath.includes('semantic-ui-css') ?
localName :
getLocalIdent(loaderContext, localIdentName, localName, options);
}
}
}