vite 和 cesium

CesiumJS是一个开源的JavaScript库,用于在web浏览器中创建3D地球仪和2D地图,而无需插件。它将WebGL用于硬件加速图形,并且是跨平台、跨浏览器的,并针对动态数据可视化进行了调整。来自百度百科

更具cesium的官方教程,你可能需要配置才能正常使用 cesium。

在 vite 的社区插件,我们可以找到 vite-plugin-cesium ,它能够快速搭建 cesium 的开发环境。

npm i vite-plugin-cesium -D

在 vite.config.ts 中添加插件

import { defineConfig } from 'vite';
import cesium from 'vite-plugin-cesium'; // 引入插件
export default defineConfig({
    plugins: [cesium()],
});

centos 安装 nodejs

yum install epel-release

EPEL (Extra Packages for Enterprise Linux)是基于Fedora的一个项目,为“红帽系”的操作系统提供额外的软件包,适用于RHEL、CentOS和Scientific Linux.

我们在Centos下使用yum安装时往往找不到rpm的情况,官方的rpm repository提供的rpm包也不够丰富,很多时候需要自己编译很痛苦,而EPEL恰恰可以解决这两方面的问题。EPEL的全称叫 Extra Packages for Enterprise Linux 。EPEL是由 Fedora 社区打造,为 RHEL 及衍生发行版如 CentOS、Scientific Linux 等提供高质量软件包的项目。装上了 EPEL之后,就相当于添加了一个第三方源。

yum install nodejs
yum install npm

nodejs 版本控制 for windows

可以解决多个项目依赖不同的nodejs版本问题 仓库地址

进入仓库 > Releases > 找到最新的版本 > 下载 nvm-setup.exe > 安装

如果之前安装过nodejs,建议先卸载之后在安装 nvm,全程使用 nvm 管理即可。

基本命令

# 下载最新版
nvm install latest
# 下载 14 大版本
nvm install 14
# 切换版本
nvm use 14

install 默认从 github 下载,即需要 vpn ,也可以尝试更改镜像使用。

# 阿里云
nvm npm_mirror https://npmmirror.com/mirrors/npm/
nvm node_mirror https://npmmirror.com/mirrors/node/
# 腾讯云
nvm npm_mirror http://mirrors.cloud.tencent.com/npm/
nvm node_mirror http://mirrors.cloud.tencent.com/nodejs-release/

rollup 开发 ts 模块总结

使用 rollup.config.ts 文件作为 rollup 的配置

tsconfig.json
    "module": "esnext",   

    "moduleResolution": "node",  
你需要的开发依赖是
"@rollup/plugin-typescript": "^11.0.0",
"tslib": "^2.4.1",
"typescript": "^4.9.4"
版本为示例版本,建议安装最新的。
output配置

建议同时输出 es 和 cjs 两个格式

# rollup.config.ts
output: [
        {
            file: './dist/bundle.ejs',
            format: 'es',
        },
        {
            file: './dist/bundle.cjs',
            format: 'cjs',
        }
    ]

在 package.json 中配置

  "main": "./dist/bundle.cjs",
  "module": "./dist/bundle.ejs",

这样即可使用 require 导入 ,也可以使用 import 导入。

编译脚本
# package.json
"scripts": {
    "build": "rollup --config rollup.config.ts --configPlugin typescript"
  },

编译类型声明文件

在 rollup.config.ts 的插件中配置如下

plugins: [
        del({targets: 'dist/*'}),
        typescript({
            compilerOptions: {declaration: true, outDir: './dist'},
            include: "src/**/*"
        })
    ],

排除模块

在 rollup.config.ts 的插件中配置如下

// input
// output
// plugins
external: ['axios']

建议依赖格式

"peerDependencies": {
    "axios": "^1.2.2"
  }

使用 jest 测试

需要的依赖:
jest
@types/jest

防止编译test目录,可以这样做

# rollup.config.ts
plugins: [
        del({targets: 'dist/*'}),
        typescript({
            compilerOptions: {declaration: true, outDir: './dist'},
            include: "src/**/*"
        })
    ],

nginx 不同路径代理不同地址

有这样的需求,www.domain.com/a 代理到 A 地址。www.domain.com/b 代理到 B 地址。

可以通过 nginx 实现。配置不是很复杂。

    # A
    location /a{
      proxy_pass http://www.other1.com:80/;
    }
    # B
    location /b { 
      proxy_pass http://www.other1.com:80/;
    }

proxy_pass 后面的url加上了/,相当于是绝对根路径,则nginx不会把location中匹配的路径部分代理走。如果没有/,则会把匹配的路径部分也给代理走

