Logo

site iconHCLonely

爱好: JavaScript, 动漫,游戏,小说
请复制 RSS 到你的阅读器,或快速订阅到 :

Inoreader Feedly Follow Feedbin Local Reader

HCLonely RSS 预览

将 Node.js 项目打包为一个可执行文件

2024-03-05 11:22:49

简介

Node.js 从v18.16.0,v19.7.0版本开始原生支持了打包为可执行文件(Single executable applications), 常用的打包工具pkg也因此不在更新,下面介绍一下我在使用 NodeJs Single executable applications功能时的一些经验和问题。

使用

创建并打包你的项目文件

因为目前该功能只能将单个 js 文件封装为可执行文件,所以我们要借助打包工具(如 webpack, rollup 等)将 js 项目大包围一个 js 文件。由于 wenpack 的配置过于繁杂,这里介绍使用 rollup 工具进行打包。

  1. 安装 rollup: npm install --global rollup;

  2. 在项目根目录新建rollup.config.js文件,内容如下(根据项目内容进行调整):

    const commonjs  = require('@rollup/plugin-commonjs'); // commonjs支持,使用es模块可不使用此插件,安装:npm install @rollup/plugin-commonjs -Dconst { nodeResolve } = require('@rollup/plugin-node-resolve');const json = require('@rollup/plugin-json'); // 将静态json文件作为模块导入,按需安装,安装:npm install @rollup/plugin-json -Dconst { string } = require('rollup-plugin-string'); // 将静态文件文本作为模块导入,按需安装,安装:npm install @rollup/plugin-json -Dconst terser = require('@rollup/plugin-terser');// 压缩打包后的文件大小,按需安装,安装:npm install @rollup/plugin-json -Dmodule.exports = {  input: 'dist/main.js', // 项目入口文件  output: {    dir: 'output', // 输出文件目录    format: 'cjs' // 输出文件格式  },  plugins: [terser({    format: {      comments: false    }  }), nodeResolve({    preferBuiltins: true,    exportConditions: ['node']  }),  commonjs(),  json(),  string({    include: ['**/*.html', '**/*.yml']  })]};
  3. 打包项目:rollup -c

