create-react-app+antd-mobile+less+viewport环境搭建

写下此文章的初衷:最近项目需要架构升级,然而由于create-react-app升级到@2.x的原因,又因为想享受CRA升级带来的便利,不想eject项目,所以任何不想eject的同学,都可以了解一下这篇文章,开始我们的旅途吧

简介:本文共分为4部分,第一部分安装create-react-app,第二部分安装ant-mobile,第三部分:安装less,第四部分安装viewport各部分依赖

一、项目基础,安装create-react-app脚手架,创建create-react-app项目my-app

1、在全局环境安装create-react-app工具

在任意文件夹执行以下命令:

npm isntall -g create-react-app
2、用create-react-app工具创建我的第一个项目my-app

进入放置项目my-app的文件夹,执行以下命令:

/**创建项目my-app,并进入项目my-app文件夹*/
create-react-app my-app && cd my-app

启动我的项目my-app只需执行命令:

npm start

到这一步,其实你已经完成react大部的插件的安装,像一些:热更新、webpack、css babel等等,详细可以了解create-react-app工具。

二、安装项目UI 组件库:Ant Design Mobile

1、安装antd-mobile
npm install antd-mobile --save
2、完成component、css按需加载需要一些配置插件

引入 react-app-rewired 并修改 package.json 里的启动配置。。由于新的 react-app-rewired@2.x 版本的关系,你需要还需要安装 customize-cra。

npm install react-app-rewired customize-cra --save-dev
/* package.json */
  "scripts": {
    "start": "set PORT=3006 && react-app-rewired start",
    "build": "react-app-rewired build",
    "test": "react-app-rewired test --env=jsdom",
    "eject": "react-scripts eject"
  },

然后在项目根目录创建一个 config-overrides.js 用于修改默认配置。

module.exports = function override(config, env) {
  // do stuff with the webpack config...
  return config;
};

使用 babel-plugin-import, babel-plugin-import 是一个用于按需加载组件代码和样式的 babel 插件,现在我们尝试安装它并修改 config-overrides.js 文件。

npm install babel-plugin-import --save-dev
+ const { override, fixBabelImports } = require('customize-cra');

- module.exports = function override(config, env) {
-   // do stuff with the webpack config...
-   return config;
- };
+ module.exports = override(
+   fixBabelImports('import', {
+     libraryName: 'antd-mobile',
+     style: 'css',
+   }),
+ );

完成后,按需引入一个Button

import { Button } from 'antd-mobile';
...
    <Button type="primary">primary</Button>
...

彩蛋:当项目启动之后,你会发现是在port:3000端口运行的,如果需要换成其他端口,在my-app文件夹下,找到package.json文件,把

"start": "react-app-rewired start",

改成(在端口3006执行):

"start": "set PORT=3006 && react-app-rewired start",

到这一步之后,如无需less和lib-flexible开发的同学,已经可以在my-app项目尽情开发啦,赶紧体验一把热更新带来的便捷吧!

但是我们一般都不满足的,css那种语言,怎么看都不像是程序,于是,less、sass、stylus这三个css预处理器就横空出世了,在本文中,我们重点了解less在create-react-app和ant-mobile环境下的安装。

三、安装less!

依旧的,进入my-app项目目录

安装less和less-loader

npm install less less-loader --save-dev

安装react-app-rewire-less来修改less配置:

npm i react-app-rewire-less --save

修改config-overrides.js文件为:

const { override, fixBabelImports, addLessLoader } = require('customize-cra');
const rewireLess = require('react-app-rewire-less');

module.exports = override(
  fixBabelImports('import', {
    libraryName: 'antd',
    libraryDirectory: 'es',
    style: true,
  }),
  addLessLoader({
    javascriptEnabled: true,
    //modifyVars: { '@primary-color': '#1DA57A' }, // 这里不注释掉,那你的无法修改主题色primary-color 这里很坑的 要注意!
  }),
);

继续修改App.css文件名为:App.less

修改App.js文件:

import './App.css';

import './App.less';

启动my-app,如果看到正常页面,则less加入成功。

四、添加viewport移动端自适应方案

viewport是lib-flexible方案的升级版,同学们可以了解:https://github.com/amfe/lib-flexible/

1、安装postCss插件
npm i --save postcss-aspect-ratio-mini postcss-px-to-viewport postcss-write-svg postcss-cssnext postcss-viewport-units cssnano cssnano-preset-advanced

再安装react-app-rewire-postcss支持config-overrides重写:

