react create-react-app v5配置 px2rem (不暴露 eject方式)

news/2024/7/15 18:10:22 标签: react.js, 前端, 前端框架

环境信息:

create-react-app v5
“react”: “^18.2.0”
“postcss-plugin-px2rem”: “^0.8.1”

配置步骤:

不暴露 eject 配置自己的webpack:
1.下载react-app-rewired 和 customize-cra-5

npm install react-app-rewired customize-cra-5 --save-dev

2.在项目根目录创建一个config-overrides.js 文件

3.安装 postcss-plugin-px2rem 和 lib-flexible (注意这里安装 postcss-px2rem、px2rem这类都行,都是 px2rem衍生的库,不过不同的库具体配置不一样,建议查看文档具体有哪些参数。查看方法可以去 npm 官网 搜索包名,查看详情即可,或者问 ai 比如: 文心,gpt)

cnpm install postcss-plugin-px2rem  lib-flexible --save

4.配置config/webpack.config.js

加上这段代码重写addPostcssPlugins 方法:

// 重写 addPostcssPlugins 方法
const addPostcssPlugins = plugins => (config) => {
  const rules = config.module.rules.find(rule => Array.isArray(rule.oneOf)).oneOf;
  rules.forEach(r => r.use
      && r.use.forEach((u) => {
        if (u.options && u.options.postcssOptions && u.options.postcssOptions.ident === 'postcss') {
          if (!u.options.postcssOptions.plugins) {
            u.options.postcssOptions.plugins = plugins;
          }
          if (u.options.postcssOptions.plugins) {
            const originalPlugins = u.options.postcssOptions.plugins;
            u.options.postcssOptions.plugins = [originalPlugins, ...plugins];
          }
        }
      }));
  return config;
};

然后 使用配置:

addPostcssPlugins([['postcss-pxtorem', {
    rootValue: 37.5,
    propList: ['*'],
  }]]),

或者 :

 addPostcssPlugins([['postcss-px2rem-exclude', {
    remUnit: 37.5,
    exclude: /node_modules/i,
  }]]),

4.在 src/index.js(入口文件引入 import ‘lib-flexible’; )
入口文件引入 import 'lib-flexible';
5.public/index.html 里 注释调 meta 和加上 一段兼容ipad和ipad pro 的兼容代码。

注释掉(注释的原因是 lib-flexible 会自动创建 meta):

<meta name="viewport" content="width=device-width, initial-scale=1" />

在 head里加上(ipad和ipad pro ):

<!-- 淘宝弹性布局方案lib-flexible不兼容ipad和ipad pro的解决方法 -->
    <script>
    /(iPhone|iPad|iPhone OS|Phone|iPod|iOS)/i.test(navigator.userAgent)&&(head=document.getElementsByTagName('head'),viewport=document.createElement('meta'),viewport.name='viewport',viewport.content='target-densitydpi=device-dpi, width=480px, user-scalable=no',head.length>0&&head[head.length-1].appendChild(viewport));
    </script>

这段代码用于检测用户是否正在使用iPhone、iPad、iPod或iOS等苹果设备。如果是,它将创建一个新的视口元标签,并添加到HTML文档的头部。视口元标签的内容设置为 ‘target-densitydpi=device-dpi, width=480px, user-scalable=no’,这意味着它会尝试让页面在各种设备上看起来相似,页面的宽度被设置为480px,并且用户不能手动缩放页面。

我的 index.html 代码如下:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
    <!-- <meta name="viewport" content="width=device-width, initial-scale=1" /> -->
    <meta name="theme-color" content="#000000" />
    <meta
      name="description"
      content="Web site created using create-react-app"
    />
    <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
    <!--
      manifest.json provides metadata used when your web app is installed on a
      user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
    -->
    <link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
    <!--
      Notice the use of %PUBLIC_URL% in the tags above.
      It will be replaced with the URL of the `public` folder during the build.
      Only files inside the `public` folder can be referenced from the HTML.

      Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
      work correctly both with client-side routing and a non-root public URL.
      Learn how to configure a non-root public URL by running `npm run build`.
    -->
    <title>React App</title>
    <!-- 淘宝弹性布局方案lib-flexible不兼容ipad和ipad pro的解决方法 -->
    <script>
    /(iPhone|iPad|iPhone OS|Phone|iPod|iOS)/i.test(navigator.userAgent)&&(head=document.getElementsByTagName('head'),viewport=document.createElement('meta'),viewport.name='viewport',viewport.content='target-densitydpi=device-dpi, width=480px, user-scalable=no',head.length>0&&head[head.length-1].appendChild(viewport));
    </script>
  </head>
  <body>
    <noscript>You need to enable JavaScript to run this app.</noscript>
    <div id="root"></div>
    <!--
      This HTML file is a template.
      If you open it directly in the browser, you will see an empty page.

      You can add webfonts, meta tags, or analytics to this file.
      The build step will place the bundled scripts into the <body> tag.

      To begin the development, run `npm start` or `yarn start`.
      To create a production bundle, use `npm run build` or `yarn build`.
    -->
  </body>
  
</html>

index.html截图
6.重新运行 npm start 审查元素 看看 px 是不是被转换成了rem。如果转换成功说明,配置成功了。
可以在 App.js 里加上一个div然后在 App.css 里写上一个width,height然后 用到 div上。

