在托管至 GitHub 的原生微信小程序工程上实现对 npm 依赖库的开放源代码许可证信息半自动化生成
此仓库所有文档采用木兰开放作品许可协议 署名-相同方式共享,第1版许可,代码采用木兰宽松许可证, 第2版许可。
如果您的微信小程序工程非原生微信小程序工程(如 Uni-App、Taro 等跨平台工程,或 Vite、Webpack、Rollup 等构建工具工程),请优先考虑使用诸如 rollup-license-plugin、webpack-license-plugin 等插件。此仓库所列举的方案只能实现半自动化生成开放源代码许可证信息,而使用 Vite、Webpack、Rollup 等构建工具及其插件可实现全自动编译产物构建。
首先需确保本地存在 Node.js 和 npm 环境。若还未安装,请前往 Node.js 官网按指导进行安装,这里不再赘述。下文假定您已安装 Node.js 和 npm。
在原生微信小程序工程根目录(即微信小程序 project.config.json
所在目录)中打开终端,安装 license-checker-rseidelsohn
、shelljs
、uglify-js
、json5
和 spdx-license-list
依赖
npm
npm install license-checker-rseidelsohn shelljs uglify-js json5 spdx-license-list --save-dev
Yarn
yarn add license-checker-rseidelsohn shelljs uglify-js json5 spdx-license-list --dev
pnpm
pnpm add license-checker-rseidelsohn shelljs uglify-js json5 spdx-license-list --dev
将 OSSLicensesBuilder.js
、OSSLicensesBuilderConfig.json5
和 OSSLicensesBuildFormat.json
文件下载并移动至微信小程序工程根目录(即微信小程序 project.config.json
所在目录),并执行命令:
npm pkg set scripts.build-oss-licenses-dist="node OSSLicensesBuilder.js"
或直接在根目录 package.json
新增:
{
"scripts": {
"build-oss-licenses-dist": "node OSSLicensesBuilder.js"
}
}
package.json
完整示例
package.json
完整示例{
"dependencies": {},
"devDependencies": {
"license-checker-rseidelsohn": "^4.4.2",
"json5": "^2.2.3",
"shelljs": "^0.8.5",
"spdx-license-list": "^6.9.0",
"uglify-js": "^3.19.3"
},
"scripts": {
"build-oss-licenses-dist": "node OSSLicensesBuilder.js"
}
}
此时执行
npm run build-oss-licenses-dist
命令,则会在微信小程序工程根目录生成 OSSLicensesDist.js
和 OSSLicensesDistText.js
文件。开放源代码许可信息由 module.exports
语句导出为 JS 对象。
为缩减文件大小,防止文件内存在过多重复的许可证文本,脚本将生成两个文件:
OSSLicensesDist.js
:包含所有依赖项许可证信息的 JavaScript 文件OSSLicensesDistText.js
:包含所有许可证文本的 JavaScript 文件
OSSLicensesDist.js
中的子项将存在 licenseTextHash
字段,该字段的值为许可证文本的 SHA256 杂凑值,可在 OSSLicensesDistText.js
中作为键找到。
如果您希望将 OSSLicensesDist.js
文件放在具体 Page 页或其他自定义目录,请在 OSSLicensesBuilderConfig.json5
文件中修改 customPath
属性,如:
[
{
outputFile: "OSSLicensesDist",
customFormat: "OSSLicensesBuildFormat.json",
customPath: "/this-is-my-goal-page/my-assets/",
}
]
如果您的微信小程序使用了分包,并由于分包而在多个子包存在 npm 依赖项,希望一并生成子包的开放源代码许可信息,则可在 OSSLicensesBuilderConfig.json5
文件中新增配置,如:
[
{
outputFile: "OSSLicensesDist",
customFormat: "OSSLicensesBuildFormat.json",
customPath: "/"
},
{
outputFile: "OSSLicensesDistSub1",
customFormat: "OSSLicensesBuildFormat.json",
customPath: "/",
startPath: "subpackage1/"
},
{
outputFile: "OSSLicensesDistSub2",
customFormat: "OSSLicensesBuildFormat.json",
customPath: "/",
startPath: "subpackage2/"
}
]
此时执行 npm run build-oss-licenses-dist
命令,则会在微信小程序工程根目录生成 OSSLicensesDist.js
、OSSLicensesDistText.js
、OSSLicensesDistSub1.js
、OSSLicensesDistSub1Text.js
、OSSLicensesDistSub2.js
和 OSSLicensesDistSub2Text.js
文件。可按需使用。
可选:OSSLicensesBuildFormat.json 配置
OSSLicensesBuildFormat.json
用于自定义 license-checker-rseidelsohn
对生成的开放源代码信息文件的构建格式,如仓库示例:
{
"name": "",
"repository": "",
"publisher": "",
"email":"",
"version": "",
"description": "",
"licenses": "",
"licenseText": "",
"path": false,
"licenseFile": false,
"copyright": false
}
若属性设置为 false
,则不会在生成的开放源代码信息文件中生成该属性。若非 false
,则填入值为占位默认值。
举例来说,假设为 "email"
属性填入值为 "異議あり!"
如果 license-checker-rseidelsohn
未在某个 npm 依赖包中找到此包作者的 email
信息,则会对生成的开放源代码信息文件中的此项包的 email
属性值设置为 "異議あり!"
。
有效属性为:
copyright
:版权声明信息,如 “Copyright (c) 年份 作者名 作者连接”description
:描述email
:邮箱licenseFile
:此依赖项在本地计算机中的开源许可文件所在的本地路径字符串。由于对用户端来说本地路径没有什么实质作用,且考虑到微信小程序文件总大小限制,不建议生成此项。path
:同上,不建议生成此项。licenseModified
licenses
:开源许可 SPDX ID。OSSLicensesBuilder.js
会根据 SPDX ID 一并生成licenseName
字段,该字段的值为开源许可名称(SPDX Name)。licenseText
:开源许可全文。为缩减文件大小,防止文件内存在过多重复的许可证文本,脚本会将此字段改为licenseTextHash
字段,该字段的值为许可证文本的 SHA256 杂凑值,可在OSSLicensesDistText.js
中作为键找到。name
:依赖项名称publisher
:依赖项发布者repository
:开源仓库地址url
:依赖项地址,大多数情况下此项为空version
:依赖项的语义版本号
在 GitHub 仓库根目录新建 .github
目录,打开 .github
目录后,新增 workflows
目录。
将 update-oss-licenses-dist.yml
下载并移动至 .github/workflows
目录。
下载的 update-oss-licenses-dist.yml
默认采用 windows-latest
为工作流运行环境:
jobs:
update-oss-licenses-dist:
strategy:
matrix:
os: [ windows-latest ] # 请根据您的微信小程序开发环境配置相应(如 `macos-latest`、`ubuntu-latest` 等),因为部分 npm 包在不同系统环境下分发的包不一致
runs-on: ${{ matrix.os }}
由于部分 npm 包在不同系统环境下分发的包不一致,请根据您的实际情况修改 update-oss-licenses-dist.yml
文件。例如:
- 如果您的微信小程序使用
miniprogram-ci
构建,请根据构建服务器选择运行环境。例如假设miniprogram-ci
在 Linux 系统下工作,请将matrix
.os
改为ubuntu-latest
。 - 如果您在 Windows 上使用微信开发者工具构建与上传,请将
matrix
.os
改为windows-latest
。 - 如果您在 macOS 上使用微信开发者工具构建与上传,请将
matrix
.os
改为macos-latest
。
将包含 .github/workflows/update-oss-licenses-dist.yml
的提交推送至 GitHub 仓库后,默认情况下,此工作流会自动在每次提交后运行。如果工作流内生成的开源许可信息文件与仓库原有的开源许可信息文件不一致,则此工作流会将新的开放源代码许可信息文件生成一个 Pull Request。
由于生成的开源许可信息 JavaScript 文件已经由 module.exports
导出为 JS 对象,因此您可以在微信小程序中直接引用此文件。例如:
// SPDX-License-Identifier: MulanPSL-2.0
// 假设这是 pages/oss-licenses-menu/oss-licenses-menu.js
// 如果存在分包,需要多次引入相关对象,这里不再赘述
const ossLicensesDist = require('../../OSSLicensesDist.js')
// 以 `Page()` 页面构造器为例
Page({
data: {},
onLoad(options) {
console.log(ossLicensesDist)
// 由对应页面 WXML 属性绑定此数据并向用户端展示信息
this.setData({
ossLicensesDist: ossLicensesDist
})
}, licenseDistClick(e) {
// 点击开源许可信息项,跳转到对应开源许可信息页面。对应开源许可信息页面的具体写法此文档不再赘述。
wx.navigateTo({
url: '/pages/oss-licenses/oss-licenses?index=' + e.currentTarget.dataset.index,
})
// **提醒**:
// 如需展示许可证全文文本,请在常量 `ossLicensesDist` 找到该项的 `licenseTextHash` 字段的值,
// 然后引入 `OSSLicensesDistText.js`,
// 将上述 `licenseTextHash` 的值作为键在 `OSSLicensesDistText.js` 中找到此键的值,值即为许可证文本。
}
})
<!-- SPDX-License-Identifier: MulanPSL-2.0 -->
<!-- 假设这是 pages/oss-licenses-menu/oss-licenses-menu.wxml -->
<!-- 假设项目引入了 TDesign 微信小程序组件库,并引入了其中的 `t-cell` 和 `t-tag` 组件 -->
<!-- 为方便展示样式表,这里假设项目引入了 UnoCSS。具体样式声明可在下列元素的 class 中查看 -->
<t-cell arrow bind:tap="licenseDistClick" data-index="{{index}}" description="{{item.description}}" hover
wx:for="{{ossLicensesDist}}" wx:key="index">
<view slot="title">
<!-- 依赖项名称与作者 -->
<text class="text-32rpx inline">{{item.name + (item.publisher !== '' ? (' (' + item.publisher + ')') : '')}}</text>
</view>
<view class="inline" slot="description">
<!-- 依赖项语义版本号。展示版本号以防止因部分依赖项在项目迭代过程存在开源许可变更导致的同项目许可混淆 -->
<t-tag class="mr-16rpx mt-12rpx inline-block" size="medium" theme="default" variant="light">
{{item.version}}
</t-tag>
<!-- 依赖项开源许可名称 -->
<!-- 如果需要界面展示更简短的名称(SPDX ID),可将 `item.licenseName` 改为 `item.licenses` -->
<t-tag class="mt-12rpx inline-block" size="medium" theme="primary" variant="light">
{{item.licenseName}}
</t-tag>
</view>
</t-cell>
此仓库的诞生离不开以下开源项目,感谢以下开源项目的作者和贡献者:
- NPM License Checker(Roman Seidelsohn),Licensed under BSD 3-Clause License
- ShellJS,Licensed under BSD 3-Clause License
- UglifyJS,Licensed under BSD License
- JSON5,Licensed under MIT License
- List of SPDX licenses(Sindre Sorhus),Licensed under CC0 1.0 Universal License
- TDesign WeChat MiniProgram(Tencent),Licensed under MIT License
- Node.js®(OpenJS Foundation),Licensed under MIT License
- npm,Licensed under Artistic License 2.0
- UnoCSS,Licensed under MIT License