微信小プログラムのモジュール化開発実践

9761 ワード

微信小プログラムのモジュール化開発実践
公衆番号前スタックノート
関連して正版の小さいプログラムの開発の1つを読みます:言語、ライフサイクルとデータは誇張します.
準備
  • マイクロクレジットのプログラムは何ですか?ウィーチャットウィジェットの公式文書
  • は、アプリケーション状態管理スキームを理解する:Reduxも、Fluxアーキテクチャの具体的な実現
  • である.
  • Javascript包装ツールを理解する:webpack
  • ES 6/7コード変換ツール:Babel、原理は大体文法分析ツール(Esprimaなど)を使って、コードを抽象的な文法ツリーに解析して、最後のコードに書き直します.
  • Javascriptテストツール:just、mochaなど、必要に応じて選択してください.
  • TL;DR;
    WeChatアプレットの現在のバージョンのAPI実装には、両方の側面を兼ねる必要がありますので、calbackの書き方を使用しています.よく知られているCallback-Hellは、伝統的なjs文法上の歴史的問題ですが、やはり手の道具は開発効率の源泉です.だから、筆者は現在のバージョンのマイクロクレジットのAPIに対して簡単なパッケージweapを作りました.
    同時に、WeChatウィジェットのフレームワーク自体はインタラクションとUIの実現に専念し、内蔵の状態管理を提供していません.もし多くの非同期の操作が直接AppまたはPageで実現されたら、書いたら悪夢になると信じています.そしてテストが容易ではないので、Redux方式に基づく状態管理モジュールを実現しました.アプリケーションの状態管理を簡単に実行するために使用します.
    特に、WeChatウィジェットの構築(コンパイル)には、App scope以外のrequireファイルはサポートされていません.npmはここでは使いにくいです.だから、私たちはリアルタイムのbuildをアプリケーションに依存して、WeChatウィジェットの中で地元のmodulesを引用する必要があります.このような構築シーンについては、webpackが一番便利なプランだと思います.みんながCOPYは地元に行くと言います.
    ツールとモジュールの取り付け
    マイクロクレジットの開発ツールをダウンロードします.
    開発者ツールはnwjsでシミュレーションした環境で、実際にはWeChatではJavascriptCoreの環境ですが、心配しないでください.
    nwjsにはちょっとしたバグがあるかもしれません.コードを書く時は注意してください.
    マイクロクレジットの開発ツールをダウンロードします.
    npmコマンドでWeChatウィジェットのプロジェクトを開始します.
    mkdir myapp
    cd myapp
    npm init
    
    必要なモジュールのインストールを開始します.
    プログラムを実行する時に必要なモジュール以外に、必要なモジュールを構築することが多いように見えますが、心配しないでください.ほとんどは 性です.直接に呼び出す必要はありません.
    経験の少ない学生に理解してもらうために、これらを段階的にインストールします.
    コード変換ツール、Babel
    npm install --save-dev babel-cli babel-core babel-loader babel-plugin-add-module-exports babel-polyfill babel-preset-es2015 babel-preset-stage-0
    
    これらのモジュールがあれば、構築時にES 6/7のコードをES 5のコードに変換することができます.
    パッケージツールのインストール、webpack
    npm install webpack --save-dev
    
    ここでは、コードを包装するだけで、dev serverとhot module replace機能は必要ないので、webpack module自体をインストールする必要があります.他の拡張機能やプラグインをインストールする必要がありません.
    セットアップRedux
    npm install redux redux-thunk --save-dev
    
    実際のアプリケーションでは、APIサーバのインターフェースを非同期的に呼び出す必要があるので、[ action](http://redux.js.org/docs/advanced/AsyncActions.html)を処理するためにredux-thunkというモジュールが必要である.
    アプレットを開発するためのサブモジュールをインストールします.
    npm install xixilive/weapp xixilive/redux-weapp --save-dev
    
    weappモジュールは、WeChatウィジェットAPIのwrapperであり、より使いやすいAPIを提供し、redux-weappは、Reduxに基づいてWeChatウィジェットを状態管理する.
    プロジェクトディレクトリを作成する構造は以下の通りです.
    myapp
     |- es6                #    
       |- myapp.js         #  app.js   require   
     |- lib                #        js  
     |- pages              #        
       |- projects
         |- projects.js
         |- projects.json
         |- projects.wxml
         |- projects.wxss
       ...
     |- app.js             #        
     |- app.json
     |- app.wxss
     |- webpack.config.js  # webpack    
    
    ビルドスクリプトを作成
    まずwebpack.config.jsと書かなければなりません.これは必要です. マイクロクレジット・プログラムの依存性のために構築されていますので、jsファイルだけを処理します.css、imageなどの他の資源を包装する必要があれば、読者自身で検討してください.実際には、WeChat・アプリケーション・パッケージは1 MBの上限があります.
    // webpack.config.js
    
    var path = require('path'), webpack = require('webpack')
    
    var jsLoader = {
      test: /\.js$/, //      .es6      ,           pattern
      loader: 'babel',
      query: {
        //       ,     ES    polyfill, polyfill          require
        presets: ["es2015", "stage-0"]
      },
      //     es6      
      include: path.join(__dirname, 'es6'),
      //      node_modules    
      exclude: path.join(__dirname, 'node_modules')
    }
    
    module.exports = {
      // sourcemap   ,        sourcemap, production     (    )
      devtool: null,
    
      //   es6   context  ,       entry, output         `../` 
      context: path.join(__dirname, 'es6'),
    
      //         
      //   : `{entry: {out: ['./x', './y','./z']}}`     :  x,y,z            ,   : out
      //      webpack  
      entry: {
        myapp: './myapp'
      },
    
      output: {
        //           lib  
        path: path.join(__dirname, 'lib'),
    
        //            myapp, `[name]`         
        filename: '[name].js',
    
        // module    `umd`,   commonjs amd,      webpack  
        libraryTarget: 'umd'
      },
    
      module: {
        loaders: [jsLoader]
      },
    
      resolve: {
        extensions: ['', '.js'],
        //  es6         ,    require/import           resolve  (      ../)
        modulesDirectories: ['es6', 'node_modules']
      },
    
      plugins: [
        new webpack.NoErrorsPlugin(),
    
        //        dev production,         
        //      global   `process.env`  Object
        new webpack.DefinePlugin({
          'process.env': {
            'NODE_ENV': JSON.stringify('development')
          }
        })
      ]
    }
    
    
    npmコマンドを定義します
  • test笔者はjustが好きですので、ここでjustを使って例を作ります.
  • // package.json
    
    "scripts": {
      "pretest": "eslint es6", //        
      "test": "jest",
      ...
    },
    ...,
    // jest   package.json     
    "jest": {
      "automock": false,
      "bail": true,
      "transform": {
        ".js": "/node_modules/babel-jest" // babel  
      },
      "testPathDirs": [
        "/__tests__/"
      ],
      "testRegex": ".test.js$",
      "unmockedModulePathPatterns": [
        "/node_modules/"
      ],
      "testPathIgnorePatterns": [
        "/node_modules/"
      ]
    }
    
  • buildここは構築の命令です.成否はこの一挙にあります.)
  • // package.json
    
    "scripts": {
      ...,
      //   watch  ,       ,                    ,   es6    js    ,                 
      "build": "webpack --watch --progress --colors --config webpack.config.js"
    },
    
    アプリケーションコードを書く
    ようやく本題に入りました.上記のweapとredux-weapを使って、あなたが快適だと感じてください.
    この例では、github/octokitのオープンソース項目を調べて、小さなプログラムに表示することを目標としています.
    mypapモジュール
  • 定義store:/es6/store.js
  • ここは単純な例です.実際には複雑なstore shopがあります.もっと多くのmiddlewareを導入して動作と状態の変化を処理します.
    // /es6/store.js
    
    import {createStore, applyMiddleware, bindActionCreators} from 'redux'
    import thunk from 'redux-thunk'
    import reducers from './reducers'
    
    export default function(initState = {}){
      return createStore(
        reducers,
        initState,
        applyMiddleware(thunk)
      )
    }
    
  • 定義reducers:/es6/reducers.js
  • ReducerとはStore dispatch actionsによる状態変化を扱うfunctionであり、パラメータは常に(state,action)です.
    // /es6/reducers.js
    import { combineReducers } from 'redux'
    
    //   projects  
    const projects = (state = [], action) => {
      switch (action.type) {
        case 'PROJECTS_LOADED':
          return state.concat[action.payload]
        //other cases
      }
    
      return state
    }
    
    //    reducer    
    //        store    ,      predictable ?
    export default combineReducers({
      projects
    })
    
  • 定義actions:/es6/actions.js
  • アクションは通常Plain Objectで、いつもStore dispatchによって、「何が起こったのか、結果は何か」という論理を述べています.
    // /es6/actions.js
    
    import {weapp} from 'weapp'
    
    //           api module,        
    const http = weapp.Http('https://api.github.com')
    
    //       action, redux-thunk       Function action(          ~~)
    export const loadProjects = (org) => {
      return (dispatch) => {
        http.get(`/orgs/${org}/repos`).then(response => {
          //  store   'PROJECTS_LOADED'       
          dispatch({
            type: 'PROJECTS_LOADED',
            payload: response
          })
        })
      }
    }
    
  • myapモジュール入口:/es6/myapp.js
  • // /es6/myapp.js
    import {bindActionCreators} from 'redux'
    import {weapp} from 'weapp'
    import connect from 'redux-weapp'
    import store from './store'
    import actions from './actions'
    
    export {
      weapp,
      connect,
      bindActionCreators,
      store,
      actions
    }
    
    
    アプレットモジュール
  • エントランスファイル:app.jsapp.json
  • // /app.js
    App({
      //     ,       life-cycle  
    })
    
    app.json
    {
      "pages": [
        "pages/projects/projects"
      ],
      "window": {
        "navigationBarTitleText": "Orchid"
      },
      "networkTimeout": {
        "request": 10000,
        "downloadFile": 10000
      },
      "debug": true
    }
    
  • ページ論理:projects.js
  • 上記のように、ウィジェットの起動ページはprojectsです.
    // /pages/projects/projects.js
    
    //       modules
    import {
      weapp,
      connect,
      bindActionCreators,
      store,
      actions
    } from '../../lib/app'
    
    //   Page  Object
    const config = {
      data: {
        projects: [] //for init-render
      },
    
      onReady(){
        //      loadProjects?    
        this.loadProjects('octokit')
      },
    
      onStateChange(nextState){
        this.setData({projects: nextState})
      }
    }
    
    // connect store with page
    const page = connect.Page(
      store, // required
      //        projects  
      (state) => ({projects: state.projects}),
    
      //  Action   Store.dispatch binding   ,            github API    
      (dispatch) => {
        return {
          loadProjects: bindActionCreators(actions.loadProjects, dispatch)
        }
      }
    )
    
    //    connect    
    Page(page(config))
    
  • ページUI:projects.wxml
  • 
      {{project.name}}
    
    
    後記
    サンプルコードは実際に実行されていません.開発手順を示すだけで早くこのモデルを完全に実現し、githubに置いておきます.
    最後に、ここまで読んでくれてありがとうございます.公衆番号:JS姉さん
    参照
  • https://github.com/nwjs/nw.js/issues
  • http://redux.js.org
  • https://webpack.github.io
  • https://facebook.github.io/jest/docs
  • https://babeljs.io
  • https://github.com/xixilive/weapp
  • https://github.com/xixilive/redux-weapp