Полка CRA+react-app-rewired для сборки reactH5

React.js

Это мой первый день в Gengwen Challenge

предисловие

  • Эта статья в основном черезcreate-react-appстроительные лесаreact-app-rewiredДобавьте некоторую дополнительную конфигурацию веб-пакета, чтобы построить сборку на основеvwПолка H5

Начинать

1. Установка

    npx create-react-app juejin-react-h5(你的项目名称)

2. Далее устанавливаем соответствующие зависимости

    // 安装基本UI库andt-mobile
    yarn add antd-mobile
    // 安装 react-app-rewired customize-cra 用来添加webpack相关配置,
    // 这俩个包应为不用打包在项目中,所以只需要安装在开发环境就好了
    yarn add react-app-rewired customize-cra -D
    // babel-plugin-import这个是分包工具
    yarn add babel-plugin-import -D

3. Изменитьpackage.jsonэлемент запуска

     {
        "start": "react-app-rewired start",
        "build": "react-app-rewired build",
        "test": "react-app-rewired test --env=jsdom",
        "eject": "react-scripts eject"
      }

4. Создайте проект в корневом каталоге проекта.config-overrides.jsИспользуется для изменения конфигурации по умолчанию

const { override, fixBabelImports }  = require("customize-cra")

module.exports = override(
    fixBabelImports("import", {
      libraryName: 'antd-mobile',
      style: 'css',
    })
)

5. Измените app.js

import { Button } from 'antd-mobile'

function App() {
  return (
    <div className="App">
      <Button type="primary">按钮</Button>
    </div>
  );
}

export default App;

6. Запустите проект и получите доступlocalhost:3000

 yarn start

7. Откройте страницу и переключитесь в режим мобильной разработки, чтобы увидеть визуализацию.

tu1.png

8. Затем мы устанавливаем инструмент прекомпиляции css (выберите здесь sass)

yarn add sass

9. Затем мы создаем новый файл app.scss под src и пишем несколько тестовых css

.p{
    color: red;
    width: 750px;
}

10. Наконец, добавьте app.scss в app.js и перезапустите проект.

Когда мы увидели этот рендеринг, sass был успешно внедрен.

sass.png

11. Настройте глобальные переменные sass

    //先安装一个loader 和 path
    yarn add sass-resources-loader path -D
    const resolve = _path => path.resolve(__dirname, _path)
    module.exports = override(
        fixBabelImports('import', {
            libraryName: 'antd-mobile',
            style: 'css',
        }),
        adjustStyleLoaders(rule => {
            if (rule.test.toString().includes('scss')) {
              rule.use.push({
                loader: require.resolve('sass-resources-loader'),
                options: {
                  resources: [resolve("./src/styles/theme.scss")]
                }
              });
            }})
           )
  • Далее мы создаем файл theme.scss и пишем переменную цвета
    $red: red;
  • Мы можем использовать его в app.scss
    .p{
        color: $red;
        width: 750px;
    }
  • Эффект все равно хороший

sass.png

12. Далее ставим блокpxПеревести вvwБар

    //安装 postcss-px-to-viewport
    yarn add postcss-px-to-viewport -D

13. Далее мы изменимconfig-overrides.jsкод в

const { override, fixBabelImports, addPostcssPlugins }  = require("customize-cra")

module.exports = override(
    fixBabelImports('import', {
        libraryName: 'antd-mobile',
        style: 'css',
    }),
    adjustStyleLoaders(rule => {
            if (rule.test.toString().includes('scss')) {
              rule.use.push({
                loader: require.resolve('sass-resources-loader'),
                options: {
                  resources: [resolve("./src/styles/theme.scss")]
                }
              });
            }}),
    addPostcssPlugins([
        require("postcss-px-to-viewport")({
            unitToConvert: 'px',  // 需要转换的单位,默认‘px’
            viewportWidth: 750,   // 设计稿的视口宽度
            unitPrecision: 6,     // px转vw之后保留的精度(保留几位小数)
            propList: ['*'],      // 那些属性可以被转换成vw * 代表全部
            viewportUnit: 'vw',   // 希望使用的视口单位 // vw
            fontViewportUnit: 'vw', //字体使用的视口单位
            selectorBlackList: [],  // 需要忽略的CSS选择器,不会转为视口单位,使用原有的px等单位
            minPixelValue: 1,       // 设置最小的转换数值,如果为1的话,只有大于1的值会被转换
            mediaQuery: false,      // 媒体查询里的单位是否需要转换单位
            replace: true,          // 是否直接更换属性值,而不添加备用属性
            exclude: [/node_modules/], // 忽略某些文件夹下的文件或特定文件,例如 'node_modules' 下的文件
            landscape: false,       // 是否添加根据 landscapeWidth 生成的媒体查询条件 @media (orientation: landscape)
            landscapeUnit: 'vw'     // 横屏时使用的单位
        })
    ])
)

14. Когда мы снова запустим проект, мы увидим, что 750px в теге p были изменены на 100vw (поскольку ширина нашего окна просмотра установлена ​​на 750)

