成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

微信小程序模塊化開發(fā)實踐

luxixing / 1302人閱讀

摘要:前言省略準備了解微信小程序是什么微信小程序官方文檔了解應用狀態(tài)管理方案也是架構的具體實現(xiàn)了解打包工具了解代碼轉(zhuǎn)譯工具原理大致是借助語法分析工具之類的將代碼解析成抽象語法樹再重寫成最終的代碼測試工具等等請根據(jù)需要選擇微信小程序目前版本的實現(xiàn)需

前言: 省略...

準備

了解微信小程序是什么? 微信小程序官方文檔

了解應用狀態(tài)管理方案: Redux, 也是Flux架構的具體實現(xiàn)

了解Javascript打包工具: webpack

了解ES6/7代碼轉(zhuǎn)譯(transcompile)工具: Babel, 原理大致是借助語法分析工具(Esprima之類的), 將代碼解析成抽象語法樹, 再"重寫"成最終的代碼.

Javascript測試工具: jest, mocha等等, 請根據(jù)需要選擇.

TL;DR;

微信小程序目前版本的API實現(xiàn)需要兼顧方方面面, 所以仍然使用callback寫法, 眾所周知的Callback-Hell是傳統(tǒng)js語法上的歷史問題, 但畢竟稱手的工具是開發(fā)效率的源泉. 因此筆者對當前版本的微信小程序API做了簡單的封裝 weapp.

同時, 微信小程序框架本身專注于交互和UI的實現(xiàn), 并未提供內(nèi)置的狀態(tài)管理, 如果眾多的異步操作都直接在App或者Page中一一實現(xiàn), 相信寫起來會是一場噩夢, 而且不易于測試, 筆者又因此針對微信小程序?qū)崿F(xiàn)了一個基于Redux方案的狀態(tài)管理模塊, 用以方便的在小程序中實現(xiàn)應用狀態(tài)管理 redux-weapp.

特別地, 微信小程序構建(編譯)時不支持從App scope之外require文件, npm在此就不好用了. 所以, 我們需要實時build依賴到應用本地, 在微信小程序中引用本地的modules, 對于這種構建場景, 筆者認為webpack算是最方便的方案. 大家都說COPY到本地是最最最方便的方式~~

安裝工具和依賴模塊 下載微信小程序開發(fā)者工具

開發(fā)者工具是用nwjs模擬的環(huán)境, 實際在微信中是JavascriptCore環(huán)境, 不過不用擔心, 只是兩個不同的vm, 本質(zhì)是一樣的.

nwjs可能存在一些小bug, 寫代碼的時候注意一下就好.

下載 微信小程序開發(fā)者工具

用npm命令開始一個微信小程序項目
mkdir myapp
cd myapp
npm init
開始安裝必要的依賴模塊

由于除了小程序運行時需要的模塊, 還有構建所需要的模塊, 看起來會比較多, 不過不用擔心, 大多數(shù)都是聲明性的, 不需要你直接調(diào)用.

為了方便經(jīng)驗少些的同學理解, 我將這些依賴分步安裝.

代碼轉(zhuǎn)譯工具, 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

有了上面這些模塊, 就可以在構建時將ES6/7的代碼轉(zhuǎn)譯為ES5的代碼了(其實解釋器都只認ES5).

安裝打包工具, webpack

npm install webpack --save-dev

在此, 我們只需要對代碼進行打包, 不需要dev server和hot module replace功能, 因此只需要安裝webpack module本身, 無需安裝其他擴展和插件.

安裝Redux

npm install redux redux-thunk --save-dev

由于在實際應用中, 我們經(jīng)常會需要異步調(diào)用API服務器的接口, 所以需要redux-thunk這個模塊來處理 異步action.

安裝開發(fā)小程序的輔助模塊

npm install xixilive/weapp xixilive/redux-weapp --save-dev

其中, weapp模塊是對微信小程序API的wrapper, 提供了更易于使用的API, redux-weapp是基于Redux對微信小程序進行狀態(tài)管理.

建立項目目錄結構如下
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等資源, 請讀者自行研究. 實際上, 微信小程序包有1MB的上限.

// webpack.config.js

var path = require("path"), webpack = require("webpack")

var jsLoader = {
  test: /.js$/, // 你也可以用.es6做文件擴展名, 然后在這里定義相應的pattern
  loader: "babel",
  query: {
    // 代碼轉(zhuǎn)譯預設, 并不包含ES新特性的polyfill, polyfill需要在具體代碼中顯示require
    presets: ["es2015", "stage-0"]
  },
  // 指定轉(zhuǎn)譯es6目錄下的代碼
  include: path.join(__dirname, "es6"),
  // 指定不轉(zhuǎn)譯node_modules下的代碼
  exclude: path.join(__dirname, "node_modules")
}

