Nextフレームワークと主流ツールの統合(二)-完備と最適化


前言:18年12月24日にプロジェクトがオンラインに成功し、2週間のオンラインバグ、UI、コードの最適化を経て、多くの問題を解決したので、このプロジェクトを改善し、最適化します.
  • レイアウト最適化
  • HD構成
  • antd-mobileカスタム構成
  • antd-mobile Toastコンポーネントパッケージ
  • レイアウトの最適化
    レイアウトの最適化はこの文章で完了しました→[モバイルエンドの優雅なレイアウトの実践]()最後に私が使用した案は--absoluteがドキュメントフローから離れている(利点は容器を設置するheight: 100%,htmlウィンドウの高さを直接継承できる)ことです.
    HD構成
    問題の発見
    プロジェクトを開始する前にdpr(device pixel radio)とスケールについてあまり理解しておらず、プロジェクト開発時に直接1として書きました.その後、UIが検収されたとき、UIデザイナーが予想した細線効果が実現していないことが分かった.私はこの問題を解決する時、dprの紹介を真剣に見に行きました.このdprを詳しく解く文章はまあまあだ.
    概念的に、dprは、デバイスの物理画素とデバイス独立画素(すなわち、css論理画素、以下、css論理画素と呼ぶ)との比率である.
    例えば、iPhone 6の解像度は750*1334、window.screen.width(css論理画素)は375なので
    dpr = 750 /375 = 2

    例えば、iPhone Xの解像度は1125*2436、window.screen.width(css論理画素)も375なので、
    dpr = 1125 /375 = 3

    ではdprは何の役に立つのでしょうか.
    その前に、モバイル側に必要なmetaラベルについて説明します.

    device-widthはhtmlにおいても同様に理想(基準)ビューポートの幅、すなわち320 px,375 px,414 pxと解読され、ここでpxはcss画素を指し、通常は論理画素とも呼ばれる.html中のcss画素の表示サイズはNA中のpt,dpの表示サイズと等しいと考えられる.
    このmetaタグにより、initial-scale=1初期スケーリング100%を実現することができ、1px css = 1pxに達することができ、言い換えればbody { width: 375px; }はiPhone 6上で縦画面全体の幅を満たすことができる.
    では、問題は来て、もし私たちが箱に1 pxの細い線を加えるならば:border-bottom: 1px solid red;です.ではiPhone 6では本当に1 pxなのでしょうか?
    iPhone 6本体のスクリーンショット(幅702 px):
    高さは明らかに1画素以上であることがわかる.これは、iPhone 6のdprが2であり、スケールが100%であるため、1 pxのcssが2 px物理画素としてレンダリングされるため、dprによるものである.
    これが私たちのUIのもちもちと製品たちが満足していないところです.
    では、次はどうやってこの問題を解決しますか?
    ソリューション
    スケーリングスケールは、デバイスのdprに基づいて動的に計算され、ルートノードのfont-sizeである.
    // rem.js
    (function(doc, win) {
      var docEl = doc.documentElement,
        dpr = Math.min(win.devicePixelRatio, 3);
      dpr = window.top === window.self ? dpr : 1; // iframe   ,    
      var scale = 1 / dpr,
        resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize';
      docEl.dataset.dpr = dpr;
      var metaEl = doc.createElement('meta');
      metaEl.name = 'viewport';
      metaEl.content =
        'initial-scale=' +
        scale +
        ',maximum-scale=' +
        scale +
        ', minimum-scale=' +
        scale +
        ',user-scalable=no,viewport-fit=cover';
      docEl.firstElementChild.appendChild(metaEl);
      var recalc = function() {
        var width = docEl.clientWidth;
        //   1280 1280  
        if (width / dpr > 1280) {
          width = 1280 * dpr;
        }
        // px : rem = 100 : 1
        docEl.style.fontSize = 100 * (width / 375) + 'px';
      };
      recalc();
      if (!doc.addEventListener) return;
      win.addEventListener(resizeEvt, recalc, false);
    })(document, window);
    

    リッチテキスト要素が表示されている場合は、リッチテキスト要素のスタイルを処理する必要があります.
    モバイル端末は異なる機種に適しているため、rem単位を使用するのは良い選択であり、私たちもずっとそれを使用しています.
    ここでは、dprに基づいてinitial-scaleを計算するほか、ルートノードのfont-sizeを調整し、スケーリング時にウィンドウサイズに復元できるようにした(スケーリングするため、remの基数を相応に増やす).
    このように私たちが書いたborder-bottom: 1px solid red;は、このスキームでこのように表示されています.
    わあ、カカカ、明らかに細くなったことがわかります.これこそ私たちのUIもちたちが望んでいるO(∩∩)O~~
    しかし,このような設定は,ant-design-mobileを結合すると,ant-design-mobileのコンポーネントが縮小されていることが分かった.もともと、その要素はpx単位で、私たちはスケールする前にその最小単位に対応する基数を乗じていませんでした.では、基数を構成する必要があります.
    antd-mobileカスタム構成
    ドキュメントを調べると、ant-design-mobileはトピック構成を提供し、@hdの変数を長さの基本単位として提供し、デフォルト値は1pxです.
    私たちは@hd0.01remに設定するだけで問題を解決することができます.
    このトピックで構成されたドキュメントは、webpackプロジェクトの例です.では、どのようにしてnext.jsプロジェクトでカスタム構成を完了しますか?
    私はnextにいます.jsのexamplesには私の必要なexampleは見つかりませんでしたが、2つの関連例が見つかりました.1つはwith-antd-mobileで、1つはwith-ant-design-lessです.2つ目はant-designのカスタムトピック構成であり、このexampleに倣ってwith-antd-mobileのカスタムトピック構成を追加することができるはずです.
    ここで、このwith-antd-mobileは、Nextフレームワークと主流ツールの統合を書いた後に更新されました.next.config.jsの構成は、ここでも最新の構成に変更されています.
  • インストール解析Lessとnormalize.cssのパッケージ
  • npm i @zeit/next-less @zeit/next-css less less-vars-to-js -S
  • 修正.babelrc構成
  • {
      "presets": ["next/babel"],
      "plugins": [
        [
          "import",
          {
            "libraryName": "antd-mobile",
            "style": true
          }
        ]
      ]
    }
    
  • 修正next.config.js構成
  • /* eslint-disable */
    const withCSS = require('@zeit/next-css');
    const withSass = require('@zeit/next-sass');
    const withLess = require('@zeit/next-less');
    const lessToJS = require('less-vars-to-js');
    const fs = require('fs');
    const path = require('path');
    
    // Where your antd-custom.less file lives
    const themeVariables = lessToJS(fs.readFileSync(path.resolve(__dirname, './antd-custom.less'), 'utf8'));
    
    // fix: prevents error when .less files are required by node
    if (typeof require !== 'undefined') {
      require.extensions['.less'] = file => {};
      require.extensions['.css'] = file => {};
    }
    
    module.exports = withCSS(
      withLess(
        withSass({
          lessLoaderOptions: {
            javascriptEnabled: true,
            modifyVars: themeVariables
          }
        })
      )
    );
    
  • プロジェクトの下で新しいLess変数ファイルantd-custom.less
  • @hd: 0.01rem;

    プロジェクトを再起動すると、大成功になります.
    antd-mobile Toastコンポーネントパッケージantd-mobileToast.info()コンポーネントが表示されている間に背景をクリックできずに消えてしまい、オリジナルのToastとは少し違いますが、体験のためにここでもう1層パッケージを作り、背景をクリックしている間にToastを隠すようにしました.
    // utils/toast.js
    static info = (content, duration, onClose, mask) => {
        Toast.info(content, duration, onClose, mask);
        const toastElement = document.getElementsByClassName('am-toast-mask')[0];
        toastElement &&
          toastElement.addEventListener('click', () => {
            Toast.hide();
            onClose && onClose();
          });
      };
    antd-mobileのloading図はAndroidでちょっと変ですが、ここでもLoadingをカスタマイズしました.
    static loading = (content, duration, onClose, mask) => {
        Toast.info(
          
    Created with Sketch.
    {content}
    , duration, onClose, mask ); };

    最後に書く
    1つのプロジェクトは、より良いものになるために、絶えず最適化され、改善される必要があります.プロジェクトの構築はプロジェクト責任者にとって大きな試練であり、プロジェクト設計の初期に多くの問題が考慮されていなければ、最適化に大きな精力を費やす可能性が高い.
    要するに、困難や問題から逃げないでください.これらは成長の道に欠かせないものです.