npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

coscmd

v1.0.8

Published

一个上传本地文件到腾讯云对象存储(COS)的命令行工具

Downloads

15

Readme

coscmd

一个上传本地文件到腾讯云对象存储(COS)的命令行工具

使用场景

  • 希望通过一行简单的命令上传本地文件(夹)到 COS
  • 希望前端项目打包完成后自动把产物上传到 COS(参考下面的最佳实践部分)
  • 希望文件上传完成后自动预热或刷新 CDN 缓存(需使用腾讯云 CDN 并和 COS 绑定)
  • 一次上传到多个 COS 存储桶

环境要求

Node.js v12 及以上版本。

安装

npm i -g coscmd
# 或
yarn global add coscmd

安装太慢?试试 URM

安装完成后,会获得可全局执行的 coscmdcos (简写)命令。

快速入手

执行 cos upload 命令前,你需要至少在腾讯云创建了一个 COS 存储桶,并把相关的配置添加到了 coscmd 的配置文件中。

# 查看 coscmd 中配置的 COS 客户端
cos client list
# 上传本地 index.js 文件到 COS 的 file/index.js 位置
cos upload index.js file/index.js
# 上传本地 dist 文件夹下的全部文件到 COS 的 project/foo 路径下(up 是 upload 的别名)
cos up dist project/foo
# 上传本地 dist 文件夹下的全部 html、js、css 文件到 COS 的 project/foo 路径下
cos up 'dist/**/*.@(html|js|css)' project/foo
# 上传本地 dist 文件夹下的全部非 map 文件到 COS 的 project/foo 路径下
cos up dist project/foo --ignore 'dist/**/*.map'

配置介绍

coscmd 会从命令行参数、当前目录下的 cos.config.js 文件以及用户根目录下的 cos.config.js 文件中解析运行时所需的配置,从而决定如何上传文件。一个典型的 cos.config.js 配置文件如下:

// cos.config.js
module.exports = {
  client: {
    enable: true, // 是否启用
    Bucket: "bucket-xxxx", // COS 存储桶的名称
    Region: "ap-guangzhou", // COS 存储桶所在地域
    SecretId: "***", // 腾讯云 SecretId
    SecretKey: "***", // 腾讯云 SecretKey
    cdn: { domain: "file.example.com" }, // 与 COS 关联的 CDN 的配置(未关联可不填)
  },
  upload: {
    source: "dist/**", // 本地资源,支持单文件、文件夹、glob 表达式
    ignore: ["dist/**/*.map"], // 要忽略文件的 glob 表达式
    cwd: process.cwd(), // 查找 source 时的工作目录,默认是 process.cwd()
    target: "project/foo", // 保存到 COS 的路径,默认是根路径
    rename: false, // 是否对文件进行重命名,如何设置为 true 默认重命名为 16 个小写字母和数字的随机组合,设置为数字可以自定义长度
    flat: false, // 是否铺平文件夹层级
    showProgress: false, // 是否以进度条的形式展示上传过程
    cdnPurgeCache: false, // 是否刷新 CDN 缓存
    cdnPushCache: false, // 是否预热 CDN 缓存
    dryRun: false, // 只模拟上传过程,不实际上传
  },
};

你可以复制这段配置,在自己电脑的用户根目录下创建一个 cos.config.js 文件,来测试一下上面介绍到的 cos upload 命令了,注意把其中的一些值替换为你自己 COS 的配置。

client 字段的作用是配置 COS 客户端及其关联的 CDNupload 字段的作用是配置上传行为。这两个字段可以是一个对象也可以是一个数组,如果是数组,则代表有多个客户端或者有多次不同的上传任务。接下来我们分别详细介绍这两部分的配置。

客户端(client)配置

client 字段的完整 TS 类型定义为如下的 ClientConfig

import { COSOptions } from "cos-nodejs-sdk-v5";
import { ClientConfig as CDNClientConfig } from "tencentcloud-sdk-nodejs/tencentcloud/common/interface";

// COS 存储桶配置
export interface BucketParams {
  Bucket: string;
  Region: string;
}
export interface SingleClientConfig extends BucketParams, COSOptions {
  // 是否启用这个客户端
  enable?: boolean;
  // client 名称,当有多个客户端时可以在执行命令行时通过 --client 参数指定要使用的客户端,不指定,使用全部 enable 的客户端
  name?: string;
  // COS 关联的 CDN 的相关配置
  cdn?: {
    domain: string; // CDN 加速域名
    config?: CDNClientConfig; // 实例化 CDN Client 时的配置参数
  };
}
export type ClientConfig = SingleClientConfig | SingleClientConfig[];