image.png

15. ДобавитьLodashБиблиотека инструментов для загрузки по требованию

    yarn add lodash
    // config-overrides.js 中添加 lodash 按需加载
    fixBabelImports("lodash", {
        libraryDirectory: "",
        camel2DashComponentName: false
    })

16. Добавить@псевдоним

  • В Vue мы часто пишем@/xx/xx, вы можете настроить его так в CRA
    
    const path = require("path")
    const { override, fixBabelImports, addPostcssPlugins, addWebpackAlias }  = require("customize-cra")
    const resolve = dir => path.resolve(__dirname, dir)
    module.exports = override(
    fixBabelImports('import', {
        libraryName: 'antd-mobile',
        style: 'css',
    }),
        addWebpackAlias({
            ["@"]: resolve("./src")
        }),
        addPostcssPlugins([
            require("postcss-px-to-viewport")({
                unitToConvert: 'px',  // 需要转换的单位,默认‘px’
                viewportWidth: 750,   // 设计稿的视口宽度
                unitPrecision: 6,     // px转vw之后保留的精度(保留几位小数)
                propList: ['*'],      // 那些属性可以被转换成vw * 代表全部
                viewportUnit: 'vw',   // 希望使用的视口单位 // vw
                fontViewportUnit: 'vw', //字体使用的视口单位
                selectorBlackList: [],  // 需要忽略的CSS选择器,不会转为视口单位,使用原有的px等单位
                minPixelValue: 1,       // 设置最小的转换数值,如果为1的话,只有大于1的值会被转换
                mediaQuery: false,      // 媒体查询里的单位是否需要转换单位
                replace: true,          // 是否直接更换属性值,而不添加备用属性
                exclude: [/node_modules/], // 忽略某些文件夹下的文件或特定文件,例如 'node_modules' 下的文件
                landscape: false,       // 是否添加根据 landscapeWidth 生成的媒体查询条件 @media (orientation: landscape)
                landscapeUnit: 'vw'     // 横屏时使用的单位
            })
        ])
)

17. Работа с несколькими доменами

  • В процессе совместной отладки интерфейса с нашими back-end партнерами будут междоменные проблемы.Конфигурация CRA выглядит следующим образом
const path = require("path");

const { override,
    fixBabelImports,
    addWebpackAlias,
    addPostcssPlugins,
    overrideDevServer } = require('customize-cra');

const resolve = _path => path.resolve(__dirname, _path)

module.exports = {
    webpack: override(
        fixBabelImports('import', {
            libraryName: 'antd-mobile',
            style: 'css',
        }),
        fixBabelImports("lodash", {
            libraryDirectory: "",
            camel2DashComponentName: false
        }),
        addWebpackAlias({
            ['@']: resolve("./src")
        }),
        addPostcssPlugins([
            require("postcss-px-to-viewport")({
                unitToConvert: 'px',  // 需要转换的单位,默认‘px’
                viewportWidth: 750,   // 设计稿的视口宽度
                unitPrecision: 6,     // px转vw之后保留的精度(保留几位小数)
                propList: ['*'],      // 那些属性可以被转换成vw * 代表全部
                viewportUnit: 'vw',   // 希望使用的视口单位 // vw
                fontViewportUnit: 'vw', //字体使用的视口单位
                selectorBlackList: [],  // 需要忽略的CSS选择器,不会转为视口单位,使用原有的px等单位
                minPixelValue: 1,       // 设置最小的转换数值,如果为1的话,只有大于1的值会被转换
                mediaQuery: false,      // 媒体查询里的单位是否需要转换单位
                replace: true,          // 是否直接更换属性值,而不添加备用属性
                exclude: [/node_modules/], // 忽略某些文件夹下的文件或特定文件,例如 'node_modules' 下的文件
                landscape: false,       // 是否添加根据 landscapeWidth 生成的媒体查询条件 @media (orientation: landscape)
                landscapeUnit: 'vw'     // 横屏时使用的单位
            })
        ])
    ),

    devServer: overrideDevServer([
        config => ({
            ...config,
            proxy: {
                "/api": {
                    target: "http://localhost:4444",
                    pathRewrite: { "^/api": "" }
                }
            }
        })
    ]),
}
  • на этот раз, когда мы посещаем/apiКогда интерфейс начинается с , адрес запроса будет проксирован наhttp://localhost:4444
  • 🌰/api/testбудет представлен какhttp://localhost:4444/test

18. Проблема с реальной машиной

  • Сначала измените нашapp.jsа такжеapp.scss
  • Мы добавили 50 тегов p на страницу для тестирования
    import { Button } from 'antd-mobile'
    import '@/app.scss'

    function App() {
      return (
        <div className="App">
          {
            Array(50).fill(1).map((item, idx) => (<p className="p" key={idx}>一段自定义的css样式文字,第{idx}条</p>))
          }
          <Button type="primary">按钮</Button>
        </div>
      );
    }

    export default App;
  • Затем мы очищаемpполя этикетки