访问的时候,不可省略最后一个 /,比如访问 A 时,地址为 www.domain.com/a/

如果可以,建议网站地址为 http://www/domain.com/a/index.html

drone email 插件自定义邮件内容

# .drone.yml 下的 steps
  - name: notify #邮件通知
    image: drillster/drone-email
    settings:
      host: smtp.qiye.aliyun.com
      port: 465
      username:
        from_secret: email_username
      password:
        from_secret: email_password
      from:
        from_secret: email_username
      recipients:
        - postmaster@codeon.cn

      body: file:///drone/src/email/body.html

drone/src 表示项目所在目录

file 协议必须从根目录开始

需要默认模板请参考这里

只需复制 DefaultTemplate 变量的内容即可

# /drone/src/email/body.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <meta name="viewport" content="width=device-width" />
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <style>
      * {
        margin: 0;
        padding: 0;
        font-family: "Helvetica Neue", "Helvetica", Helvetica, Arial, sans-serif;
        box-sizing: border-box;
        font-size: 14px;
      }
      body {
        -webkit-font-smoothing: antialiased;
        -webkit-text-size-adjust: none;
        width: 100% !important;
        height: 100%;
        line-height: 1.6;
        background-color: #f6f6f6;
      }
      table td {
        vertical-align: top;
      }
      .body-wrap {
        background-color: #f6f6f6;
        width: 100%;
      }
      .container {
        display: block !important;
        max-width: 600px !important;
        margin: 0 auto !important;
        /* makes it centered */
        clear: both !important;
      }
      .content {
        max-width: 600px;
        margin: 0 auto;
        display: block;
        padding: 20px;
      }
      .main {
        background: #fff;
        border: 1px solid #e9e9e9;
        border-radius: 3px;
      }
      .content-wrap {
        padding: 20px;
      }
      .content-block {
        padding: 0 0 20px;
      }
      .header {
        width: 100%;
        margin-bottom: 20px;
      }
      h1, h2, h3 {
        font-family: "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif;
        color: #000;
        margin: 40px 0 0;
        line-height: 1.2;
        font-weight: 400;
      }
      h1 {
        font-size: 32px;
        font-weight: 500;
      }
      h2 {
        font-size: 24px;
      }
      h3 {
        font-size: 18px;
      }
      hr {
        border: 1px solid #e9e9e9;
        margin: 20px 0;
        height: 1px;
        padding: 0;
      }
      p,
      ul,
      ol {
        margin-bottom: 10px;
        font-weight: normal;
      }
      p li,
      ul li,
      ol li {
        margin-left: 5px;
        list-style-position: inside;
      }
      a {
        color: #348eda;
        text-decoration: underline;
      }
      .last {
        margin-bottom: 0;
      }
      .first {
        margin-top: 0;
      }
      .padding {
        padding: 10px 0;
      }
      .aligncenter {
        text-align: center;
      }
      .alignright {
        text-align: right;
      }
      .alignleft {
        text-align: left;
      }
      .clear {
        clear: both;
      }
      .alert {
        font-size: 16px;
        color: #fff;
        font-weight: 500;
        padding: 20px;
        text-align: center;
        border-radius: 3px 3px 0 0;
      }
      .alert a {
        color: #fff;
        text-decoration: none;
        font-weight: 500;
        font-size: 16px;
      }
      .alert.alert-warning {
        background: #ff9f00;
      }
      .alert.alert-bad {
        background: #d0021b;
      }
      .alert.alert-good {
        background: #68b90f;
      }
      @media only screen and (max-width: 640px) {
        h1,
        h2,
        h3 {
          font-weight: 600 !important;
          margin: 20px 0 5px !important;
        }
        h1 {
          font-size: 22px !important;
        }
        h2 {
          font-size: 18px !important;
        }
        h3 {
          font-size: 16px !important;
        }
        .container {
          width: 100% !important;
        }
        .content,
        .content-wrapper {
          padding: 10px !important;
        }
      }
    </style>
  </head>
  <body>
    <table class="body-wrap">
      <tr>
        <td></td>
        <td class="container" width="600">
          <div class="content">
            <table class="main" width="100%" cellpadding="0" cellspacing="0">
              <tr>
                {{#success build.status}}
                  <td class="alert alert-good">
                    <a href="{{ build.link }}">
                      Successful build #{{ build.number }}
                    </a>
                  </td>
                {{else}}
                  <td class="alert alert-bad">
                    <a href="{{ build.link }}">
                      Failed build #{{ build.number }}
                    </a>
                  </td>
                {{/success}}
              </tr>
              <tr>
                <td class="content-wrap">
                  <table width="100%" cellpadding="0" cellspacing="0">
                    <tr>
                      <td>
                        Repo:
                      </td>
                      <td>
                        {{ repo.owner }}/{{ repo.name }}
                      </td>
                    </tr>
                    <tr>
                      <td>
                        Author:
                      </td>
                      <td>
                        {{ commit.author.name }} ({{ commit.author.email }})
                      </td>
                    </tr>
                    <tr>
                      <td>
                        Branch:
                      </td>
                      <td>
                        {{ commit.branch }}
                      </td>
                    </tr>
                    <tr>
                      <td>
                        Commit:
                      </td>
                      <td>
                        {{ truncate commit.sha 8 }}
                      </td>
                    </tr>
                    <tr>
                      <td>
                        Started at:
                      </td>
                      <td>
                        {{ datetime build.created "Mon Jan 2 15:04:05 MST 2006" "Local" }}
                      </td>
                    </tr>
                  </table>
                  <hr>
                  <table width="100%" cellpadding="0" cellspacing="0">
                    <tr>
                      <td>
                        {{ commit.message }}
                      </td>
                    </tr>
                  </table>
                </td>
              </tr>
            </table>
          </div>
        </td>
        <td></td>
      </tr>
    </table>
  </body>
</html>

eslint 忽略检查

忽略一块代码

/* eslint-disable */

alert('foo');

/* eslint-enable */

忽略当前行

alert('foo'); // eslint-disable-line

忽略下一行

// eslint-disable-next-line
alert('foo');

忽略整个文件

/* eslint-disable */

放在文件头

忽略更多文件,可以关注 .eslintignore 文件

flex 子元素超出父元素实例

正常来说,当父元素设置为 flex 之后,子元素应该平分父元素的大小。

但是实际情况是,子元素会超出父元素。

描述一下自己遇到的情况

父元素 div{height:100%,display:flex;flex-direction: column;}

子元素 header:{flex: 0 0 60px;}

子元素 main:{flex: 1;}

子元素 footer:{flex: 0 0 80px;}

实际显示情况是 父元素 div 的高度是 822px。header、footer 子元素正常,因为 main 元素内部是需要华东内容的,导致 main 超出了 父元素的高度,实际高度是 1431 px,

解决办法

给子元素 main 添加一个属性 overflow: hidden;

ps: 给子元素 main 添加 height:0 也能达到效果,但是不理解。

经学习,min-height 或者 min-widht 也可以达到目的,建议使用 min 。

Office 部署和激活

网上的激活方式五花八门,有一种通用的工具可以解决部署和激活的问题,上手加单。

官网 Office Tool Plus

部署

首先从下载地址下载包含框架的版本。

解压之后打开目录下的 Office Tool Plus.exe 程序。

进入部署界面,选择导入配置

<Configuration>
  <Add OfficeClientEdition="64" Channel="PerpetualVL2021" AllowCdnFallback="true">
    <Product ID="ProPlus2021Volume">
      <Language ID="zh-cn" />
      <ExcludeApp ID="Access" />
      <ExcludeApp ID="Lync" />
      <ExcludeApp ID="OneDrive" />
      <ExcludeApp ID="OneNote" />
      <ExcludeApp ID="Outlook" />
      <ExcludeApp ID="Publisher" />
      <ExcludeApp ID="Teams" />
    </Product>
  </Add>
  <Display AcceptEULA="True" />
  <Property Name="AutoActivate" Value="1" />
</Configuration>

文件请以 XML 后缀命名,导入之后可以更具自己需要进行自定义。

然后点击部署即可,等待部署成功,office 就安装成功了。

激活

我喜欢采用 kms 激活,更多激活方式参考官方帖子

可能会用到 kms 主机列表 来查询可用的主机,也可以从互联网上检索。

  1. 进入激活界面
  2. 根据上面的版本安装许可证,如果没有改动,选择 Office LTSC 专业增强版 2021 – 批量许可证
  3. 等待输出 产品密钥安装成功 的字样
  4. 在 KMS 管理模块中 输入KMS主机 http://kms.03k.org,也可以检查http://kms.03k.org状态
  5. 点击保存设置,点击激活按钮。激活成功会输出产品激活成功字样

激活需要注意的地方

  • 每隔 7 天(默认),Office 都会与 KMS 通信一次,以更新自己的许可证状态。
  • 如果 KMS 允许你更新许可,那么新的许可就是 180 天期限。
  • 如果 KMS 不允许你更新许可,或者 KMS 不可用,那么原来的 180 天期限到期后,你的 Office 就会变成未激活了。