React18TS项目:配置react-css-modules,使用styleName

使用pnpm和Babel插件实现CSSModules在Webpack中的配置
本文介绍了如何在项目中添加`babel-plugin-react-css-modules`并配置Webpack以启用CSSModules功能,包括手动安装依赖、Webpack配置示例和在TypeScript项目中正确使用styleName。

他的好处不说了

网上一堆文章一个能打的都没有,

添加开发依赖

pnpm add -D @dr.pogodin/babel-plugin-react-css-modules @types/react-css-modules  

Babel Plugin "React CSS Modules" | Dr. Pogodin Studio

看@dr.pogodin/babel-plugin-react-css-modules官方文档

不使用babel-plugin-react-css-modules

手搭webpack配置需要处理

1.能启用css modules

对于裸 Webpack,请参见webpack css-loader的 modules 的选项 链接

2.配置@dr.pogodin/babel-plugin-react-css-modules

使用

  • 将此插件作为直接依赖项安装(在不允许编译时 styleName 解析的边缘情况下,插件会回退到运行时解析)。
npm install --save @dr.pogodin/babel-plugin-react-css-modules
  • Install Webpack at least as a dev dependency:
    至少将 Webpack 作为开发依赖项安装 Webpack:
npm install --save-dev webpack
  • Add the plugin to Babel configuration:
    将插件添加到 Babel 配置中:
{
  "plugins": [
    ["@dr.pogodin/react-css-modules", {
      // The default localIdentName in "css-loader" is "[hash:base64]",
      // it is highly-recommended to explicitly specify the same value
      // both here, and in "css-loader" options, including the hash length
      // (the last digit in the template below).
      "generateScopedName": "[hash:base64:6]"

      // See below for all valid options.
    }]
  ]
}

我自己项目手写的webpack.base.js中使用

const CSS_MODULE_LOCAL_IDENT_NAME = '[name]__[local]___[hash:base64:5]';


{
	test: /.(jsx?)|(tsx?)$/,
		exclude: /node_modules/,
		use: [
		{
			loader: 'babel-loader',
			options: {
				presets: ['@babel/preset-env', '@babel/preset-react', '@babel/preset-typescript'],
				plugins: [
					[
						'@dr.pogodin/react-css-modules',
						{
							generateScopedName: CSS_MODULE_LOCAL_IDENT_NAME,
							autoResolveMultipleImports: true, // 允许多个匿名导入
							webpackHotModuleReloading: true, // 启用热模块重新加载代码的注入
							handleMissingStyleName: 'throw', // 确定应为未定义的 CSS 模块执行的操作
							filetypes: {
								'.less': {
									syntax: 'postcss-less',
								},
							},
						},
					],
				],
			},
		},
	],
},
{
	test: /\.less$/,
	use: [
		'style-loader',
		{
			loader: 'css-loader',
			options: {
				modules: {
					localIdentName: CSS_MODULE_LOCAL_IDENT_NAME,
					auto: resourcePath => resourcePath.endsWith('.module.less'),
				},
			},
		},
		{
			loader: 'postcss-loader',
			options: {
				postcssOptions: {
					plugins: [['postcss-preset-env', {}]],
				},
			},
		},
		{
			loader: 'less-loader',
			options: {
				lessOptions: {
					javascriptEnabled: true,
				},
			},
		},
	],
	// 排除 node_modules 目录
	exclude: /node_modules/,
},

3.TS项目不能直接在jsx中使用styleName,会报错,

需要引入@types/react-css-modules

就可以使用module.less和styleName了

项目中使用

index.module.less

.adminColor {
	color: aquamarine;
	background-color: black;
}

index.tsx

import React from 'react';
import './index.module.less';

const Dashboard: React.FC = () => {
	return (
		<>
			<h2 styleName="adminColor">我的</h2>
		<div styleName="adminColor">我的</div>
		</>
	);
};
export default Dashboard;

效果

样式编码