.box{
  width: 100px;
  height: 100px;
  background: red;
}

测试代码
运行之后的效果截图:
从100px转换成了1.333rem ,当切换时,他也跟着变大变小。
运行后的效果截图

完整的配置代码:

addWebpackAlias和 addLessLoader 你可以忽略。前者是 别名 src 可以写成@ ,后者是 可以使用less 语法。

const {
  override,
  addLessLoader,
  // addPostcssPlugins,
  fixBabelImports,
  addWebpackAlias,
} = require("customize-cra-5");
const path = require("path");
// 重写 addPostcssPlugins 方法
const addPostcssPlugins = plugins => (config) => {
  const rules = config.module.rules.find(rule => Array.isArray(rule.oneOf)).oneOf;
  rules.forEach(r => r.use
      && r.use.forEach((u) => {
        if (u.options && u.options.postcssOptions && u.options.postcssOptions.ident === 'postcss') {
          if (!u.options.postcssOptions.plugins) {
            u.options.postcssOptions.plugins = plugins;
          }
          if (u.options.postcssOptions.plugins) {
            const originalPlugins = u.options.postcssOptions.plugins;
            u.options.postcssOptions.plugins = [originalPlugins, ...plugins];
          }
        }
      }));
  return config;
};

module.exports = override(
  addLessLoader({
    lessOptions: {
      javascriptEnabled: true,
      // modifyVars: { '@primary-color': '#1DA57A' }, // 你的主题色
    },
  }),
  addPostcssPlugins([['postcss-pxtorem', {
    rootValue: 37.5,
    propList: ['*'],
  }]]),
  // addPostcssPlugins([['postcss-px2rem-exclude', {
  //   remUnit: 37.5,
  //   exclude: /node_modules/i,
  // }]]),
  addWebpackAlias({
    "@": path.resolve("src"),
  })
);

总结:

我是根据 issues里的回答写出来的具体可参考:
react项目:在configoveride.js中addPostcssPlugins添加postcss-pxtorem无效
github ieeues 截图
其他配置可以参考:
react create-react-app v5 从零搭建项目(不暴露 eject)


http://www.niftyadmin.cn/n/5077518.html

相关文章

jq时间戳转换成日期形式

function timestampToTime(timestamp) {var date new Date(timestamp * 1000);//时间戳为10位需*1000&#xff0c;时间戳为13位的话不需乘1000var Y date.getFullYear() -;var M (date.getMonth()1 < 10 ? 0(date.getMonth()1) : date.getMonth()1) -;var D date.get…

腾讯云2023年双十一优惠活动整理汇总

随着双十一的到来&#xff0c;各大云服务厂商也开始纷纷推出优惠活动&#xff0c;其中腾讯云作为国内知名的云服务提供商&#xff0c;自然也不例外。那么&#xff0c;腾讯云双十一优惠活动都有哪些呢&#xff1f;本文将会为大家整理汇总&#xff0c;方便大家了解和选择。 一、腾…

swift界面初体验

1.添加视图 lazy var contentView: UIView {let a UIView()self.view.addSubview(a)return a}()2.添加文本 lazy var tipsLabel: UILabel {let a UILabel()a.font UIFont.regular13a.textColor UIColor.withHex(hexString:"#58C65C")a.text R.string.locali…

N9030B是德科技信号分析仪

181/2461/8938它能够实现对复杂信号的实时捕获、分析和处理。Keysight N9030B采用了最先进的技术和设计&#xff0c;为工程师和科学家们提供了一系列强大的功能&#xff0c;帮助他们更好地进行信号分析&#xff0c;以满足不断变化的应用需求。 Keysight N9030B采用了全新的硬件…

【java学习】类的写法(13)

文章目录 1. 类的语法格式2. 创建java自定义类 1. 类的语法格式 修饰符 class 类名 {属性声明 ;方法声明 ; }说明&#xff1a; (1) 修饰符public:类可以被任意访问 (2) 类的正文要用{ }括起来 示例&#xff1a; public class Person{public int age ; // 声明公有变量 agepu…

遍历List集合

1.初始化 // 写法一 List<String> list new ArrayList<>(); list.add("a"); list.add("b"); list.add("c");// 写法二 List<String> list new ArrayList(){{add&#xff08;"a"&#xff09;;add&#xff08;&quo…

javascript二维数组(19)不要键名只保留值的算法

在数组var a[ {pre1_day_off:1}, {pre2_day_off:2}, {pre3_day_off:3} ]中&#xff0c;如果去除键名只保留值&#xff0c;形成[1,2,3]这样的数组格式 在JavaScript中&#xff0c;你可以通过使用Array.prototype.map函数来实现这个目标。map函数遍历数组的每个元素&#xff0c;然…

Springboot学习笔记——3

Springboot学习笔记——3 一、热部署1.1、手动启动热部署1.2、自动启动热部署1.3、热部署范围配置1.4、关闭热部署 二、配置高级2.1、第三方bean属性绑定2.2、松散绑定2.3、常用计量单位应用2.4、bean属性校验2.5、进制数据转换规则 三、测试3.1、加载测试专用属性3.2、加载测试…