其中 COSOptions腾讯云 COS Node.js SDK 在实例化 COS 客户端时的参数,其中 CDNClientConfig腾讯云 API Node.js SDK 在实例化 CDN 客户端时的参数,cdn.config 如果未指定,默认会复用 COSOptions 中的 SecretIdSecretKey,请保证该密钥同时有 COSCDN 的访问权限。

当前目录下的配置文件优先级高于用户根目录下的配置文件,所以你可以把 client 配置仅保存到用户根目录下的配置文件中,这样可以避免密钥等敏感信息出现在项目代码里。

得益于配置文件是 js,你也可以使用环境变量,比如:

// cos.config.js
module.exports = {
  client: [
    {
      /*...*/
      SecretId: process.env.COS_SECRET_ID, // 腾讯云 SecretId
      SecretKey: process.env.COS_SECRET_KEY, // 腾讯云 SecretKey
    },
  ],
  upload: [
    /*...*/
  ],
};

你甚至可以通过 Promise 异步返回配置:

// cos.config.js
module.exports = async () => {
  await new Promise((resolve) => setTimeout(resolve, 3000));

  return {
    client: [
      /*...*/
    ],
    upload: [
      /*...*/
    ],
  };
};

由于 COS 本身也支持使用临时密钥来初始化,你也可以这样设置

// cos.config.js
const axios = require("axios");

module.exports = {
  client: [
    {
      /*...*/
      // 使用临时密钥初始化 COS,参考 https://cloud.tencent.com/document/product/436/14048
      getAuthorization: function (options, callback) {
        axios({
          method: "POST",
          url: "https://example.com/api/cos/sts", // 伪地址,仅作示例
          data: {
            scope: options.Scope,
          },
        }).then((res) => {
          const data = get(res, "data");
          const credentials = get(data, "credentials");

          if (credentials) {
            callback({
              TmpSecretId: credentials.tmpSecretId,
              TmpSecretKey: credentials.tmpSecretKey,
              SecurityToken: credentials.sessionToken,
              StartTime: data.startTime,
              ExpiredTime: data.expiredTime,
              ScopeLimit: true,
            });
          } else {
            console.error("cos credentials invalid");
          }
        });
      },
    },
  ],
  upload: [
    /* ... */
  ],
};

上传(upload)配置

upload 字段的完整 TS 类型定义为如下的 UploadConfig

import {
  PushUrlsCacheRequest,
  PurgeUrlsCacheRequest,
} from "tencentcloud-sdk-nodejs/tencentcloud/services/cdn/v20180606/cdn_models";

export interface SingleUploadConfig {
  source: string; // 本地资源,支持单文件、文件夹、glob 表达式
  ignore: string[]; // 要忽略文件的 glob 表达式
  cwd?: string; // 查找 source 时的工作目录,默认是 process.cwd()
  target?: string; // 保存到 COS 的路径,默认是根路径
  rename?: boolean | number; // 是否对文件进行重命名,如何设置为 true 默认重命名为 16 个小写字母和数字的随机组合,设置为数字可以自定义长度
  flat?: boolean; // 是否铺平文件夹层级
  showProgress?: boolean; // 是否以进度条的形式展示上传过程
  cdnPurgeCache?: boolean | Omit<PurgeUrlsCacheRequest, "Urls">; // 是否刷新 CDN 缓存
  cdnPushCache?: boolean | Omit<PushUrlsCacheRequest, "Urls">; // 是否预热 CDN 缓存
  dryRun?: boolean; // 只模拟上传过程,不实际上传
  preUpload?: (files: Pick<FileRes, "rPath" | "fullPath" | "cosKey">[]) => Promise<void>; // 开始上传前的钩子
  postUpload?: (uploadRes: UploadRes) => Promise<void>; // 上传完成后的钩子
}
export type UploadConfig = SingleUploadConfig | SingleUploadConfig[];

其中 PurgeUrlsCacheRequestPushUrlsCacheRequest 分别是 腾讯云 API Node.js SDK 在调用 CDN 缓存刷新和 CDN 缓存预热 API 时的参数,其中的 Urls 字段由 coscmd 根据上传的文件自动设置。

upload 字段和 client 字段一样,当前目录下的配置文件优先级高于用户根目录下的配置文件,所以你可以把 upload 配置在项目里,这样就可以为不同的项目设置不同的上传任务了。

upload 字段和 client 字段不同的地方在于,upload 中的值也可以通过命令行参数指定。使用方式如下:

Usage: cos upload|up [options] [source] [target]

