Commit d3466d0f authored by 谢卓城's avatar 谢卓城

更新:npm命令. 修复:gulp dev命令删除miniprogram_npm文件的问题

parent 4feae52e
...@@ -38,7 +38,7 @@ const imageFiles = [ ...@@ -38,7 +38,7 @@ const imageFiles = [
/* 清除dist目录 */ /* 清除dist目录 */
gulp.task("clean", done => { gulp.task("clean", done => {
del.sync(["dist/**"]); del.sync(["dist/**", "!dist/miniprogram_npm"]);
done(); done();
}); });
......
...@@ -9,9 +9,9 @@ ...@@ -9,9 +9,9 @@
"lint": "eslint src --fix", "lint": "eslint src --fix",
"devBuild": "gulp devBuild", "devBuild": "gulp devBuild",
"build": "gulp prod", "build": "gulp prod",
"buildminiprogramci": "node ./package/miniprogramci.js", "build:ci": "node ./package/miniprogramci.js",
"devPackage": "sh ./package/package.sh 0 & npm run buildminiprogramci", "devPackage": "sh ./package/package.sh 0 & npm run build:ci",
"package": "sh ./package/package.sh 1 & npm run buildminiprogramci", "package": "sh ./package/package.sh 1 & npm run build:ci",
"page": "gulp new -p", "page": "gulp new -p",
"component": "gulp new -c" "component": "gulp new -c"
}, },
......
...@@ -2,8 +2,7 @@ ...@@ -2,8 +2,7 @@
* @Descripttion: 开发环境 * @Descripttion: 开发环境
*/ */
const API_URL = { const API_URL = {
host: "http://xxdev.xxx.com", host: "https://www.jianshu.com"
r: "https://xxr.xxx.com"
}; };
module.exports = API_URL; module.exports = API_URL;
...@@ -4,7 +4,6 @@ const app = getApp(); ...@@ -4,7 +4,6 @@ const app = getApp();
Page({ Page({
data: { data: {
motto: "Hello World",
userInfo: {}, userInfo: {},
hasUserInfo: false, hasUserInfo: false,
canIUse: wx.canIUse("button.open-type.getUserInfo") canIUse: wx.canIUse("button.open-type.getUserInfo")
...@@ -50,6 +49,18 @@ Page({ ...@@ -50,6 +49,18 @@ Page({
}); });
} }
}, },
requestAction(e) {
// 网络请求
app._get(
"",
res => {
console.log("发起get请求-res", res);
},
err => {
console.log("发起get请求-err", err);
}
);
},
getUserInfo: function(e) { getUserInfo: function(e) {
console.log(e); console.log(e);
app.globalData.userInfo = e.detail.userInfo; app.globalData.userInfo = e.detail.userInfo;
......
...@@ -8,6 +8,6 @@ ...@@ -8,6 +8,6 @@
</block> </block>
</view> </view>
<view class="usermotto"> <view class="usermotto">
<text class="user-motto">{{motto}}</text> <button bind:tap="requestAction"> 网络请求 </button>
</view> </view>
</view> </view>
import ExpireCache from './ExpireCache';
export default class Buffer extends ExpireCache {
static cacheMap = new Map();
}
export default class CacheItem {
/**
* 缓存item
* @param {Any} data 缓存数据
* @param {Number} timeout 缓存时长,计算缓存过期时间,单位-秒
* @param {Any} cacheLabel 缓存标记,对比标记极端缓存是否过期
*/
constructor(data, timeout, cacheLabel = null) {
this.data = data;
this.cacheLabel = cacheLabel;
this.expireTime = timeout ? new Date().getTime() + timeout * 1000 : null;
}
}
import CacheItem from './CacheItem';
export default class ExpireCache extends CacheItem {
constructor(data, timeout, cacheLabel) {
super(data, timeout, cacheLabel);
}
// 定义静态数据map来作为缓存池
static cacheMap = new Map();
// 数据是否过期
static isExpire(name, curCacheLabel) {
const data = this.cacheMap.get(name);
// 没有数据 一定过期
if (!data) return true;
// 获取系统当前时间戳
const { expireTime, cacheLabel } = data;
const currentTime = new Date().getTime();
// 缓存含过期时间&&已过期
const timeExpire = expireTime && currentTime > expireTime;
// 缓存含过期标记&&标记已变化
const labelExpire = curCacheLabel && cacheLabel && curCacheLabel !== cacheLabel;
if (timeExpire || labelExpire) {
this.cacheMap.delete(name);
return true;
}
// 不过期
return false;
}
// 当前data在 cache 中是否过期 - 判断时间&标记
static has(name, cacheLabel) {
return !this.isExpire(name, cacheLabel);
}
// 删除
static delete(name) {
return this.cacheMap.delete(name);
}
/**
* 获取,如有过期标记需要传入过期标记或者先用has判断
* @param {Any} name 缓存名称
* @param {Any} cacheLabel 缓存标记
*/
static get(name, cacheLabel) {
return this.has(name, cacheLabel) ? this.cacheMap.get(name).data : null;
}
// 存储
static set(name, data, timeout, cacheLabel) {
const itemCache = new ExpireCache(data, timeout, cacheLabel);
// 缓存
this.cacheMap.set(name, itemCache);
}
}
import ExpireCache from './ExpireCache';
import StorageMap from './StorageMap';
export default class Storage extends ExpireCache {
static cacheMap = new StorageMap();
static getCacheName(name) {
return `${INJECTION_FROM_WEBPACK.serverType}iyourcar_cache_${name}`;
}
}
export default class StorageMap {
static getCacheName(name) {
// INJECTION_FROM_WEBPACK.serverType用户区分当前环境
return `${"INJECTION_FROM_WEBPACK.serverType"}iyourcar_cache_${name}`;
}
get(name) {
let storageData = null;
try {
storageData = wx.getStorageSync(name);
} catch (e) {}
return storageData;
}
set(name, data) {
wx.setStorage({
key: name,
data,
});
}
delete(name) {
wx.removeStorageSync(name);
}
}
export const storageMap = new StorageMap();
const API_URL = require("../env.js"); const API_URL = require("../env.js");
import axios from "./request/axios"; import axios from "nmaxios";
/** /**
* 初始化网络配置,会覆盖默认配置 * 初始化网络配置,会覆盖默认配置
*/ */
function initAxios() { function initAxios() {
const baseUrl = API_URL.host; const baseUrl = API_URL.host + "/shakespeare/notes/28193853/user_notes";
const header = { const header = {
"content-type": "application/x-www-form-urlencoded; charset=UTF-8" "content-type": "application/x-www-form-urlencoded; charset=UTF-8"
}; };
......
# 基于 wx.request 封装的类 axios 请求
## Introduction
- wx.request 的配置、axios 的调用方式
## feature
- 支持 wx.request 所有配置项
- 支持 axios 调用方式
- 支持 自定义 baseUrl
- 支持 自定义响应状态码对应 resolve 或 reject 状态
- 支持 对响应(resolve/reject)分别做统一的额外处理
- 支持 转换请求数据和响应数据
- 支持 请求缓存(内存或本地缓存),可设置缓存标记、过期时间
## use
### app.js @onLaunch
```javascript
axios.creat({
header: {
content-type': 'application/x-www-form-urlencoded; charset=UTF-8'
},
baseUrl: 'https://api.baseurl.com',
...
});
```
### page.js
```javascript
axios
.post("/url", { id: 123 })
.then((res) => {
console.log(response);
})
.catch((err) => {
console.log(err);
});
```
## API
```javascript
axios(config) - 默认get
axios(url[, config]) - 默认get
axios.get(url[, config])
axios.post(url[, data[, config]])
axios.cache(url[, data[, config]]) - 缓存请求(内存)
axios.cache.storage(url[, data[, config]]) - 缓存请求(内存 & local storage
axios.creat(config) - 初始化定制配置,覆盖默认配置
```
## config
默认配置项说明
```javascript
export default {
// 请求接口地址
url: undefined,
// 请求的参数
data: {},
// 请求的 header
header: "application/json",
// 超时时间,单位为毫秒
timeout: undefined,
// HTTP 请求方法
method: "GET",
// 返回的数据格式
dataType: "json",
// 响应的数据类型
responseType: "text",
// 开启 http2
enableHttp2: false,
// 开启 quic
enableQuic: false,
// 开启 cache
enableCache: false,
/** 以上为wx.request的可配置项,参考 https://developers.weixin.qq.com/miniprogram/dev/api/network/request/wx.request.html */
/** 以下为wx.request没有的新增配置项 */
// {String} baseURL` 将自动加在 `url` 前面,可以通过设置一个 `baseURL` 便于传递相对 URL
baseUrl: "",
// {Function} (同axios的validateStatus)定义对于给定的HTTP 响应状态码是 resolve 或 reject promise 。如果 `validateStatus` 返回 `true` (或者设置为 `null` 或 `undefined`),promise 将被 resolve; 否则,promise 将被 reject
validateStatus: undefined,
// {Function} 请求参数包裹(类似axios的transformRequest),通过它可统一补充请求参数需要的额外信息(appInfo/pageInfo/场景值...),需return data
transformRequest: undefined,
// {Function} resolve状态下响应数据包裹(类似axios的transformResponse),通过它可统一处理响应数据,需return res
transformResponse: undefined,
// {Function} resolve状态包裹,通过它可做接口resolve状态的统一处理
resolveWrap: undefined,
// {Function} reject状态包裹,通过它可做接口reject状态的统一处理
rejectWrap: undefined,
// {Boolean} _config.useCache 是否开启缓存
useCache: false,
// {String} _config.cacheName 缓存唯一key值,默认使用url&data生成
cacheName: undefined,
// {Boolean} _config.cacheStorage 是否开启本地缓存
cacheStorage: false,
// {Any} _config.cacheLabel 缓存标志,请求前会对比该标志是否变化来决定是否使用缓存,可用useCache替代
cacheLabel: undefined,
// {Number} _config.cacheExpireTime 缓存时长,计算缓存过期时间,单位-秒
cacheExpireTime: undefined,
};
```
/**
* Axios.js
*/
/* eslint-disable no-underscore-dangle */
import wxRequest from "./wxRequest";
import defaults from "./defaults";
import { combineUrl, mergeConfig } from "./util";
import Buffer from "../cache/Buffer";
import Storage from "../cache/Storage";
import StorageMap from "../cache/StorageMap";
class Axios {
constructor(config = defaults) {
this.defaultConfig = config;
}
/**
* 初始化用户配置,会覆盖默认配置
* @param {Object} _config 配置
*/
creat(_config = {}) {
this.defaultConfig = mergeConfig(this.defaultConfig, _config);
}
axios($1 = {}, $2 = {}) {
let config = $1;
// 兼容axios(url[, config])方式
if (typeof $1 === "string") {
config = $2;
config.url = $1;
}
return this.request(config);
}
get(url, _config = {}) {
const config = {
..._config,
url,
method: "GET"
};
return this.request(config);
}
post(url, data = {}, _config = {}) {
const config = {
..._config,
url,
data,
method: "POST"
};
return this.request(config);
}
/**
* 请求缓存api,缓存于内存中
*/
cache(url, data = {}, _config = {}) {
const config = {
..._config,
url,
data,
method: "POST"
};
return this._cache(config);
}
/**
* 请求缓存api,缓存于本地缓存中
*/
storage(url, data = {}, _config = {}) {
const config = {
..._config,
url,
data,
method: "POST",
cacheStorage: true
};
return this._cache(config);
}
/**
* 请求缓存
* @param {Object} _config 配置
* @param {Boolean} _config.useCache 是否开启缓存
* @param {String} _config.cacheName 缓存唯一key值,默认使用url&data生成
* @param {Boolean} _config.cacheStorage 是否开启本地缓存
* @param {Any} _config.cacheLabel 缓存标志,请求前会对比该标志是否变化来决定是否使用缓存,可用useCache替代
* @param {Number} _config.cacheExpireTime 缓存时长,计算缓存过期时间,单位-秒
*/
_cache(_config) {
const {
url = "",
data = {},
useCache = true,
cacheName: _cacheName,
cacheStorage,
cacheLabel,
cacheExpireTime
} = _config;
const computedCacheName = _cacheName || `${url}#${JSON.stringify(data)}`;
const cacheName = StorageMap.getCacheName(computedCacheName);
// return buffer
if (useCache && Buffer.has(cacheName, cacheLabel)) {
return Buffer.get(cacheName);
}
// return storage
if (useCache && cacheStorage) {
if (Storage.has(cacheName, cacheLabel)) {
const data = Storage.get(cacheName);
// storage => buffer
Buffer.set(
cacheName,
Promise.resolve(data),
cacheExpireTime,
cacheLabel
);
return Promise.resolve(data);
}
}
const curPromise = new Promise((resolve, reject) => {
const handleFunc = res => {
// do storage
if (useCache && cacheStorage) {
Storage.set(cacheName, res, cacheExpireTime, cacheLabel);
}
return res;
};
this._request(_config)
.then(res => {
resolve(handleFunc(res));
})
.catch(reject);
});
// do buffer
Buffer.set(cacheName, curPromise, cacheExpireTime, cacheLabel);
return curPromise;
}
request(_config) {
// config支持缓存
if (_config.useCache) return this._cache(_config);
return this._request(_config);
}
_request(_config = {}) {
let config = mergeConfig(this.defaultConfig, _config);
const { baseUrl, url, header, data = {}, transformRequest } = config;
const computedConfig = {
header: {
"content-type": "application/x-www-form-urlencoded; charset=UTF-8",
// ycFrom: "yc-component",
...header
},
...(baseUrl && {
url: combineUrl(url, baseUrl)
}),
...(transformRequest &&
typeof transformRequest === "function" && {
data: transformRequest(data)
})
};
config = mergeConfig(config, computedConfig);
// console.log('iyourcar-component-axios__request-config :', config);
return wxRequest(config);
}
}
export default Axios;
/**
* 基于wx.request封装的类axios请求
* wx.request 的配置、axios的调用方式
* @config 配置参数说明 --> ./defaults.js
* @api axios(config) - 默认get
* @api axios(url[, config]) - 默认get
* @api axios.get(url[, config])
* @api axios.post(url[, data[, config]])
* @api axios.cache(url[, data[, config]]) - 缓存请求(内存)
* @api axios.cache.storage(url[, data[, config]]) - 缓存请求(内存 & local storage)
* @api axios.creat(config) - 初始化定制配置,覆盖默认配置
* @use @app.js-onLaunch:axios.creat(config); @page.js: axios.post(url[, data[, config]]);
* @reference http://www.axios-js.com/zh-cn/docs/
*/
import Axios from "./axios.class.js";
const axiosInstance = new Axios();
const { axios } = axiosInstance;
axios.creat = axiosInstance.creat.bind(axiosInstance);
axios.get = axiosInstance.get.bind(axiosInstance);
axios.post = axiosInstance.post.bind(axiosInstance);
axios.cache = axiosInstance.cache.bind(axiosInstance);
axios.cache.storage = axiosInstance.storage.bind(axiosInstance);
export default axios;
/** config - axios默认配置项 */
export default {
// 请求接口地址
url: undefined,
// 请求的参数
data: {},
// 请求的 header
header: "application/json",
// 超时时间,单位为毫秒
timeout: undefined,
// HTTP 请求方法
method: "GET",
// 返回的数据格式
dataType: "json",
// 响应的数据类型
responseType: "text",
// 开启 http2
enableHttp2: false,
// 开启 quic
enableQuic: false,
// 开启 cache
enableCache: false,
/** 以上为wx.request的可配置项,参考 https://developers.weixin.qq.com/miniprogram/dev/api/network/request/wx.request.html */
/** 以下为wx.request没有的新增配置项 */
// {String} baseURL` 将自动加在 `url` 前面,可以通过设置一个 `baseURL` 便于传递相对 URL
baseUrl: "",
// {Function} (同axios的validateStatus)定义对于给定的HTTP 响应状态码是 resolve 或 reject promise 。如果 `validateStatus` 返回 `true` (或者设置为 `null` 或 `undefined`),promise 将被 resolve; 否则,promise 将被 reject
validateStatus: undefined,
// {Function} 请求参数包裹(类似axios的transformRequest),通过它可统一补充请求参数需要的额外信息(appInfo/pageInfo/场景值...),需return data
transformRequest: undefined,
// {Function} resolve状态下响应数据包裹(类似axios的transformResponse),通过它可统一处理响应数据,需return res
transformResponse: undefined,
// {Function} resolve状态包裹,通过它可做接口resolve状态的统一处理
resolveWrap: undefined,
// {Function} reject状态包裹,通过它可做接口reject状态的统一处理
rejectWrap: undefined,
// {Boolean} _config.useCache 是否开启缓存
useCache: false,
// {String} _config.cacheName 缓存唯一key值,默认使用url&data生成
cacheName: undefined,
// {Boolean} _config.cacheStorage 是否开启本地缓存
cacheStorage: false,
// {Any} _config.cacheLabel 缓存标志,请求前会对比该标志是否变化来决定是否使用缓存,可用useCache替代
cacheLabel: undefined,
// {Number} _config.cacheExpireTime 缓存时长,计算缓存过期时间,单位-秒
cacheExpireTime: undefined
};
let scene = "";
export function getPageInfo() {
const postData = {};
try {
if (!scene) {
scene = wx.getLaunchOptionsSync().scene || "";
}
postData.scene = scene;
} catch (error) {
//
}
const pageList = getCurrentPages();
if (pageList.length) {
const currentPage = pageList[pageList.length - 1];
const defaultOptions = JSON.stringify({ default: true });
postData.currentPage = currentPage.__route__;
const optionNameList = ["op", "options", "option"];
postData.currentOptions = defaultOptions;
optionNameList.forEach(i => {
const option = currentPage.data[i] || currentPage[i];
if (option) {
postData.currentOptions = JSON.stringify(option);
}
});
if (pageList.length > 1 && pageList[pageList.length - 2]) {
const previousPage = pageList[pageList.length - 2];
postData.previousPage = previousPage.__route__;
postData.previousOptions = defaultOptions;
optionNameList.forEach(i => {
const option = previousPage.data[i] || previousPage[i];
if (option) {
postData.previousOptions = JSON.stringify(option);
}
});
}
}
return postData;
}
export function mergeConfig(config0 = {}, config1 = {}) {
return {
...config0,
...config1
};
}
export function combineUrl(url, host) {
return `${host.replace(/\/$/, "")}/${url.replace(/^\//, "")}`;
}
export function ifReqSuccess(res) {
return /^2/.test(res.statusCode.toString()) && res.data.errcode === 0;
}
export function ifReqNeedAuth(res) {
return res.data.errcode === 100 || res.data.errcode === 101;
}
export function handleError(res) {
if (res && res.data && res.data.msg) {
wx.showToast({
title: res.data.msg,
icon: "none"
});
}
}
export default function wxRequest(config) {
return new Promise((resolve, reject) => {
wx.request({
...config,
success(res) {
const {
resolveWrap,
rejectWrap,
transformResponse,
validateStatus,
} = config;
if ((validateStatus && validateStatus(res)) || ifSuccess(res)) {
// eslint-disable-next-line no-underscore-dangle
const _resolve = resolveWrap ? resolveWrap(res) : res;
return resolve(transformResponse ? transformResponse(_resolve) : _resolve);
}
return reject(rejectWrap ? rejectWrap(res) : res);
},
fail(res) {
const { rejectWrap } = config;
reject(rejectWrap ? rejectWrap(res) : res);
},
});
});
}
function ifSuccess(res) {
return /^2/.test(res.statusCode.toString()) && res.data.errcode === 0;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment