Reputation: 37
I'm trying to implement css modules in my typescript react project, but still can't get the css file imported:
Here are the files regarding the App and css:
App.tsx:
import "./App.css";
//returns some jsx
<h3 styleName="background" className="background">CSS Here</h3>
//I also use react className to hope the css renders
App.css:
.background {
color: pink;
background-color: black;
font-size: 20px;
}
App.css.d.ts:
interface CssExports {
'background': string;
}
export const cssExports: CssExports;
export default cssExports;
And Here are the configs, where I think the problem comes from:
webpack.config.ts:
import * as path from "path";
import * as webpack from "webpack";
const ForkTsCheckerWebpackPlugin = require("fork-ts-checker-webpack-plugin");
const config: webpack.Configuration = {
entry: "./src/index.tsx",
module: {
rules: [
{
test: /\.(ts|js)x?$/,
exclude: /node_modules/,
use: {
loader: "babel-loader",
options: {
presets: [
"@babel/preset-env",
"@babel/preset-react",
"@babel/preset-typescript",
],
},
},
},
{
test: /\.css$/,
use: [
{ loader: "style-loader" },
{ loader: "css-modules-typescript-loader" },
{
loader: "css-loader",
options: {
modules: true,
},
},
// {
// loader: "postcss-loader",
// options: {
// postcssOptions: {
// plugins: [
// [
// "postcss-preset-env",
// {
// // Options
// },
// ],
// ],
// },
// },
// },
// I don't know how they should be chained and what loader/options exactly to include
],
},
],
},
resolve: {
extensions: [".tsx", ".ts", ".js"],
},
output: {
path: path.resolve(__dirname, "build"),
filename: "bundle.js",
},
devServer: {
contentBase: path.join(__dirname, "build"),
compress: true,
port: 4000,
},
plugins: [
new ForkTsCheckerWebpackPlugin({
async: false,
eslint: {
files: "./src/**/*",
},
}),
],
};
export default config;
.babelrc:
{
"presets": [
"@babel/preset-env",
"@babel/preset-react",
"@babel/preset-typescript"
],
"plugins": [
["@dr.pogodin/react-css-modules", {
"webpackHotModuleReloading": true
}],
[
"@babel/plugin-transform-runtime",
{
"regenerator": true
}
],
]
}
If helpful:
tsconfig.json:
{
"compilerOptions": {
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"allowSyntheticDefaultImports": true,
"skipLibCheck": true,
"esModuleInterop": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react"
},
"include": ["src"]
}
package.json:
"dependencies": {
"@dr.pogodin/babel-plugin-react-css-modules": "^6.0.7",
"react": "^16.14.0",
"react-dom": "^16.14.0"
},
"devDependencies": {
"@babel/core": "^7.12.3",
"@babel/plugin-transform-runtime": "^7.12.1",
"@babel/preset-env": "^7.12.1",
"@babel/preset-react": "^7.12.5",
"@babel/preset-typescript": "^7.12.1",
"@babel/runtime": "^7.12.5",
"@teamsupercell/typings-for-css-modules-loader": "^2.4.0",
"@testing-library/dom": "^7.26.5",
"@testing-library/jest-dom": "^5.11.5",
"@testing-library/react": "^11.1.1",
"@testing-library/user-event": "^12.2.0",
"@types/fork-ts-checker-webpack-plugin": "^0.4.5",
"@types/jest": "^26.0.15",
"@types/react": "^16.9.55",
"@types/react-dom": "^16.9.9",
"@types/webpack": "^4.41.24",
"@types/webpack-dev-server": "^3.11.1",
"@typescript-eslint/eslint-plugin": "^4.6.1",
"@typescript-eslint/parser": "^4.6.1",
"babel-jest": "^26.6.3",
"babel-loader": "^8.1.0",
"babel-plugin-react-css-modules": "^5.2.6",
"css-loader": "^5.0.1",
"css-modules-typescript-loader": "^4.0.1",
"eslint": "^7.12.1",
"eslint-config-prettier": "^6.15.0",
"eslint-plugin-react": "^7.21.5",
"eslint-plugin-react-hooks": "^4.2.0",
"fork-ts-checker-webpack-plugin": "^5.2.1",
"jest": "^26.6.3",
"postcss": "^8.1.6",
"postcss-loader": "^4.0.4",
"precss": "^4.0.0",
"prettier": "2.1.2",
"react-test-renderer": "^17.0.1",
"style-loader": "^2.0.0",
"ts-node": "^9.0.0",
"typescript": "^4.0.5",
"webpack": "^5.4.0",
"webpack-cli": "^4.2.0",
"webpack-dev-server": "^3.11.0"
}
Any hint would be helpful, thanks!
Upvotes: 1
Views: 1427
Reputation: 17504
The problem here is the generated hash name between babel-plugin-react-css-modules
vs css-loader
are now different in pattern.
In order to fix this, since babel-plugin-react-css-modules
is now using this pattern [path]___[name]__[local]___[hash:base64:5]
by default, you just fix by configure css-loader
using the same pattern as following:
{
loader: 'css-loader',
options: {
modules: {
localIdentName: '[path]___[name]__[local]___[hash:base64:5]',
},
}
}
Upvotes: 1