React v16.9 H5 template

倉庫地址:gitee.com/dreamer2011…javascript

一、前言

本項目適用於移動端H5混合開發的React項目,功能包括:css

  1. 採用VW,字體自動適配,默認按照UI設計稿750*1334(webpack裏能夠配置UI稿原始尺寸)上下適配各類手機設備;
  2. 自動生成 sprite 雪碧圖和相關 sprite.less ,無需手動建立雪碧圖和手寫less;
  3. webpack4最新構建,分離壓縮代碼、去除重複引用的css代碼、開發環境生成sourceMap方便調試、生產環境移除console.log打印信息等構建,並生成相關gz包,優化頁面資源加載;
  4. 基於原生API Fetch封裝 dataService 服務,統一格式進行相關接口的GET, POST請求;
  5. 統一封裝中間攔截組件 FetchData.jsx, 進行組件數據預加載和狀態注入;
  6. React router components 進行 lazing load 懶加載, 帶有組件預加載loading加載失敗error提示,增長頁面友好提示,性能也更加優化;
  7. bebel7 相關配置;
  8. 配置liveServer對生成的PROD生產環境代碼,進行預先運行檢查;
  9. css圖片相關優化,css文件生產環境自動分離;
  10. 採用browserHistory路由模式,相關本地環境配置已經自動配置(上線時,須要在服務器配置nginx
  11. 自動生成文件夾保存當前打包生成的tar包, 防止線上部署失敗; 有備份的話能夠回滾以前的代碼版本;
  12. 若是拋卻相關app h5設置,可看成 PC 項目,兼容 ie9+;
  13. 增長手機端調試面板,功能至關於打開 PC 控制檯,能夠很方便地查看 console, network, cookie, localStorage 等關鍵調試信息;
  14. 增長手勢庫,例如拖動(Pan),縮放(Pinch),旋轉(Rotate),滑動(swipe);
  15. 增長Sentry監控代碼異常錯誤上報,訪問 f5fe3d6e599849bfa1d1f0c26d1c3213@sentry.io/1729437,查看報…
  16. Bundle構建完成提醒和生成Bundle分析報告report

二、命令行

Local Server:html

yarn dev 
#or
npm run dev
複製代碼

build bundle:java

yarn build
#or
npm run build
複製代碼

生成 tar 包node

# 默認生產 cdn.tar.gz
yarn tar
#or
npm run tar
 # 能夠自定義tar包名
yarn tar react
#or
npm run tar react
複製代碼

測試打包後要上線的代碼:react

yarn start
#or
npm run start
複製代碼

三、修改UI稿尺寸原始匹配大小

webpack.config.jswebpack

{
    test: /\.less$/,
        use: [
            isProduction ? MiniCssExtractPlugin.loader : 'style-loader',
            'css-loader',
            'less-loader',
            // 配置相關移動端 VW 佈局
            {
                loader: 'postcss-less-loader',
                options: {
                    ident: 'postcss',
                    plugins: () => [
                        postcssPxToViewport({
                            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.
                        })
                    ]
                }
            }
        ]
}
複製代碼

四、如何自動生成雪碧圖

webpack.config.jsnginx

// 圖片整合成雪碧圖
const SpritesmithPlugin = require('webpack-spritesmith');
// customerTemplate
const templateFunction = function(data) {
    // console.log('---', data)
    const shared = `.sprite_ico { background-image: url(I);display:inline-block;background-size: Wpx Hpx;}`
        .replace('I', data.sprites[0].image)
        .replace('W', data.spritesheet.width)
        .replace('H', data.spritesheet.height);

    const perSprite = data.sprites
        .map(function(sprite) {
            return `.sprite_ico_N { width: Wpx; height: Hpx; background-position: Xpx Ypx;}`
                .replace('N', sprite.name)
                .replace('W', sprite.width)
                .replace('H', sprite.height)
                .replace('X', sprite.offset_x)
                .replace('Y', sprite.offset_y);
        })
        .join('\n');

    return "//out:false" + '\n'+shared + '\n' + perSprite;
};
 // 雪碧圖

plugins.push(
    new SpritesmithPlugin({
        src: {
            //下面的路徑,根據本身的實際路徑配置
            cwd: path.resolve(__dirname, './src/assets/icons'),
            glob: '*.png'
        },
        // 輸出雪碧圖文件及樣式文件
        target: {
            //下面的路徑,根據本身的實際路徑配置
            image: path.resolve(__dirname, './src/assets/sprite.png'),
            css: [
                [
                    path.resolve(__dirname, './src/less/sprite.less'),
                    {
                        format: 'function_based_template'
                    }
                ]
            ]
            // css: path.resolve(__dirname, './src/less/sprite.less')
        },
        // 自定義模板
        customTemplates: {
            function_based_template: templateFunction
        },
        // 樣式文件中調用雪碧圖地址寫法
        apiOptions: {
            // 這個路徑根據本身頁面配置
            cssImageRef: '../assets/sprite.png'
        },
        spritesmithOptions: {
            // algorithm: 'top-down'
            padding: 5
        }
    })
);

複製代碼

icon格式須要是png, 把須要生成雪碧圖的小icon放置在目錄src/assets/icons下面,而後執行yarn build,就能夠在src\less\sprite.less下去找本身的圖標ICON的className;好比:git

1568710353716

使用的時候,直接引入 sprite_ico sprite_ico_guzhi便可;無需配置引入sprite.less文件;github

<span className="sprite_ico sprite_ico_guzhi"></span>
複製代碼

五、React 書寫規範

React 組件必須首字母大寫,其餘請參考官網

六、當前文件目錄解讀

cdn    --------------構建後的資源
public --------------靜態資源
src    --------------全部React資源
	actions --------------- 相關action
	assets  --------------- 全部靜態圖片資源
	components ------------ 公共組件
	dataService-----------  請求服務
	less ------------------ less文件
	pages ----------------- 全部入口文件下的子文件
	reducers -------------- reducer
	router ---------------- 路由設置
	store ----------------- 狀態存儲
	utils ----------------- 公共方法
	.....其他都是App.jsx login.jsx等入口文件
tar    --------------構建備份的tar
....
複製代碼

七、sentry異常代碼監控

index.html

<script src="https://cdn.ravenjs.com/3.26.4/raven.min.js" crossorigin="anonymous"></script>
// 代碼錯誤監控 Raven.config('https://f5fe3d6e599849bfa1d1f0c26d1c3213@sentry.io/1729437').install();
複製代碼

添加 ==React ErrorBoundary== 組件,具體能夠參考官方文檔

import React from 'react';

import oops from "@assets/oops.png";

// catch JavaScript errors anywhere in their child component tree, log those errors, and display a fallback UI
class ErrorBoundary extends React.Component {
    constructor(props) {
        super(props);
        this.state = { error: null };
    }

    componentDidCatch(error, errorInfo) {
        this.setState({ error });
        Raven.captureException(error, { extra: errorInfo });
    }

    render() {
        if (this.state.error) {
            //render fallback UI
            return (
                <div className="snap" onClick={() => Raven.lastEventId() && Raven.showReportDialog()}>
                    <img src={oops} />
                    <p>We're sorry — something's gone wrong.</p>
                    <p>Our team has been notified, but click here fill out a report.</p>
                </div>
            );
        } else {
            //when there's not an error, render children untouched
            return this.props.children;
        }
    }
}

export default ErrorBoundary;


複製代碼

此時若是咱們如今故意改錯一些東西,則會提示 fallback UI:

在這裏插入圖片描述

點擊文字,用戶能夠主動發一個 issue 給咱們:

在這裏插入圖片描述

目前報錯信息會上傳到 sentry.io,也能夠建立本身的私服;

在這裏插入圖片描述

在這裏插入圖片描述

八、eruda手機端調試面板

index.html

//在手機端進行查看控制檯相關資源
(function () {
    //推薦 CDN 加載
    const src = 'https://cdn.jsdelivr.net/npm/eruda@1.5.8/eruda.min.js';
    // var src = 'node_modules/eruda/eruda.min.js';
    if (!/debug=true/.test(window.location) && localStorage.getItem('debug') != 'true') return;
    document.write('<scr' + 'ipt src="' + src + '"></scr' + 'ipt>');
    document.write('<scr' + 'ipt>eruda.init();</scr' + 'ipt>');
})();

複製代碼

啓動項目後,訪問 http://192.168.1.100:3002/?debug=true , 在手機上如圖:

在這裏插入圖片描述

九、hammer手勢庫

<script src="https://hammerjs.github.io/dist/hammer.js"></script>

複製代碼

舉例:

import React from 'react';

class HammerPan extends React.Component {
    render() {
        return <div className="myElement">888</div>;
    }

    componentDidMount() {
        const myElement = document.querySelector('.myElement');
        // create a simple instance
        // by default, it only adds horizontal recognizers
        const mc = new Hammer(myElement);

        // let the pan gesture support all directions.
        // this will block the vertical scrolling on a touch-device while on the element
        mc.get('pan').set({ direction: Hammer.DIRECTION_ALL });

        // listen to events...
        mc.on('panleft panright panup pandown tap press', ev => {
            myElement.textContent = ev.type + ' gesture detected.';
        });
    }
}

export default HammerPan;


複製代碼

啓動項目後,訪問 http://192.168.1.100:3002/pan,便可查看

十、生成分析報告Report

# NPM
npm install --save-dev webpack-bundle-analyzer
# Yarn
yarn add -D webpack-bundle-analyzer

複製代碼
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;

module.exports = {
  plugins: [
    new BundleAnalyzerPlugin()
  ]
}

複製代碼

在這裏插入圖片描述

十一、bundle生成tar包,並備份

在這裏插入圖片描述

package.json

"scripts": {
        "dev": "webpack-dev-server --mode development",
        "build": "bash ./rm.sh && webpack --mode production --profile --json > stats.json && yarn tar",
        "start": "node ./server.js",
        "tar": "bash ./tar.sh"
    }

複製代碼
相關文章
相關標籤/搜索