{ "name": "TOOL", "version": "5.2.0", "private": true, "description": "用增测试工具", "repository": { "type": "git", "url": "" }, "license": "ISC", "author": "SHEIN UGrowth", "scripts": { "analyze": "cross-env ANALYZE=1 max build", "build": "NODE_ENV=production sh build.sh", "build:gray": "cross-env UMI_ENV=igray max build", "build:prod": "cross-env UMI_ENV=iprod max build", "build:test": "cross-env UMI_ENV=itest max build", "dev": "pnpm run start:dev", "doctor": "npx @shined/doctor", "format": "prettier --cache --write .", "i18n-remove": "pro i18n-remove --locale=zh-CN --write", "postinstall": "max setup", "lint": "pnpm run postinstall && pnpm run lint:js && pnpm run lint:style && pnpm run lint:prettier && pnpm run tsc", "lint-staged": "lint-staged", "lint:fix": "eslint --fix --cache --ext .js,.jsx,.ts,.tsx && pnpm run lint:style", "lint:js": "eslint --cache --ext .js,.jsx,.ts,.tsx", "lint:prettier": "prettier -c --write \"src/**/*\" --end-of-line auto", "lint:style": "stylelint --fix \"src/**/*.less\" --syntax less", "openapi": "UMI_ENV=openapi max openapi", "playwright": "playwright install && playwright test", "prepare": "husky", "prettier": "prettier -c --write \"src/**/*\"", "serve": "umi-serve", "start": "cross-env REACT_APP_ENV=local UMI_ENV=dev max dev", "start:dev": "cross-env REACT_APP_ENV=dev MOCK=none UMI_ENV=dev max dev", "start:no-mock": "cross-env MOCK=none UMI_ENV=dev max dev", "start:no-ui": "cross-env UMI_UI=none UMI_ENV=dev max dev", "start:pre": "cross-env REACT_APP_ENV=pre UMI_ENV=dev max dev", "start:test": "cross-env REACT_APP_ENV=test MOCK=none UMI_ENV=dev max dev", "test": "max test", "test:component": "max test ./src/components", "test:e2e": "node ./tests/run-tests.js", "tsc": "tsc --noEmit" }, "dependencies": { "@ant-design/icons": "4.8.3", "@ant-design/moment-webpack-plugin": "^1.0.0", "@ant-design/pro-components": "2.8.7", "@arco-design/web-react": "^2.66.5", "@dnd-kit/core": "^6.3.1", "@dnd-kit/sortable": "^10.0.0", "@dnd-kit/utilities": "^3.2.2", "@monaco-editor/react": "^4.7.0", "@shein-components/avatar-robot": "^1.1.3", "@shein-components/rule-graph": "^0.0.2", "@shein-ugrowth/dynamic-modules": "4.1.15", "@shein-ugrowth/game-dejavu": "^0.1.9", "@umijs/max": "^4.4.10", "@umijs/max-plugin-openapi": "^2.0.3", "@umijs/plugins": "^4.4.10", "@umijs/preset-umi": "^4.0.48", "antd": "5.25.1", "big.js": "^6.2.1", "classnames": "^2.3.0", "cross-env": "7.0.0", "cross-port-killer": "^1.3.0", "dom-to-image-more": "^3.6.0", "form-render": "^2.4.8", "husky": "^9.1.7", "jiti": "^2.4.2", "lint-staged": "^13", "lodash-es": "^4.17.21", "mockjs": "^1.1.0", "moment": "^2.30.1", "prettier-plugin-organize-imports": "^3.2.2", "prettier-plugin-packagejson": "^2.4.3", "qrcode.react": "^3.1.0", "query-string": "^8.2.0", "rc-menu": "^9.16.1", "react": "^18.2.0", "react-color": "^2.19.3", "react-dom": "^18.2.0", "react-helmet-async": "^1.2.0", "react-quill": "^2.0.0", "react-redux": "^8.1.3", "rrc-loader-helper": "^9.2.1", "sheinq": "^2.0.28", "swagger-ui-dist": "^5.21.0", "xss": "^1.0.15" }, "devDependencies": { "@playwright/test": "^1.17.0", "@shined/doctor": "^0.0.50", "@shined/eslint": "^0.0.0-snapshot.13", "@types/big.js": "^6.2.2", "@types/express": "^4.17.0", "@types/history": "^4.7.0", "@types/jest": "^26.0.0", "@types/lodash-es": "^4.17.12", "@types/react": "^18.3.21", "@types/react-color": "^3.0.11", "@types/react-dom": "^18.3.7", "@types/react-helmet": "^6.1.0", "eslint": "^9.34.0", "prettier": "^3.6.2", "typescript": "^5.9.2" }, "packageManager": "pnpm@8.15.4", "engines": { "node": ">=12.0.0" }, "pnpm": { "overrides": { "@ant-design/icons": "4.8.3", "@ant-design/pro-components": "2.8.7", "antd": "5.25.1", "rc-tabs": "15.6.1" }, "patchedDependencies": { "@umijs/preset-umi@4.4.10": "patches/@umijs__preset-umi@4.4.10.patch", "rc-tabs@15.6.1": "patches/rc-tabs@15.6.1.patch" } } } 这是我的package-json, 我的node是18.16.0没看出问题啊
最新发布
09-10
你提供的 `package.json` 文件整体结构是合法的,没有明显的语法错误。你使用的是 **Node.js v18.16.0**,这是一个相对稳定的版本,理论上应该支持现代的 JavaScript 语法。 但从你的报错信息: ``` [error] package.json: SyntaxError: Unexpected token 'with' ``` 可以推测,问题可能出在某个依赖或插件尝试加载 `package.json` 时,误将其当作 JavaScript 模块来解析,而不是当作 JSON 文件。Node.js 从 v12 开始默认将 `.js` 文件视为 CommonJS 模块,而 `.json` 文件则始终作为 JSON 解析。如果你的某些工具(如 `prettier-plugin-packagejson` 或 `jiti`)错误地尝试将 `package.json` 当作 JS 模块执行,就可能触发此类错误。 --- ### ✅ 排查与解决方案: #### 1. **确保 `package.json` 是纯 JSON** 虽然你已经检查过格式没问题,但建议使用以下命令验证: ```bash npx validate-pkg ``` 或者手动使用 JSON 解析器检查: ```bash node -e "require('./package.json')" ``` 如果这个命令报错,说明 `package.json` 中存在隐藏的非法字符或结构。 #### 2. **升级或降级 `prettier` 和相关插件** 你使用了 `prettier@^3.6.2`,而你报错中显示使用了 `prettier-plugin-packagejson@^2.4.3`,这两个插件组合可能会导致解析 `package.json` 时出错。 尝试升级或锁定版本: ```bash pnpm add prettier prettier-plugin-packagejson@latest ``` 或者降级到稳定版本: ```bash pnpm add prettier@2.8.8 prettier-plugin-packagejson@2.4.2 ``` #### 3. **排除 `package.json` 被某些工具误解析** 在 `.lintstagedrc` 中,你可能配置了对 `package.json` 使用 `prettier`,这可能触发格式化动作。请检查 `.lintstagedrc` 内容: ```json { "*.{md,json}": ["prettier --cache --write"], "*.ts?(x)": ["npx @shined/doctor", "eslint --fix", "prettier --cache --parser=typescript --write"], "*.{css,less}": [] } ``` 建议修改为: ```json { "*.json": ["prettier --cache --write"], "*.md": ["prettier --cache --write"], "*.ts?(x)": ["npx @shined/doctor", "eslint --fix", "prettier --cache --parser=typescript --write"], "*.{css,less}": [] } ``` 这样可以避免某些插件将 `package.json` 当作 JS 模块处理。 #### 4. **尝试清除缓存并重装依赖** ```bash rm -rf node_modules package-lock.json .cache pnpm install ``` #### 5. **检查是否使用了 `jiti` 或 `unimport` 等自动解析工具** 你依赖中使用了 `jiti`,这是一个基于 ES Module 的动态导入工具,可能在某些场景下尝试解析 `package.json`,导致错误。 --- ### ✅ 总结 - 你的 `package.json` 格式看起来没问题。 - 报错可能来自工具链错误地将 `package.json` 当作 JS 模块处理。 - 建议锁定或降级 `prettier` 和相关插件版本。 - 修改 `.lintstagedrc` 避免误处理 `package.json`。 - 清理缓存并重新安装依赖。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

yusirxiaer

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值