npm i react-app-rewire-postcss --save
2.安装完成后,在config-overrides.js加入postCss配置
const addCustomize = () => config => {
  require('react-app-rewire-postcss')(config, {
        plugins: loader => [
            require('postcss-flexbugs-fixes'),
            require('postcss-preset-env')({
                autoprefixer: {
                    flexbox: 'no-2009',
                },
                stage: 3,
            }),
            require('postcss-aspect-ratio-mini')({}),
            require('postcss-px-to-viewport')({
                viewportWidth: 750, // (Number) The width of the viewport.
                viewportHeight: 1334, // (Number) The height of the viewport.
                unitPrecision: 3, // (Number) The decimal numbers to allow the REM units to grow to.
                viewportUnit: 'vw', // (String) Expected units.
                selectorBlackList: ['.ignore', '.hairlines'], // (Array) The selectors to ignore and leave as px.
                minPixelValue: 1, // (Number) Set the minimum pixel value to replace.
                mediaQuery: false // (Boolean) Allow px to be converted in media queries.
            }),
            require('postcss-write-svg')({
                utf8: false
            }),
            require('postcss-viewport-units')({}),
            require('cssnano')({
                preset: "advanced",
                autoprefixer: false,
                "postcss-zindex": false
            })
        ]
    });
  return config;
}

此时config-overrides.js,整个配置如下:

const { override, fixBabelImports, addLessLoader } = require('customize-cra');
const rewireLess = require('react-app-rewire-less');


const addCustomize = () => config => {
  require('react-app-rewire-postcss')(config, {
        plugins: loader => [
            require('postcss-flexbugs-fixes'),
            require('postcss-preset-env')({
                autoprefixer: {
                    flexbox: 'no-2009',
                },
                stage: 3,
            }),
            require('postcss-aspect-ratio-mini')({}),
            require('postcss-px-to-viewport')({
                viewportWidth: 750, // (Number) The width of the viewport.
                viewportHeight: 1334, // (Number) The height of the viewport.
                unitPrecision: 3, // (Number) The decimal numbers to allow the REM units to grow to.
                viewportUnit: 'vw', // (String) Expected units.
                selectorBlackList: ['.ignore', '.hairlines'], // (Array) The selectors to ignore and leave as px.
                minPixelValue: 1, // (Number) Set the minimum pixel value to replace.
                mediaQuery: false // (Boolean) Allow px to be converted in media queries.
            }),
            require('postcss-write-svg')({
                utf8: false
            }),
            require('postcss-viewport-units')({}),
            require('cssnano')({
                preset: "advanced",
                autoprefixer: false,
                "postcss-zindex": false
            })
        ]
    });
  return config;
}

module.exports = override(
  fixBabelImports('import', {
    libraryName: 'antd-mobile',
    libraryDirectory: 'es',
    style: true,
  }),
  addLessLoader({
    javascriptEnabled: true,
    //modifyVars: { '@primary-color': '#1DA57A' }, # 这里不注释掉,那你的无法修改主题色primary-color 这里很坑的 要注意!
  }),
  addCustomize(),
);
3、引入阿里cdn

在<head></head>中引入阿里cdn

<script src="//g.alicdn.com/fdilab/lib3rd/viewport-units-buggyfill/0.6.2/??viewport-units-buggyfill.hacks.min.js,viewport-units-buggyfill.min.js"></script>

在body中,加入如下js代码:

<script>
  window.onload = function () {
    window.viewportUnitsBuggyfill.init({
      hacks: window.viewportUnitsBuggyfillHacks
    });
  }
</script>

最终index.html如下

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico" />
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <meta name="theme-color" content="#000000" />
    <!--
      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>
    <script src="//g.alicdn.com/fdilab/lib3rd/viewport-units-buggyfill/0.6.2/??viewport-units-buggyfill.hacks.min.js,viewport-units-buggyfill.min.js"></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`.
    -->
    <script>
      window.onload = function () {
        window.viewportUnitsBuggyfill.init({
          hacks: window.viewportUnitsBuggyfillHacks
        });
      }
    </script>
  </body>
</html>

重新执行npm start打开页面,在style:.App下面发现:

content: "viewport-units-buggyfill; width: 100vw; height: 26.667vw; line-height: 26.667vw";
//如果遇到img无法显示,则添加全局css
img { 
    content: normal !important; 
}

至此,恭喜你,你手上已经多了一个可以自适应移动端+less+antd-mobile项目了,尽情发挥你的才能吧

项目地址:https://github.com/wihtebox/my-app

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,088评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,715评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,361评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,099评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 60,987评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,063评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,486评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,175评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,440评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,518评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,305评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,190评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,550评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,880评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,152评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,451评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,637评论 2 335

推荐阅读更多精彩内容