如何在create-react-app專案中使用vw實現手淘vw移動端適配佈局

混元霹靂手發表於2018-01-30

2018年是我感覺是前端的外掛年,在css方面,postcss的外掛也是剛剛的,無論是autoprefixer,還是postcss-cssnext等一系列方面,今天剛好做一個移動端新專案,特意請教了手淘團隊,出了一個新方案,開始拋棄使用Flexible實現手淘H5頁面的終端適配,使用vw佈局方案,關於vue-cli使用的配置已經有講解,我就講講create-react-app的配置

具體的內容原因請下以面連結

w3cplus vm佈局

配置方面就不用說了,如何用creat-react-app生成一個專案,執行起來,請看以下連結

https://reactjs.org/docs/forms.html

直接進入如何配置

生成專案後,直接進行 webpack.config.dev.js,配置開發環境配置找到這段程式碼

              {
                loader: require.resolve('postcss-loader'),
                options: {
                  config: {
                    path: 'postcss.config.js'  // 這個得在專案根目錄建立此檔案
                  },
                  // Necessary for external CSS imports to work
                  // https://github.com/facebookincubator/create-react-app/issues/2677
                  ident: 'postcss'
                  // plugins: () => [
                  //   require('postcss-flexbugs-fixes'),
                  //   autoprefixer({
                  //     browsers: [
                  //       '>1%',
                  //       'last 4 versions',
                  //       'Firefox ESR',
                  //       'not ie < 9', // React doesn't support IE8 anyway
                  //     ],
                  //     flexbox: 'no-2009',
                  //   }),
                  // ],
                },
              },
複製程式碼

create-react-app 自己配置了,內聯的autoprefixer,把它注示掉,然後在options里加指向的配置地址,把所有的plugins外掛配置全放入一個在專案根目標的postcss.config.js,通過postcss解析的時候自然會執行這些差件,因為運用大量的配置,在生產環境同樣要同到,進行一個共同配置。

在配置之前先下一些包

npm i postcss-aspect-ratio-mini postcss-px-to-viewport postcss-write-svg postcss-cssnext postcss-viewport-units cssnano cssnano-preset-advanced --D
複製程式碼

postcss.config.js配置


module.exports = {
    "plugins": [
        require('postcss-flexbugs-fixes'),
        require("autoprefixer")({
            browsers: [
                '>1%',
                'last 4 versions',
                'Firefox ESR',
                'not ie < 9', // React doesn't support IE8 anyway
            ],
            flexbox: 'no-2009',
        }),
        require("postcss-aspect-ratio-mini"),
        require("postcss-write-svg")({ utf8: false }),
        require("postcss-cssnext"),
        require("postcss-px-to-viewport")({
            viewportWidth: 750,
            viewportHeight: 1334,
            unitPrecision: 3,
            viewportUnit: 'vw',
            selectorBlackList: ['.ignore', '.hairlines'],
            minPixelValue: 1,
            mediaQuery: false
        }),
        require("postcss-viewport-units"),
        require("cssnano")({
            preset: "advanced",
            autoprefixer: false,
            "postcss-zindex": false
        })

    ]
}
複製程式碼

以上的配置原理還是請到 w3cplus vm佈局

require('postcss-flexbugs-fixes'),
        require("autoprefixer")({
            browsers: [
                '>1%',
                'last 4 versions',
                'Firefox ESR',
                'not ie < 9', // React doesn't support IE8 anyway
            ],
            flexbox: 'no-2009',
        }),
複製程式碼

為了不破壞整體性還是把create-react-app原本的差件搬過來。關於postcss的配置就結束了

改一下public/index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <meta name="theme-color" content="#000000">
    <!--
      manifest.json provides metadata used when your web app is added to the
      homescreen on Android. See https://developers.google.com/web/fundamentals/engage-and-retain/web-app-manifest/
    -->
    <link rel="manifest" href="%PUBLIC_URL%/manifest.json">
    <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
    <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>
    <!--
      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>
  </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
        });

        var winDPI = window.devicePixelRatio;
            var uAgent = window.navigator.userAgent;
            var screenHeight = window.screen.height;
            var screenWidth = window.screen.width;
            var winWidth = window.innerWidth;
            var winHeight = window.innerHeight;
            alert(
                "Windows DPI:" + winDPI +
                ";\ruAgent:" + uAgent +
                ";\rScreen Width:" + screenWidth +
                ";\rScreen Height:" + screenHeight +
                ";\rWindow Width:" + winWidth +
                ";\rWindow Height:" + winHeight
            )
      }
    </script>
  </body>
</html>

複製程式碼

引入 viewport-units-buggyfill.hacks的ali cdn 再初始化執行init方法

ok此時配置完成,執行 npm start

注意幾點: viewportWidth: 750 可以當作是iphone6的視口度,你的設計圖也要是750的比例,也是移動端的標準設計比。正常的用px,最後會/2進行一個比例換算。

解決安桌機0.5px線的問題,需要通過postcss-write-svg,對於我這種不懂svg的,是一個很奇秒的設計, 示例請看原作者。

當你寫好之後,發現chrome 控制檯是換成了vw,就是成功了,如果設定了最小轉化值minPixelValue: 1,說明小於等於1px的不進行vw的轉換。

在生產環境webpack.production.config.js中,與dev也是同樣的配置。

感謝手淘團隊,感w3cPlus 大漠

相關文章