react 使用 postcss-px-to-viewport 实现 px 自动转 vw 自适应

最近做了一个 react + next 的网址大全项目,需要实现不管是大屏还是小屏,都能让整个页面在一页中显示而不出现滚动条,一顿操作后还是有点小瑕疵,大佬给我推荐了一个插件:postcss-px-to-viewport,试了一下,确实好用,记录一下。

一、安装 postcss-px-to-viewport

bash 复制代码
pnpm install postcss postcss-px-to-viewport --save-dev

安装完后,可以看到我们的项目依赖中多了一行

二、在项目根目录创建 postcss.config.js 文件

键入以下内容

javascript 复制代码
module.exports = {
  plugins: {
    'postcss-import': {}, // 必须放在第一个
    'postcss-px-to-viewport': {
      viewportWidth: 1920,
      unitPrecision: 5,
      viewportUnit: 'vw',
      selectorBlackList: [],
      minPixelValue: 1,
      mediaQuery: false
    },
  }
}

三、修改 next.config.ts 文件

javascript 复制代码
import type { NextConfig } from 'next';
import { join, resolve } from 'path';

const nextConfig: NextConfig = {
  output: 'export',
  distDir: 'build',
  // 使用相对路径前缀,确保静态资源可以正确加载
  assetPrefix: './',
  images: {
    unoptimized: true,
  },
  outputFileTracingRoot: process.cwd(),
  experimental: {
    optimizeCss: false
  },

  webpack: (config, { isServer }) => {
    // 配置 CSS 输出路径
    if (!isServer) {
      const miniCssExtractPlugin = config.plugins.find(
        (p: { constructor: { name: string; }; }) => p.constructor.name === 'MiniCssExtractPlugin'
      );
      if (miniCssExtractPlugin) {
        (miniCssExtractPlugin as any).options.filename = 'static/css/[name].[contenthash].css';
        (miniCssExtractPlugin as any).options.chunkFilename = 'static/css/[name].[contenthash].css';
      }
    }

    // 配置 manifest 文件输出路径
    config.plugins.push(
      new (require('webpack').DefinePlugin)({
        'process.env.MANIFEST_OUTPUT_PATH': JSON.stringify(
          resolve(__dirname, 'build/_next/static')
        )
      })
    );

    // 配置图片和其他资源的输出路径
    config.module.rules.forEach((rule: { oneOf: any[]; }) => {
      if (rule.oneOf) {
        rule.oneOf.forEach((oneOfRule: { type?: string | undefined; generator?: { filename: string; } | undefined; test?: { test: (arg0: string) => boolean; } | undefined; }) => {
          const assetRule = oneOfRule as { type?: string; generator?: { filename: string; }; test?: { test: (arg0: string) => boolean } };
          
          if (assetRule.type === 'asset') {
            assetRule.generator = {
              filename: 'static/media/[name].[contenthash][ext]',
            };
          }

          if (
            assetRule.test &&
            typeof assetRule.test.test === 'function' &&
            assetRule.test.test('.svg')
          ) {
            assetRule.generator = {
              filename: 'static/media/[name].[contenthash][ext]',
            };
          }
        });
      }
    });

    // 确保公共路径正确设置
    config.output = {
      ...config.output,
      publicPath: './_next/',
    };

    return config;
  },
};

export default nextConfig;

大功告成!现在跑动项目,会发现,我们的 px 变成了 vw,可以自动自适应啦!

相关推荐
IT_陈寒21 小时前
Python+AI实战:用LangChain构建智能问答系统的5个核心技巧
前端·人工智能·后端
袁煦丞1 天前
MoneyPrinterTurbo一键生成短视频:cpolar内网穿透实验室第644个成功挑战
前端·程序员·远程工作
代码小学僧1 天前
让 AI 真正帮你开发:前端 MCP 实用技巧分享
前端
晴殇i1 天前
前端鉴权新时代:告别 localStorage,拥抱更安全的 JWT 存储方案
前端·javascript·面试
Json____1 天前
使用node Express 框架框架开发一个前后端分离的二手交易平台项目。
java·前端·express
since �1 天前
前端转Java,从0到1学习教程
java·前端·学习
码农刚子1 天前
ASP.NET Core Blazor简介和快速入门 二(组件基础)
javascript·后端
小奋斗1 天前
面试官:[1] == '1'和[1] == 1结果是什么?
前端·面试
萌萌哒草头将军1 天前
尤雨溪宣布 oxfmt 即将发布!比 Prettier 快45倍 🚀🚀🚀
前端·webpack·vite
weixin_405023371 天前
webpack 学习
前端·学习·webpack