.p{
    color: red;
    width: 750px;
    margin: 0;
    padding: 0;
}
  • Затем мы используем мобильный телефон для подключения к Wi-Fi, соответствующему компьютеру, и получаем доступ к IP-адресу компьютера.
    输入 ifconfig

image.png

  • Затем используйте телефон открытымhttp://10.5.9.250:3000/, вы можете увидеть нашу страницу

image.png

  • В это время мы видим, что кнопка мобильного телефона (iphoneX) заблокирована маленькой черной полосой внизу
  • Решение
    • Найдите тег сопряжения public/index.html и добавьте атрибут viewport-fit=cover. <meta name="viewport" content="width=device-width, initial-scale=1,viewport-fit=cover" />
    • тело добавить CSS, как это
      body {
          padding-bottom: constant(safe-area-inset-bottom);
          padding-bottom: env(safe-area-inset-bottom);
        }
    
  • Затем перезапускаем проект и еще раз проверяем на реальной машине

image.png

  • В это время маленькая черная полоса внизу не будет блокировать кнопку.

19. Полный код

  • package.json
{
  "name": "juejin-react-h5",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@testing-library/jest-dom": "^5.11.4",
    "@testing-library/react": "^11.1.0",
    "@testing-library/user-event": "^12.1.10",
    "antd-mobile": "^2.3.4",
    "path": "^0.12.7",
    "react": "^17.0.2",
    "react-dom": "^17.0.2",
    "react-scripts": "4.0.3",
    "sass": "^1.34.1",
    "web-vitals": "^1.0.1"
  },
  "scripts": {
    "start": "react-app-rewired start",
    "build": "react-app-rewired build",
    "test": "react-app-rewired test --env=jsdom",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ]
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  },
  "devDependencies": {
    "babel-plugin-import": "^1.13.3",
    "customize-cra": "^1.0.0",
    "postcss-px-to-viewport": "^1.1.1",
    "react-app-rewired": "^2.1.8",
    "sass-resources-loader": "^2.2.1"
  }
}

  • config-overrides.js
const path = require("path");

const { override,
    fixBabelImports,
    addWebpackAlias,
    addPostcssPlugins,
    adjustStyleLoaders,
    overrideDevServer } = require('customize-cra');

const resolve = _path => path.resolve(__dirname, _path)

module.exports = {
    webpack: override(
        // antd-mobile 分包
        fixBabelImports('import', {
            libraryName: 'antd-mobile',
            style: 'css',
        }),
        // lodash分包
        fixBabelImports("lodash", {
            libraryDirectory: "",
            camel2DashComponentName: false
        }),
        //别名
        addWebpackAlias({
            ['@']: resolve("./src")
        }),
        // 添加loader 全局css
        adjustStyleLoaders(rule => {
            if (rule.test.toString().includes('scss')) {
              rule.use.push({
                loader: require.resolve('sass-resources-loader'),
                options: {
                  resources: [resolve("./src/styles/theme.scss")]
                }
              });
            }}),
            // px转 vw
        addPostcssPlugins([
            require("postcss-px-to-viewport")({
                unitToConvert: 'px',  // 需要转换的单位,默认‘px’
                viewportWidth: 750,   // 设计稿的视口宽度
                unitPrecision: 6,     // px转vw之后保留的精度(保留几位小数)
                propList: ['*'],      // 那些属性可以被转换成vw * 代表全部
                viewportUnit: 'vw',   // 希望使用的视口单位 // vw
                fontViewportUnit: 'vw', //字体使用的视口单位
                selectorBlackList: [],  // 需要忽略的CSS选择器,不会转为视口单位,使用原有的px等单位
                minPixelValue: 1,       // 设置最小的转换数值,如果为1的话,只有大于1的值会被转换
                mediaQuery: false,      // 媒体查询里的单位是否需要转换单位
                replace: true,          // 是否直接更换属性值,而不添加备用属性
                exclude: [/node_modules/], // 忽略某些文件夹下的文件或特定文件,例如 'node_modules' 下的文件
                landscape: false,       // 是否添加根据 landscapeWidth 生成的媒体查询条件 @media (orientation: landscape)
                landscapeUnit: 'vw'     // 横屏时使用的单位
            })
        ])
    ),
// 本地开发相关
    devServer: overrideDevServer([
        config => ({
            ...config,
            proxy: {
                "/api": {
                    target: "http://localhost:4444",
                    pathRewrite: { "^/api": "" }
                }
            }
        })
    ]),
}

20. Адрес проектаGitHub.com/Tcloth2345/Сон…

использованная литература

напиши в конце

  • Когда вы это видите, во-первых, вы очень настойчивый человек.В этой статье нет иллюстраций, это все работа.Если вы прочитали ее от начала до конца, поставьте себе лайк.
  • В этой статье в основном создается полка React H5, от макета до стиля и переадресации интерфейса, основные функции были построены.
  • Приветствую всех, кто комментирует и указывает на недостатки