module.exports = {
  // sourcemap 選項, 建議開發(fā)時包含sourcemap, production版本時去掉(節(jié)能減排)
  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規(guī)范為 `umd`, 兼容commonjs和amd, 具體請參看webpack文檔
    libraryTarget: "umd"
  },

  module: {
    loaders: [jsLoader]
  },

  resolve: {
    extensions: ["", ".js"],
    // 將es6目錄指定為加載目錄, 這樣在require/import時就會自動在這個目錄下resolve文件(可以省去不少../)
    modulesDirectories: ["es6", "node_modules"]
  },

  plugins: [
    new webpack.NoErrorsPlugin(),

    // 通常會需要區(qū)分dev和production, 建議定義這個變量
    // 編譯后會在global中定義`process.env`這個Object
    new webpack.DefinePlugin({
      "process.env": {
        "NODE_ENV": JSON.stringify("development")
      }
    })
  ]
}
定義npm命令

test 筆者比較喜歡jest, 所以在此就用jest做范例了.

// package.json

"scripts": {
  "pretest": "eslint es6", //推薦進行靜態(tài)檢查
  "test": "jest",
  ...
},
...,
// jest允許在package.json中定義配置
"jest": {
  "automock": false,
  "bail": true,
  "transform": {
    ".js": "/node_modules/babel-jest" //用babel轉(zhuǎn)譯
  },
  "testPathDirs": [
    "/__tests__/"
  ],
  "testRegex": ".test.js$",
  "unmockedModulePathPatterns": [
    "/node_modules/"
  ],
  "testPathIgnorePatterns": [
    "/node_modules/"
  ]
}

build 這里就是構建的命令了, 成敗在此一舉 :)

// package.json

"scripts": {
  ...,
  // 帶上watch選項, 實時編譯修改, 由于小程序開發(fā)工具也監(jiān)視應用文件的修改, 所以es6目錄下的js文件修改, 將導致小程序開發(fā)工具自動重新加載
  "build": "webpack --watch --progress --colors --config webpack.config.js"
},
寫應用代碼

總算進入正題了(工欲善其事,...), 借助上述的 weapp 和 redux-weapp, 希望你會感到很舒服~~.

在這個范例(myapp)中, 我們目標是去查詢 github/octokit 的開源項目, 并顯示在小程序中.

建議不了解Redux的讀者先去快速了解一下(2 hours) Getting started with Redux - from egghead

myapp模塊

定義store: /es6/store.js

這里只是簡單的范例, 實際中會有比較復雜的store shape, 需要引入更多的middleware來處理動作和狀態(tài)的變化.

// /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時發(fā)生的狀態(tài)變化的function, 參數(shù)總是為(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

Action通常是個Plain Object, 總是被Store dispatch, 描述了"發(fā)生了什么, 結果是什么"的邏輯

// /es6/actions.js

import {weapp} from "weapp"

// 更好的方法是定義一個api module, 來處理網(wǎng)絡請求
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"這件事情發(fā)生了
      dispatch({
        type: "PROJECTS_LOADED",
        payload: response
      })
    })
  }
}

myapp模塊入口: /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在一起, 這樣就是一個可以發(fā)起對github API的請求了
  (dispatch) => {
    return {
      loadProjects: bindActionCreators(actions.loadProjects, dispatch)
    }
  }
)

// 啟動被connect過的頁面
Page(page(config))

頁面UI: projects.wxml


  {{project.name}}
后記

范例代碼未實際運行, 僅用以表示開發(fā)步驟, 我會盡快把這個范例實現(xiàn)完整, 放到github上.

最后, 謝謝您耐心閱讀至此!

參考

https://github.com/nwjs/nw.js...

http://redux.js.org

https://webpack.github.io

https://facebook.github.io/je...

https://babeljs.io

文章版權歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://m.hztianpu.com/yun/81085.html

相關文章

  • 微信小程開發(fā)最佳實踐

    摘要:于是,我重新思考了下,最佳的微信小程序開發(fā)實踐應該是無痛的,且舒服的,無痛的是指在小程序的飛速發(fā)展變更中,我們不用重復的浪費學習第三方框架和原生框架。以上,便可以在微信小程序中使用了。 weapp-starter 微信小程序開發(fā)最佳實踐 項目地址 為什么會有這個 repo 在小程序之初便開發(fā)應用了,現(xiàn)在小程序的開發(fā)也越來越成熟了,完善了很多的API、組件、架構等,社區(qū)也由原來的零星點點...

    Developer 評論0 收藏0
  • 前端資源系列(3)-微信小程開發(fā)資源匯總

    摘要:微信小程序應用號開發(fā)資源匯總文檔工具教程代碼插件組件文檔從搭建一個微信小程序開始小程序開發(fā)文檔小程序設計指南工具小程序開發(fā)者工具官方支持微信小程序?qū)崟r預覽的支持的微信小程序組件化開發(fā)框架轉(zhuǎn)在線工具小程序云端增強社區(qū)微信小程序 微信(小程序or應用號)開發(fā)資源匯總-文檔-工具-教程-代碼-插件-組件 文檔 從搭建一個微信小程序開始 小程序開發(fā)文檔 小程序設計指南 工具 小程序開發(fā)者...

    paney129 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<