create-react-app搭建vw-layout解決方案

發表於2019-04-04

create-react-app搭建vw-layout解決方案

前言:我第一次接觸到vw適配移動端的方案是在大漠先生的部落格裡(如何在Vue專案中使用vw實現移動端適配),強烈建議沒看過的朋友先去看一下這篇部落格。vw解決方案早有耳聞,我也很想上手嘗試一下,所以想要自己上手配置一個CRA腳手架的解決方案。在自己動手之前也先查了一些資料,其中Ghan的這篇部落格很有幫助:使用create-react-app腳手架搭建vw-layout解決方案。和Ghan的方案不同,我研究了下決定藉助react-app-rewired來搭建。下面把我的配置過程寫在這裡,有什麼不對的地方歡迎批評,小白第一次配,求輕拍。

先上一些背景資料。主要用到以下幾個工具:
react-app-rewired:一個CRA再配置的工具,源自React社群,可以在不eject的情況下自定義配置CRA腳手架建立的app。原理很簡單,在專案根目錄下新建一個配置檔案(config-overrides.js),把webpack的配置作為一個config物件傳入react-app-rewired,再用config-overrides中的配置對其做修改,然後用修改後的config物件對專案打包。
react-app-rewire-postcss:一個react-app-rewired中使用的postcss-loader。通過在config-overrides.js中載入這個loader並自定義配置,從而實現修改CRA預設配置的目的。

除此之外還要用到幾個常規外掛:
cssnano-preset-advanced
postcss-aspect-ratio-mini
postcss-px-to-viewport
postcss-write-svg
cssnano
postcss-viewport-units
postcss-flexbugs-fixes
postcss-preset-env

其中,postcss-flexbugs-fixes、postcss-preset-env是目前版本CRA的預設配置,就不做過多的解釋了;由於cssnano的配置中使用了preset: "advanced"配置,需要安裝cssnano-preset-advanced包;zhipostcss-aspect-ratio-mini、postcss-px-to-viewport、postcss-write-svg、cssnano、postcss-viewport-units這幾個外掛是這個方案的核心,大漠先生已經做了非常詳細的解釋,強烈建議大家去看大漠的這篇文章。

開始

構建

create-react-app vwpage複製程式碼

安裝依賴

yarn add postcss-aspect-ratio-mini postcss-px-to-viewport postcss-write-svg postcss-viewport-units cssnano cssnano-preset-advanced react-app-rewired postcss-preset-env --dev
//使用yarn作為包管理工具,習慣npm的朋友也可以用npm複製程式碼

這裡簡單說明一下,大漠先生的教程中提到的postcss-cssnext已經停止維護了,整合進了postcss-preset-env這個專案中,因此不需要再安裝postcss-cssnext了,具體資訊參見該專案github。

react-app-rewired配置

在專案根目錄下新建config-overrides.js檔案。內容如下:

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

安裝react-app-rewire-postcss Loaders

yarn add react-app-rewire-postcss --dev複製程式碼

配置config-overrides.js

module.exports = function override(config, env) {
    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;
}複製程式碼

相容方案

大漠老師在部落格中提到了Viewport Units Buggyfill作為相容工具,我簡單看了下這個專案的gitHub介紹,這是一個buggyfill,主要是修復某些瀏覽器中關於viewport實現的bug,而不是作為polyfill在完全不支援viewport的瀏覽器中來實現它。

1.引入JavaScript檔案:
viewport-units-buggyfill主要有兩個JavaScript檔案:viewport-units-buggyfill.js和viewport-units-buggyfill.hacks.js。你只需要在你的HTML檔案中引入這兩個檔案。比如在react專案中的index.html引入它們:

<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>複製程式碼

2.在body中加入以下程式碼:

<script> 
    window.onload = function () {
        window.viewportUnitsBuggyfill.init({
            hacks: window.viewportUnitsBuggyfillHacks
        }); 
    } 
</script>
複製程式碼

One more thing

修改專案package.json中的npm scripts:

  /* package.json */

  "scripts": {
-   "start": "react-scripts start",
+   "start": "react-app-rewired start",
-   "build": "react-scripts build",
+   "build": "react-app-rewired build",
-   "test": "react-scripts test --env=jsdom",
+   "test": "react-app-rewired test --env=jsdom"
}複製程式碼


相關文章