眾所周知,Callback-Hell(回調(diào)地獄)是傳統(tǒng) JS 語法上的歷史問題。但畢竟稱手的工具是開發(fā)效率的源泉,因此筆者對當(dāng)前版本的微信小程序 API 做了簡單的封裝——weapp。
同時(shí),微信小程序框架本身專注于交互和 UI 的實(shí)現(xiàn),并未提供內(nèi)置的狀態(tài)管理。如果眾多的異步操作都直接在 App
或 Page
中一一實(shí)現(xiàn),相信開發(fā)起來會(huì)很困難,而且不易于測試。
因此,我又因此針對微信小程序?qū)崿F(xiàn)了一個(gè)基于 Redux 方案的狀態(tài)管理模塊,用以方便的在小程序中實(shí)現(xiàn)應(yīng)用狀態(tài)管理 redux-weapp。
特別地,微信小程序構(gòu)建(編譯)時(shí)不支持從 App scope 之外 require 文件,npm 在此就不好用了。
所以,我們需要實(shí)時(shí) build 依賴到應(yīng)用本地,在微信小程序中引用本地的 modules。
對于這種構(gòu)建場景,我認(rèn)為 webpack 算是最方便的方案。
從官方文檔,了解微信小程序是什么;
了解 Redux 應(yīng)用狀態(tài)管理方案,同時(shí)它也是 Flux 架構(gòu)的具體實(shí)現(xiàn);
了解 JavaScript 打包工具 webpack;
了解 ES6/7 代碼轉(zhuǎn)譯(transcompile)工具 Babel。原理是借助語法分析工具,將代碼解析成抽象語法樹后「重寫」成最終的代碼;
類似 Jest、Mocha 等 JavaScript 測試工具,可以根據(jù)需要選擇。
開發(fā)者工具是用 NW.js 模擬的環(huán)境,在微信中,則是 JavascriptCore 環(huán)境。
不過不用擔(dān)心, 只是兩個(gè)不同的 VM,本質(zhì)是一樣的。
NW.js 可能存在一些小 bug,寫代碼的時(shí)候注意一下就好。
1
2
|
mkdir myappcd myapp npm init |
由于除了小程序運(yùn)行時(shí)需要的模塊,還有構(gòu)建所需要的模塊。
看起來會(huì)比較多,不過不用擔(dān)心,大多數(shù)都是聲明性的,不需要你直接調(diào)用。
為了方便經(jīng)驗(yàn)少些的同學(xué)理解,我將這些依賴分步安裝。
首先是代碼轉(zhuǎn)譯工具 Babel:
1
|
npm install --save-dev babel-cli babel-core babel-loader babel-plugin-add-module-exports babel-polyfill babel-preset-es2015 babel-preset-stage-0 |
有了上面這些模塊,就可以在構(gòu)建時(shí),將 ES6/7 的代碼轉(zhuǎn)譯為 ES5 的代碼了(其實(shí)解釋器都只認(rèn) ES5)。
接下來,我們安裝打包工具 webpack:
1
|
npm install webpack --save-dev |
我們只需要對代碼進(jìn)行打包,不需要 dev server 和 hot module replace 功能。
因此,我們只需要安裝 webpack module 本身即可,無需安裝其他擴(kuò)展和插件。
接下來,我們來安裝 Redux:
1
|
npm install redux redux-thunk --save-dev |
需要注意的是,由于在實(shí)際應(yīng)用中,我們經(jīng)常會(huì)需要異步調(diào)用 API 服務(wù)器的接口,因此我們還需要 redux-thunk
這個(gè)模塊,來處理異步行為。
然后安裝開發(fā)小程序的輔助模塊:
1
|
npm install xixilive /weapp xixilive /redux-weapp --save-dev |
其中,weapp 模塊是對微信小程序 API 的 wrapper,提供了更易于使用的 API,redux-weapp 是基于 Redux 對微信小程序進(jìn)行狀態(tài)管理。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
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
, 這個(gè)是必須的。
由于這個(gè)構(gòu)建是為了本地化微信小程序的依賴,因此我們只處理 JS 文件。若需要打包其他資源,請讀者自行研究。
而且,值得注意的是,微信小程序包有 1 MB 的上限。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
/ / webpack.config.jsvar path = require( 'path' ), webpack = require( 'webpack' )var jsLoader = { test: / \.js$ / , / / 你也可以用.es6做文件擴(kuò)展名, 然后在這里定義相應(yīng)的pattern loader: 'babel' , query: { / / 代碼轉(zhuǎn)譯預(yù)設(shè), 并不包含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 選項(xiàng), 建議開發(fā)時(shí)包含sourcemap, production版本時(shí)去掉(節(jié)能減排) devtool: null, / / 指定es6目錄為context目錄, 這樣在下面的entry, output部分就可以少些幾個(gè)`.. / `了 context: path.join(dirname, 'es6' ), / / 定義要打包的文件 / / 比如: `{entry: {out: [ './x' , './y' , './z' ]}}` 的意思是: 將x,y,z等這些文件打包成一個(gè)文件,取名為: 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 時(shí)就會(huì)自動(dòng)在這個(gè)目錄下resolve文件(可以省去不少.. / ) modulesDirectories: [ 'es6' , 'node_modules' ] }, plugins: [ new webpack.NoErrorsPlugin(), / / 通常會(huì)需要區(qū)分dev和production, 建議定義這個(gè)變量 / / 編譯后會(huì)在 global 中定義`process.env`這個(gè) Object new webpack.DefinePlugin({ 'process.env' : { 'NODE_ENV' : JSON.stringify( 'development' ) } }) ] } |
首先是代碼測試命令 test
。
由于我喜歡用 Jest,所以這里也用 Jest 做范例。
1
2
3
4
5
6
7
8
9
|
// package.json"scripts": { "pretest": "eslint es6", //推薦進(jìn)行靜態(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/" ] } |
接下來,就是激動(dòng)人心的 build
命令。成敗在此一舉
工作日 8:30-12:00 14:30-18:00
周六及部分節(jié)假日提供值班服務(wù)