上传本地文件到腾讯云 COS

Arguments:
  source             要上传的本地资源,支持单文件、文件夹、glob 表达式
  target             保存到 COS 的路径,默认是根路径

Options:
  --rename [rename]  是否对文件进行重命名,如果为是,默认使用 16 个小写字母和数字的随机组合,指定数字可以自定义长度
  --flat             是否展开文件夹层级
  --show-progress    是否以进度条的形式展示上传过程
  --cdn-purge-cache  是否刷新 CDN 缓存
  --cdn-push-cache   是否预热 CDN 缓存
  --dry-run          只模拟上传过程,不实际上传
  -h, --help         display help for command

支持多种配置方式的好处在于,你可以把可能包含敏感信息的 client 配置保存在用户根目录下,把和上传任务相关的配置保存在项目里或者在运行时指定。这样既方便给不同的项目设置不同的上传任务,也使得你可以在任意位置通过 cos up 命令上传任意文件到 COS 了。

upload 配置的优先级规则

命令行参数中指定的值会覆盖掉配置文件中的 upload 配置。比如配置文件中设置是 rename: false,但是执行的命令是 cos up --renmae,实际上传时文件依然会重命名。

需要注意的是:如果通过命令行指定了 source,那么配置文件中的 upload 就会被忽略。比如 cos up logo.png 就会把本地的 logo.png 上传到 COS 的根目录下,无论当前项目或用户根目录下配置文件中的 upload 是什么。

sourcetarget 介绍

source 支持填写单文件路径、文件夹路径、glob 表达式,解析 glob 表达式依赖的是 glob,其中 dot 和 nodir 参数为 true,注意使用 glob 表达式时,需要加引号。

target 在上传单文件时,如果后缀和 source 相同,则作为文件名,比如 cos up logo.png foo/brand.png 上传后在 COS 中的位置为 foo/brand.png。如果后缀不同或者没有后缀,则作为文件夹,比如 cos up logo.png bar/brand 上传后在 COS 中的位置为 bar/brand/logo.png

target 为文件夹或 glob 表达式时,参考下图中的说明:

image

最佳实践

一、前端项目打包完成后自动上传产物到 COS 并自动预热 CDN 缓存。

  1. 首先在项目中安装 coscmdnpm i coscmd --save-devyarn add coscmd -D
  2. 在项目中添加 coscmd 的运行时配置文件 cos.config.js
  3. 按照前面介绍配置 client 的方式,选择一种安全的方式添加客户端,比如:
const pkg = require("./package.json");

module.exports = {
  client: [
    {
      enable: true,
      Bucket: "bucket-xxxx",
      Region: "ap-guangzhou",
      SecretId: process.env.COS_SECRET_ID, // 从环境变量中读取腾讯云 SecretId
      SecretKey: process.env.COS_SECRET_KEY, // 从环境变量中读取腾讯云 SecretKey
      cdn: { domain: "file.example.com" },
    },
  ],
  upload: [
    {
      source: "dist/**",
      ignore: ["dist/**/*.map"], // 不上传 map 文件
      cwd: __dirname,
      target: `project/${pkg.name}`,
      rename: false,
      flat: false,
      showProgress: false,
      cdnPurgeCache: false,
      cdnPushCache: true, // 上传完成后自动预热 CDN 缓存
      dryRun: false,
      async postUpload() {
        // 上传结束后可以执行一些清理任务
      },
    },
  ],
};
  1. package.json 中 添加 npm scripts,打包完成之后自动执行上传 COS 的任务。
{
  "scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build",
    "postbuild": "cos up"
  }
}

这样配置后,无论是本地打包还是和 CI 流水线集成,都能很方便的管理前端静态资源了。

Tips

  • 执行 cos upload 命令时可以添加 --dry-run 参数,这样 coscmd 只会模拟上传过程,不会实际上传文件,方便查看都有哪些文件会被上传以及上传后的位置是什么了。
  • 设置环境变量 DEBUG=coscmd 可以查看 coscmd 的详细运行日志,包括解析到的配置文件内容,以及每个文件上传时腾讯云返回的错误和响应。
  • 如果配置文件中的 client 数组的长度(enable: true)是 mupload 数组的长度是 n,最终的上传任务数会是 m * n,也就是说,每个客户端都会把每个上传任务执行一次。
  • 当配置文件中有多个 enable 的客户端时,在执行命令时,可以使用 --client 或者 -c 参数指定要使用的客户端。不指定则全部 enable 的客户端都会生效。
  • 可以使用 --config-file 参数指定配置文件路径。

Star 趋势

Stargazers over time