UNPKG

17.8 kBMarkdownView Raw
1## 介绍
2
3miniprogram-ci 是从[微信开发者工具](https://developers.weixin.qq.com/miniprogram/dev/devtools/devtools.html)中抽离的关于小程序/小游戏项目代码的编译模块。
4
5使用前需要使用小程序管理员身份访问"[微信公众平台](https://mp.weixin.qq.com)-开发-开发设置"后下载代码上传密钥,并配置 IP 白名单,才能进行上传、预览操作。
6
7## 注意事项
8
91. 代码上传密钥拥有预览、上传代码的权限
102. 代码上传密钥不会明文存储在微信公众平台上,一旦遗失必须重置,请妥善保管
113. 未配置IP白名单的,将无法使用 miniprogram-ci 进行预览和上传
124. 可选择不对IP进行限制,但务必明白风险
13
14## 功能
15
16miniprogram-ci 目前提供以下能力:
171. 上传代码,对应小程序开发者工具的上传
181. 预览代码,对应小程序开发者工具的预览
191. 构建 npm,对应小程序开发者工具的: 菜单-工具-构建npm
201. 代理,配置 miniprogram-ci 的网络请求代理方式
211. 支持获取最近上传版本的 sourceMap
221. 支持 node 脚本调用方式和 命令行 调用方式
23
24
25## 脚本调用
26
27```shell script
28npm install miniprogram-ci --save
29```
30
31### 项目对象
32
33项目对象是本模块主要的入参,可以依据下边的定义自行实现
34
35**项目对象的定义:**
36
37```typescript
38interface IProject {
39 appid: string
40 type: string
41 projectPath: string
42 privateKey: string
43 attr(): Promise<IProjectAttr>
44 stat(prefix: string, filePath: string): IStat | undefined
45 getFile(prefix: string, filePath: string): Promise<Buffer>
46 getFileList(prefix: string, extName: string): string[]
47 updateFiles: () => void
48}
49```
50
51| 键 | 类型 | 说明 |
52| ----------- | -------- | ------------------------------------------------------------------------------------------------------------------ |
53| appid | 属性 | 小程序/小游戏项目的 appid |
54| type | 属性 | 项目的类型,有效值 miniProgram/miniProgramPlugin/miniGame/miniGamePlugin |
55| projectPath | 属性 | 项目的路径,即 project.config.json 所在的目录 |
56| privateKey | 属性 | 私钥,在获取项目属性和上传时用于鉴权使用,在 [微信公众平台](https://mp.weixin.qq.com) 上使用小程序管理员登录后下载 |
57| attr | 异步方法 | 项目的属性,如指定了 privateKey 则会使用真实的项目属性 |
58| stat | 同步方法 | 特定目录下前缀下(prefix)文件路径 (filePath) 的 stat, 如果不存在则返回 undefined |
59| getFile | 异步方法 | 特定目录下前缀下(prefix)文件路径 (filePath) 的 Buffer |
60| getFileList | 同步方法 | 特定目录下前缀下(prefix)文件路径 (filePath) 下的文件列表 |
61| updateFile | 同步方法 | 更新项目文件 |
62
63也可以通过指定项目路径来创建该对象
64
65```javascript
66const ci = require('miniprogram-ci')
67const project = new ci.Project({
68 appid: 'wxsomeappid',
69 type: 'miniProgram',
70 projectPath: 'the/project/path',
71 privateKeyPath: 'the/privatekey/path',
72 ignores: ['node_modules/**/*'],
73})
74```
75
76| 键 | 类型 | 必填 | 说明 |
77| -------------- | -------- | ---- | -------------------------------------------------------------------------------------------------------- |
78| appid | string | 是 | 合法的小程序/小游戏 appid |
79| projectPath | string | 是 | 项目路径,即 project.config.json 所在的目录 |
80| privateKeyPath | string | 是 | 私钥的路径 |
81| type | string | 否 | 显示指明当前的项目类型, 默认为 miniProgram,有效值 miniProgram/miniProgramPlugin/miniGame/miniGamePlugin |
82| ignores | string[] | 否 | 指定需要排除的规则 |
83
84### 上传
85
86```javascript
87const ci = require('miniprogram-ci')
88;(async () => {
89 const project = new ci.Project({
90 appid: 'wxsomeappid',
91 type: 'miniProgram',
92 projectPath: 'the/project/path',
93 privateKeyPath: 'the/path/to/privatekey',
94 ignores: ['node_modules/**/*'],
95 })
96 const uploadResult = await ci.upload({
97 project,
98 version: '1.1.1',
99 desc: 'hello',
100 setting: {
101 es6: true,
102 },
103 onProgressUpdate: console.log,
104 })
105 console.log(uploadResult)
106})()
107```
108#### 参数
109
110| 键 | 类型 | 必填 | 说明 |
111| ---------------- | -------- | ---- | ------------------------------------- |
112| project | IProject | 是 | #项目对象 |
113| version | string | 是 | 自定义版本号 |
114| desc | string | 否 | 自定义备注 |
115| setting | object | 否 | #编译设置 |
116| onProgressUpdate | function | 否 | 进度更新监听函数 |
117| robot | number | 否 | 指定使用哪一个 ci 机器人,可选值:1 ~ 30 |
118
119#### 返回
120
121| 键 | 类型 | 必填 | 说明 |
122| ---------------- | -------- | ---- | ------------------------------------- |
123| subPackageInfo | Array<{name:string, size:number}> | 否 | 小程序包信息, `name``__FULL__` 时表示整个小程序包, `name``__APP__` 时表示小程序主包,其他情况都表示分包 |
124| pluginInfo | Array<{name:string, version: string, size:number}> | 否 | 小程序插件信息 |
125| devPluginId | string | 否 | 插件开发模式下,上传版本的插件 id |
126
127
128### 预览
129
130```javascript
131const ci = require('miniprogram-ci')
132;(async () => {
133 const project = new ci.Project({
134 appid: 'wxsomeappid',
135 type: 'miniProgram',
136 projectPath: 'the/project/path',
137 privateKeyPath: 'the/path/to/privatekey',
138 ignores: ['node_modules/**/*'],
139 })
140 const previewResult = await ci.preview({
141 project,
142 desc: 'hello',
143 setting: {
144 es6: true,
145 },
146 qrcodeFormat: 'image',
147 qrcodeOutputDest: '/path/to/qrcode/file/destination.jpg',
148 onProgressUpdate: console.log,
149 // pagePath: 'pages/index/index', // 预览页面
150 // searchQuery: 'a=1&b=2', // 预览参数 [注意!]这里的`&`字符在命令行中应写成转义字符`\&`
151 })
152 console.log(previewResult)
153})()
154```
155
156#### 参数
157
158| 键 | 类型 | 必填 | 说明 |
159| ---------------- | -------- | ---- | --------------------------------------------------------------------|
160| project | IProject | 是 | #项目对象 |
161| desc | string | 否 | 自定义备注 |
162| setting | object | 否 | #编译设置 |
163| onProgressUpdate | function | 否 | 进度更新监听函数 |
164| robot | number | 否 | 指定使用哪一个 ci 机器人,可选值:1 ~ 30 |
165| qrcodeFormat | string | 否 | 返回二维码文件的格式 `"image"``"base64"`, 默认值 `"terminal"` 供调试用 |
166| qrcodeOutputDest | string | 是 | 二维码文件保存路径 |
167| pagePath: | string | 否 | 预览页面路径 |
168| searchQuery: | string | 否 | 预览页面路径启动参数 |
169
170#### 返回
171
172| 键 | 类型 | 必填 | 说明 |
173| ---------------- | -------- | ---- | ------------------------------------- |
174| subPackageInfo | Array<{name:string, size:number}> | 否 | 小程序包信息, `name``__FULL__` 时表示整个小程序包, `name``__APP__` 时表示小程序主包,其他情况都表示分包 |
175| pluginInfo | Array<{name:string, version: string, size:number}> | 否 | 小程序插件信息 |
176
177
178
179### 拉取最近上传版本的sourceMap
180
181```javascript
182const ci = require('miniprogram-ci')
183;(async () => {
184 const project = new ci.Project({
185 appid: 'wxsomeappid',
186 type: 'miniProgram',
187 projectPath: 'the/project/path',
188 privateKeyPath: 'the/path/to/privatekey',
189 ignores: ['node_modules/**/*'],
190 })
191 await ci.getDevSourceMap({
192 project,
193 robot: 1,
194 sourceMapSavePath: './sm.zip'
195 })
196})()
197```
198
199#### 入参
200
201| 键 | 类型 | 必填 | 说明 |
202| ---------------- | -------- | ---- | --------------------------------------------------------------------|
203| project | IProject | 是 | #项目对象 |
204| robot | number | 是 | 指定使用哪一个 ci 机器人,可选值:1 ~ 30 |
205| sourceMapSavePath | string | 是 | 保存的路径 |
206
207
208### 构建npm
209对应开发者工具[构建npm](https://developers.weixin.qq.com/miniprogram/dev/devtools/npm.html)功能。
210
211```javascript
212const ci = require('miniprogram-ci')
213;(async () => {
214 const project = new ci.Project({
215 appid: 'wxsomeappid',
216 type: 'miniProgram',
217 projectPath: 'the/project/path',
218 privateKeyPath: 'the/path/to/privatekey',
219 ignores: ['node_modules/**/*'],
220 })
221 // 在有需要的时候构建npm
222 const warning = await ci.packNpm(project, {
223 ignores: ['pack_npm_ignore_list'],
224 reporter: (infos) => { console.log(infos) }
225 })
226 console.warn(warning)
227 // 可对warning进行格式化
228 /*
229 warning.map((it, index) => {
230 return `${index + 1}. ${it.msg}
231 \t> code: ${it.code}
232 \t@ ${it.jsPath}:${it.startLine}-${it.endLine}`
233 }).join('---------------\n')
234 */
235 // 完成构建npm之后,可用ci.preview或者ci.upload
236})()
237```
238
239| 参数 | 类型 | 必填 | 说明 |
240| ---------------- | -------- | ---- | --------------------------------------------------------------------|
241| project | IProject | 是 | 项目对象 |
242| options.ignores | string[] | 否 | 指定构建npm需要排除的规则 |
243| options.reporter | function | 否 | 构建回调信息 |
244
245### 自定义 node_modules 位置的构建 npm
246有的时候,需要被构建模块对应的 `node_modules` 可能并不在小程序项目内,所以提供了一个新的接口来支持这个需求。
247例如有如下项目结构
248
249```text
250├── lib # lib目录存放要被构建的 node_modules
251│ ├── node_modules
252│ │ └── is-object
253│ └── package.json
254└── miniprogram-project # 这里是小程序项目路径
255 ├── miniprogram # 我们希望最终把 miniprogram_npm 构建在 miniprogram/ 目录之下
256 │ ├── app.js
257 │ ├── app.json
258 │ ├── app.wxss
259 │ ├── pages
260 │ │ ├── index
261 │ │ └── logs
262 │ └── sitemap.json
263 └── project.config.json
264```
265
266于是可以这样调用
267
268```javascript
269let packResult = await ci.packNpmManually({
270 packageJsonPath: './lib/package.json',
271 miniprogramNpmDistDir: './miniprogram-project/miniprogram/',
272})
273
274console.log('pack done, packResult:', packResult)
275// 输出 pack done, packResult: { miniProgramPackNum: 0, otherNpmPackNum: 1, warnList: [] }
276```
277
278得到的最终项目
279
280```text
281.
282├── lib
283│ ├── node_modules
284│ │ └── is-object
285│ └── package.json
286└── miniprogram-project
287 ├── miniprogram
288 │ ├── app.js
289 │ ├── app.json
290 │ ├── app.wxss
291 │ ├── miniprogram_npm # <--- 这就是构建出来的由 lib/node_modules 里 miniprogram_npm 了
292 │ ├── pages
293 │ └── sitemap.json
294 └── project.config.json
295```
296
297| 参数 | 类型 | 必填 | 说明 |
298| ---------------- | -------- | ---- | --------------------------------------------------------------------|
299| options.packageJsonPath | string | 是 | 希望被构建的`node_modules` 对应的 `package.json` 的路径 |
300| options.miniprogramNpmDistDir | string | 是 | 被构建 `miniprogram_npm` 的目标位置目标位置 |
301| options.ignores | string[] | 否 | 指定需要排除的规则 |
302
303
304### 代理
305
306miniprogram-ci 使用了 [get-proxy](https://www.npmjs.com/package/get-proxy) 模块来自动获取代理地址。
307如果不适用`ci.proxy()`方法或者`--proxy`参数来指定代理,那么 miniprogram-ci 将会按照以下顺序去获取 https 代理地址
308
3091. 获取环境变量中的 `HTTPS_PROXY`
3102. 获取环境变量中的 `https_proxy`
3113. 获取环境变量中的 `HTTP_PROXY`
3124. 获取环境变量中的 `http_proxy`
3135. 获取npm配置的 `https-proxy`
3146. 获取npm配置的 `http-proxy`
3157. 获取npm配置的 `proxy`
3168. `sercerce_wechat.com` 加入到环境变量中的 `no_proxy`,miniprogram-ci 将不通过代理发送网络请求
317
318```javascript
319const ci = require('miniprogram-ci')
320ci.proxy('YOUR_PROXY_URL')
321```
322
323
324## 命令行调用
325
326```shell script
327npm install -g miniprogram-ci
328```
329
330```shell script
331#help
332miniprogram-ci --help
333
334#preview
335miniprogram-ci \
336 preview \
337 --pp ./demo-proj/ \
338 --pkp ./private.YOUR_APPID.key \
339 --appid YOUR_APPID \
340 --uv PACKAGE_VERSION \
341 -r 1 \
342 --enable-es6 true \
343 --proxy YOUR_PROXY \
344 --qrcode-format image \
345 --qrcode-output-dest '/tmp/x.jpg' \
346
347#upload
348
349miniprogram-ci \
350 upload \
351 --pp ./demo-proj/ \
352 --pkp ./private.YOUR_APPID.key \
353 --appid YOUR_APPID \
354 --uv PACKAGE_VERSION \
355 -r 1 \
356 --enable-es6 true \
357
358#pack-npm
359miniprogram-ci \
360 pack-npm \
361 --pp ./YOUR_PROJECT/ \
362 --pkp ./private.YOUR_APPID.key \
363 --appid YOUR_APPID \
364
365#pack-npm-manually
366miniprogram-ci \
367pack-npm-manually \
368--pack-npm-manually-package-json-path PACKAGE_JSON_PATH \
369--pack-npm-manually-miniprogram-npm-dist-dir DISTPATH
370
371#Proxy
372export HTTPS_PROXY = YOUR_PROXY_URL # 可以在shell脚本里声明临时proxy
373
374miniprogram-ci \
375 upload \
376 --pp ./demo-proj/ \
377 --pkp ./private.YOUR_APPID.key \
378 --appid YOUR_APPID \
379 --uv PACKAGE_VERSION \
380 -r 1 \
381 --enable-es6 true \
382 --proxy YOUR_PROXY_URL # 也可以使用这个参数声明proxy
383
384 #get dev source map
385 miniprogram-ci \
386 get-dev-source-map \
387 --pp ./demo-proj/ \
388 --pkp ./private.YOUR_APPID.key \
389 --appid YOUR_APPID \
390 -r 1 \ # 获取具体哪个robot最近上传的版本的sourceMap
391 --source-map-save-path ./sourcemap.zip #保存路径,推荐zip结尾,最后得到的是一个zip包
392```
393
394
395### 编译设置
396
397| 键 | 类型 | 说明 |
398| -------------- | ------- | ----------------------------------------------------------- |
399| es6 | boolean | 对应于微信开发者工具的 "es6 转 es5" |
400| es7 | boolean | 对应于微信开发者工具的 "增强编译" |
401| minifyJS | boolean | 上传时压缩 JS 代码 |
402| minifyWXML | boolean | 上传时压缩 WXML 代码 |
403| minifyWXSS | boolean | 上传时压缩 WXSS 代码 |
404| minify | boolean | 上传时压缩所有代码,对应于微信开发者工具的 "上传时压缩代码" |
405| codeProtect | boolean | 对应于微信开发者工具的 "上传时进行代码保护" |
406| autoPrefixWXSS | boolean | 对应于微信开发者工具的 "上传时样式自动补全" |
407
408
409## Tips
410
411`miniprogram-ci``1.0.28` 开始支持第三方平台开发的上传和预览,调用方式与普通开发模式无异。
412使用第三方平台开发模式时,应注意:
413- 请确保项目中存在正确的 `ext.json`
414- 密钥文件是第三方平台绑定的开发小程序 `appid` 的密钥文件
415- ip白名单是第三方平台绑定的开发小程序 `appid` 的 ip 白名单
416- 调用传入的 `appid` 是第三方平台绑定的开发小程序 `appid`
417关于第三方平台开发模式,请参考[这里](https://developers.weixin.qq.com/miniprogram/dev/devtools/ext.html)