封装为可执行文件

  1. 在项目根目录新建your-project-config.json文件,内容如下(根据项目需求进行调整,官方说明):

    {  "main": "output/main.js", // 打包后的项目入口文件  "output": "your-project.blob",  "disableExperimentalSEAWarning": true,  "useCodeCache": true,  "disableExperimentalSEAWarning": true, // 禁用Nodejs的试验性更能警告  "useSnapshot": false,  // 使用快照  "useCodeCache": true // 使用代码缓存}
  2. 封装文件:

    • Windows:
    node --experimental-sea-config your-project-config.jsonnode -e "require('fs').copyFileSync(process.execPath, 'your-project.exe')"npx postject your-project.exe NODE_SEA_BLOB your-project.blob --sentinel-fuse NODE_SEA_FUSE_fce680ab2cc467b6e072b8b5df1996b2
    • Linux:
    node --experimental-sea-config your-project-config.jsoncp $(command -v node) your-projectnpx postject your-project.exe NODE_SEA_BLOB your-project.blob --sentinel-fuse NODE_SEA_FUSE_fce680ab2cc467b6e072b8b5df1996b2
  3. 等待封装完成。

哔哩哔哩硬核会员搜题脚本

2023-05-29 21:11:39

一个用于哔哩哔哩硬核会员搜题的 Tampermonkey 脚本。

安装

  1. 安装Tampermonkey(建议)或其他脚本管理器;
  2. 点此安装搜题脚本。

使用

  1. 手机哔哩哔哩客户端进入答题;
  2. 浏览器登录哔哩哔哩(已登录可跳过此步骤);;
  3. 浏览器打开调试工具(F12), 将浏览器切换为移动设备(Ctrl+Shift+M);
  4. 在地址栏输入https://www.bilibili.com/h5/senior-newbie/qa并回车,等待网页加载完成;
  5. 启动脚本(Alt+N);
    • 加载题库(需要题目完全匹配):可从本地加载题库(支持txt,doc,docx,xls,xlsx格式),题库中搜索不到则使用搜索引擎搜索
    • 直接运行:使用搜索引擎搜索(支持百度搜狗必应谷歌)
  6. 点击题目即可进行搜索。

注意事项

  1. 使用此脚本时建议关闭其他插件/脚本,避免冲突;
  2. 建议选择文史知识音乐等答案比较好搜索判断的类型。

在静态网站上实现浏览记录功能

2023-02-03 17:29:56

在静态网站上实现浏览记录功能,浏览记录保存在用户本地

安装

  1. 下载visit-history.min.js文件;

  2. 在你的网页中插入

    <script src="path/to/visit-history.min.js"></script>

或直接使用CND

<script src="https://cdn.jsdelivr.net/gh/HCLonely/[email protected]"></script>

使用

保存浏览记录

const { visitHistory } = require('visit-history');visitHistory.set({  data: { }, // [必需]保存的数据  identifier: () => window.location.pathname, // [可选]网页的位移标识符, 默认为 () => window.location.pathname  limit: 20 // [可选]最大保存的浏览历史数量,默认为 20});

Example:

const { visitHistory } = require('visit-history');visitHistory.set({  data: {    title: document.querySelector('title').innerText.trim(),    link: window.location.href  },  identifier: () => window.location.href,  limit: 30});

读取浏览记录

const { visitHistory } = require('visit-history');visitHistory.get({  htmlTemplate: '', // [可选]Html模板, 使用'{{key}}'替换data中的变量. 留空则返回保存的data数据, 默认为空  limit: 10 // [可选]读取的浏览记录数量, 留空则返回所有数据, 默认为空});

Example:

const { visitHistory } = require('visit-history');const history = visitHistory.get({  htmlTemplate: '<div class="title><a href="{{link}}">{{title}}</a></div>',  limit: 10});document.querySelector('.history').innerHTML = history.join('');

鸣谢

统一推送服务Nodejs API

2022-12-21 15:32:55

介绍

注意:此模块仅作推送使用,不可交互 !!!

统一化推送服务Nodejs API. 已支持钉钉, Discord, 邮件, 飞书, PushDeer, PushPlus, QQ, QQ 频道机器人, Server 酱, Showdoc Push, Telegram Bot, 企业微信群机器人, 息知, WxPusher, NowPush, iGot, Chanify, Bark, Push, Slack, Pushback, Zulip, RocketChat, Gitter等平台.

已支持平台

安装

npm install all-pusher-api -S

使用

Example

多平台推送

const { PushApi } = require('all-pusher-api'); // 多平台同时推送(async () => {  console.log((await new PushApi([    {      name: 'ServerChanTurbo',      config: {        key: {          token: '******'        }      }    },    {      name: 'PushDeer',      config: {        key: {          token: '******'        }      }    },    {      name: 'WxPusher',      config: {        key: {          token: '******',          uids: ['******']        }      }    }  ])    .send({ message: '测试文本' })).map((e) => (e.result.status >= 200 && e.result.status < 300) ? `${e.name} 测试成功` : e));})();

单平台推送

(async () => {  // Example 1  const { PushApi } = require('all-pusher-api'); // 多平台同时推送  const result = await new PushApi([    {      name: 'ServerChanTurbo',      config: {        key: {          token: '******'        }      }    }  ])    .send({ message: '测试文本' });  console.log(result.map((e) => (e.result.status >= 200 && e.result.status < 300) ? `${e.name} 测试成功` : e));  // Example 2  const { WxPusher } = require('all-pusher-api/dist/WxPusher'); // 单平台推送可选  const wxPusherResult = await new WxPusher({    token: '******',    uids: ['******']  })    .send({ message: '测试文本' });  console.log(wxPusherResult);})();

extraOptions

(async () => {  const { DingTalk } = require('all-pusher-api/dist/DingTalk');  const result = await new DingTalk({    key: {      token: '******',      secret: '******'    }  })    .send({      message: '这条消息@了所有人',      extraOptions: {        isAtAll: true      }    });  console.log(result);})();

customOptions

这里以钉钉为例

(async () => {  const { DingTalk } = require('all-pusher-api/dist/DingTalk');  const result = await new DingTalk({    key: {      token: '******',      secret: '******'    }  })    .send({      customOptions: {        "msgtype": "actionCard",        "actionCard": {          "title": "我 20 年前想打造一间苹果咖啡厅, 而它正是 Apple Store 的前身",          "text": "![screenshot](https://img.alicdn.com/tfs/TB1NwmBEL9TBuNjy1zbXXXpepXa-2400-1218.png) \n\n #### 乔布斯 20 年前想打造的苹果咖啡厅 \n\n Apple Store 的设计正从原来满满的科技感走向生活化, 而其生活化的走向其实可以追溯到 20 年前苹果一个建立咖啡馆的计划",          "btnOrientation": "0",          "btns": [            {                "title": "内容不错",                "actionURL": "https://www.dingtalk.com/"            },            {                "title": "不感兴趣",                "actionURL": "https://www.dingtalk.com/"            }          ]        }      }    });  console.log(result);})();

自定义接口

(async () => {  const { Custom } = require('all-pusher-api/dist/Custom'); // 自定义接口只能通过此方法引入  const { createHmac } = require('crypto'); const sign = () => {    const timestamp = new Date().getTime();    const secret = '******';    const stringToSign = `${timestamp}\n${secret}`;    const hash = createHmac('sha256', secret)      .update(stringToSign, 'utf8')      .digest();    return `timestamp=${timestamp}&sign=${encodeURIComponent(hash.toString('base64'))}`;  };  console.log(await new Custom({    url: `https://oapi.dingtalk.com/robot/send?access_token=******&${sign()}`,    success: {      key: 'responseData.errcode',      value: 0    }  }).send({    msgtype: 'text',    text: {      content: '测试文本'    }  }));  /* 返回值  {    status: 200,    statusText: 'Success',    extraMessage: <AxiosResponse>  }  */});

参数

pusherConfig

这部分写的比较乱,建议配合参数生成器使用!

const pusher = new WxPusher(pusherConfig);

参数 类型 默认值 说明
token string null 大部分平台的授权token, 如果有授权信息有多个, 请使用key
baseUrl string null 对于部分支持搭建服务端的平台, 如果使用自建服务端, 需配置此选项
webhook string null Discord, 企业微信机器人, RocketChatGoogleChat 的 webhook 地址, 该平台请使用webhook而不是token
userId string null Pushback 平台的 User_id
chat_id string null Telegram 平台的 chat_id
email string null Zulip 平台的 bot email
domain string null Zulip 平台的 domain
to Array<number\|string> null Zulip 平台的发送对象
roomId string null Gitter 平台发送对象的 roomid
baseUrl string null go-cqhttp 的http通信地址, 以http://https://开头
user_id number null 使用 go-cqhttp 推送时的目标 QQ 号, 此参数与group_id, channel_id二选一
group_id number null 使用 go-cqhttp 推送时的目标群号, 此参数与user_id, channel_id二选一
channel_id string null 使用 go-cqhttp 推送时的目标频道ID, 此参数与user_id, group_id二选一, 且必须与guild_id同时存在
guild_id string null 使用 go-cqhttp 推送时的目标子频道ID, 此参数必须与channel_id同时存在
corpid string null 企业微信群机器人的corpid
agentid string null 企业微信群机器人的agentid
secret string null 钉钉、飞书加签的密钥[可选]/企业微信群机器人的secret
touser string null 企业微信群机器人指定接收消息的成员, 也可在sendOptions中配置
uids Array<string> null WxPusher 发送目标的 UID, 也可在sendOptions中配置
topicIds Array<number> null WxPusher 发送目标的 topicId, 也可在sendOptions中配置
appID string null QQ频道机器人的 ID, 使用QQ频道推送时此选项为必选
token string null QQ频道机器人的 token, 使用QQ频道推送时此选项为必选
sandbox boolean false 使用QQ频道推送时是否启用沙箱, 可选
channelID string null QQ频道的子频道 ID, 使用QQ频道推送时此选项为必选
user string null Pushover 的 user key, 使用 Pushover 推送时此选项为必选
key object null 以上参数都可以放到key中, 示例
- key.host string null 邮件发送服务器地址, 使用邮件推送时此选项为必选
- key.port number null 邮件发送服务器端口, 使用邮件推送时此选项为必选
- key.secure boolean false 邮件发送服务器是否启用TLS/SSL, 可选
- key.auth object null 邮件发送服务器的验证信息, 使用邮件推送时此选项为必选
- key.auth.user string null 邮件发送服务器的用户名, 使用邮件推送时此选项为必选
- key.auth.pass string null 邮件发送服务器的密码, 使用邮件推送时此选项为必选
proxy object null 代理配置, 可选, 部分支持
- proxy.enable boolean false 是否启用代理
- proxy.protocol string 'http' 代理协议
- proxy.host string null 代理主机地址
- proxy.port number null 代理端口
- proxy.username string null 代理用户名
- proxy.password string null 代理密码

CustomConfig

自定义接口

const customPusher = new Custom(CustomConfig);

参数 类型 默认值 说明
url string null 请求链接, 必需
method string 'POST' 请求方式, 可选
contentType string 'application/json' 发送的数据类型, 等同于hreders['Content-type']
headers AxiosRequestHeaders null 请求头, 可选
success object null 推送成功的判断方式, 必需
- success.key string null 请看示例
- success.value any null 请看示例
key object null 以上参数都可以放到key中
proxy object null 代理配置, 同上

pushersConfig

const pushers = new PushApi(pushersConfig);

const pushersConfig: Array<{  name: string,  config: pusherConfig}>

sendOptions

const result = await pusher.send(sendOptions);

参数 类型 默认值 说明
message string null 推送的消息内容, messagecustomOptions至少要有一个
title string null 部分平台支持消息标题, 不填则自动提取message第一行的前10个字符
type string 'text' 仅支持text, markdown, html. 具体平台支持情况请查看支持的消息类型
extraOptions object null 附加内容, 此对象中的内容会附加到请求体中, 示例
customOptions object null 自定义请求内容, 推送时会POSTcustomOptions, 示例

customSendOptions

const result = await customPusher.send(customSendOptions);

customSendOptions会直接作为请求体发送, 具体请查看示例.

pushersSendConfig

const results = await pushers.send(pushersSendConfig);

const pushersSendConfig: Array<{  name: string  config: pushersSendConfig}>

返回值

result

const result = await pusher.send(sendOptions);

参数 类型 默认值 说明
status number null 状态码
statusText string null 状态说明文本
extraMessage AxiosResponse Error null

results

const results = await pushers.send(pushersSendConfig);

const results: Array<{  name: string  result: result}>

支持的消息类型

所有平台支持均纯文本(text)格式消息, 大部分支持markdown格式消息, 部分支持html格式消息

markdown*为支持html格式不支持markdown格式消息时自动将markdown转换为html格式

other为部分平台支持特殊格式的消息, 可通过customOptions传入参数, 具体参数请查看相应平台的文档

  • Showdoc: text
  • Pushover: text
  • QQ(go-cqhttp): text, other
  • Qmsg: text, other
  • Discord: text, other
  • 飞书: text, other
  • NowPush: text, other
  • Chanify: text, other
  • Bark: text, other
  • Server酱Turbo: text, markdown
  • 息知: text, markdown
  • PushDeer: text, markdown, other
  • QQ频道: text, markdown, other
  • 企业微信: text, markdown, other
  • 企业微信群机器人: text, markdown, other
  • 钉钉: text, markdown, other
  • TelegramBot: text, markdown, html
  • 邮件: text, markdown*, html
  • PushPlus: text, markdown*, html
  • WxPusher: text, markdown*, html

状态码

  • 0-Missing Parameter: ***: 缺少必要参数
  • 10-Missing Options: 缺少发送消息配置
  • 11-Unknown Error: 未知错误
  • 200-Success: 推送成功
  • 201-Waiting: 待审核
  • 100-Error: 请求发送成功, 服务器返回错误信息
  • 101-No Response Data: 请求发送成功, 但没有接收到服务器返回的数据
  • 102-Request Error: 请求发送失败, 一般是网络问题
  • 103-Options Format Error: 参数格式错误
  • 104-Get "***" Failed: 获取参数失败
  • 140-Check Sign Failed: 签名校检失败

在线答题搜答案脚本

2022-04-05 23:12:09

想必大家都经历过学校/公司要求在网上答题的情况,为了更方面的搜索答案,于是这个脚本就出现了。

安装说明

  1. 安装Tampermonkey或类似浏览器扩展(脚本基于此扩展使用)

  2. 安装此脚本

必读说明

  • 不用时请关闭此脚本!
  • 启用此脚本后刷新网页才会生效!
  • 使用无题库模式时不要将弹出的窗口最大化
  • 支持txt, html, word, excel格式的题库,其他格式自行转换成支持的格式
  • 选择/复制受限时可配合网页限制解除(改)脚本使用

使用说明

  1. 使用前先在Tampermonkey中启用此脚本;

  2. 点击浏览器的Tampermonkey扩展图标,找到此脚本下面的启动启动选项并点击;

  3. 按要求选择模式

    • 题库模式[建议]: 如果你已经有该题目相关题库了就选这个,题库文件支持txt, html, word, excel格式,其他格式的题库请自行转换成支持的格式;
    • 无题库模式: 搜索时会弹出使用百度/搜狗/必应/谷歌的搜索结果,弹出的窗口不要全屏显示;
    • 直接运行: 之前使用题库模式导入过题库,并且题库不需要更新,避免重复导入题库操作;
  4. 选择题目后会弹出按钮,点击此按钮即可搜索;

  5. 用完记得关闭此脚本,否则可能会造成访问其他网页出现BUG;