Evidence 40.1.8 安装与项目初始化指南
Ubuntu 26.04.1 LTS 服务器实测 Evidence 40.1.8 安装与 DuckDB+PostgreSQL 双数据源报表工程初始化全流程,含脚手架失效与密码注入两条排障实录
Evidence 40.1.8 安装与项目初始化指南
目标:在一台干净的 Ubuntu 服务器上从 0 到 1 装好开源 CLI
@evidence-dev/evidence40.1.8、初始化报表工程、接入 DuckDB + PostgreSQL 双数据源,并用 dev/build/preview 验证跑通。本文全部命令与回显均在 Ubuntu 26.04.1 LTS 服务器(Node.js v24.22.1 / npm 11.19.1)实测,含脚手架失效与密码注入两条关键排障实录。
一、环境信息
- 操作系统:Ubuntu 26.04.1 LTS(x86_64)
- 组件版本:
@evidence-dev/evidence40.1.8(npm registrydist-tags.latest实查,查询日期 2026-11-03) - 数据源:DuckDB(模板自带示例库)+ PostgreSQL 16(监听
127.0.0.1:5433,库名analytics) - 工程目录:
/opt/evidence/my-report - Evidence 的形态是 Node.js CLI 工具 + 静态站点生成器,没有守护服务:初始化一个项目工程,装依赖,连数据源,
evidence dev起临时预览,evidence build出静态站。
模板 package.json 声明 "engines": { "node": ">=18.0.0", "npm": ">=7.0.0" }。环境检查实测:
$ node --version
v24.22.1
$ npm --version
11.19.1
二、前置条件
需要 Node.js ≥ 18 与可连的 PostgreSQL 库。本文用 PostgreSQL 16,监听 127.0.0.1:5433,库名 analytics,演示账号 postgres / 密码 q1w2e3r4,灌一张演示表:
$ PGPASSWORD=q1w2e3r4 psql -h 127.0.0.1 -p 5433 -U postgres -d analytics \
-c "CREATE TABLE daily_visits (date DATE, page TEXT, visits INTEGER, region TEXT);"
灌数时踩了一个 SQL 本身的坑,留作实录:
ERROR: function generate_series(timestamp, timestamp, unknown) does not exist
原因是日期序列的第三参写成了整数步长 1(报错回显的第三参类型 unknown 即由此而来);日期序列必须用 interval。修正后按两个页面/地区各插 61 天:
$ PGPASSWORD=q1w2e3r4 psql -h 127.0.0.1 -p 5433 -U postgres -d analytics \
-c "INSERT INTO daily_visits SELECT d::date, '/home', (random()*1000)::int, 'cn-east'
FROM generate_series('2026-09-01'::timestamp, '2026-10-31'::timestamp, interval '1 day') d;"
INSERT 0 61
$ PGPASSWORD=q1w2e3r4 psql -h 127.0.0.1 -p 5433 -U postgres -d analytics \
-c "INSERT INTO daily_visits SELECT d::date, '/pricing', (random()*1000)::int, 'cn-north'
FROM generate_series('2026-09-01'::timestamp, '2026-10-31'::timestamp, interval '1 day') d;"
INSERT 0 61
$ PGPASSWORD=q1w2e3r4 psql -h 127.0.0.1 -p 5433 -U postgres -d analytics \
-c "SELECT count(*), min(date), max(date) FROM daily_visits;"
count | min | max
-------+------------+------------
122 | 2026-09-01 | 2026-10-31
三、版本选型说明:npx create 已失效,用官方模板仓库
3.1 排障实录一:npm init evidence 与 npx evidence create 都不可用
老文档里的 npx evidence@latest create 在 2026-11 实测走不通,逐条证据:
- npm 上名为
evidence的包(1.0.3,2015 年发布)与 Evidence 无关,npx evidence会装错包; npm init evidence对应的初始化包create-evidence最新版 0.0.1(2024-08-22),解包核对bin/cli.js与@evidence-dev/evidence@40.1.8的 CLI 完全相同——只有 dev/build/sources/preview,没有 create 子命令;- 历史上的 CLI 包
@evidence-dev/cli已从 npm 下架(registry 返回404 '@evidence-dev/cli' is not in this registry)。
因此 40.1.8 的项目初始化只能从官方模板仓库取工程,下文给出两种取法。
3.2 版本口径
@evidence-dev/evidence 最新稳定版 40.1.8 即开源 CLI 的末代稳定版(2026 年官方主线转向 Evidence Studio 与新 CLI,背景见 《Evidence 40.1.8 介绍与选型指南》),工程内以 package.json 钉住 ^40.1.8、package-lock.json 锁死依赖树保证可复现。
四、安装方案 A:git 钉住开源版模板提交(本文主路径)
官方模板仓库 evidence-dev/template 的 main 分支已于 2026-10-30 改为「Deprecated」告示页(指向新 CLI),最后一个开源版模板提交是 4b13d42e15(2026-02-06,package.json 依赖 @evidence-dev/evidence: ^40.1.8)。主项目用 git 钉住该提交拉取(实测):
$ git clone https://github.com/evidence-dev/template.git my-report
$ cd my-report
$ git checkout 4b13d42e15
装依赖(模板自带 package-lock.json,用 npm ci 保证可复现):
$ cd my-report && npm ci
added 1311 packages in 18s
4.1 项目结构
my-report/
├── evidence.config.yaml # 全局配置:主题/外观/插件声明
├── package.json # scripts 封装 evidence 子命令
├── pages/ # 报表页面(Markdown + ```sql 块)
│ ├── index.md
│ └── about.md
├── sources/
│ └── needful_things/ # 一个数据源 = 一个目录
│ ├── connection.yaml # 源连接配置
│ ├── orders.sql # 一条查询 = 一个 .sql 文件
│ └── needful_things.duckdb # DuckDB 本地库文件
└── static/ # 静态资源(图标等)
注意:模板没有 svelte.config.js / vite.config.js(实测 cat 报 No such file),SvelteKit/Vite 配置由 CLI 内置生成到隐藏工作区 .evidence/,日常不需要碰。
五、安装方案 B:degit 拉取(不留 Git 历史)
不想留 Git 历史的可用 degit(实测回显如下,末行目录名即所选目标目录):
$ npx degit evidence-dev/template#4b13d42e15 degit-test
> cloned evidence-dev/template#4b13d42e15 to degit-test
! action wants to remove .github but it does not exist
> removed: .devcontainer/, scripts/
后续 npm ci 与方案 A 相同。
六、方案对比与选择建议
| 维度 | 方案 A(git clone + checkout) | 方案 B(degit) |
|---|---|---|
| 取到的内容 | 模板全仓 + 钉住历史提交 | 仅该提交的快照文件 |
| .git 目录 | 有(可再切其他提交) | 无 |
| 依赖 | git | npx(自动装 degit) |
| 适用 | 长期演进工程、需回溯模板变更 | 一次性起步、嫌 .git 碍事 |
两方案取到的是同一个开源版模板提交 4b13d42e15,工程内容一致;内网无法访问 GitHub 时,可在可联网机器上按任一方案打包工程再拷贝(离线交付后 npm ci 需本地 npm 缓存或私有 npm registry)。
七、DuckDB 数据源(模板自带)
模板预置了示例源 needful_things,sources/needful_things/connection.yaml 实测原文:
sources:
- name: needful_things
type: duckdb
options:
filepath: ./needful_things.duckdb
同目录 orders.sql 内容就是 select * from orders。示例库含一张 10000 行的 orders 表(列:id、order_datetime、order_month、first_name、last_name、email、address、state、zipcode、item、category、sales、channel、channel_group、channel_month)。
首次执行 evidence sources 前,先跑一次会看到全部查询物化:
$ npx evidence sources
- Loading plugins & sources
✔ Loading plugins & sources
-----
[Processing] needful_things
- Processing...
needful_things ⚠ No results returned.
- Processing...
orders ✔ Finished, wrote 10000 rows.
-----
[INFO]: Evaluated sources, saving manifest
[INFO]: ✅ Done!
⚠ No results returned. 是目录级占位提示,非错误。产物落在 .evidence/template/static/data/needful_things/orders/orders.parquet(目录可由 EVIDENCE_DATA_DIR 改,见 《Evidence 40.1.8 配置参数详解》 第七节)。
八、接入 PostgreSQL 源
8.1 建源目录
sources/web_analytics/connection.yaml:
name: web_analytics
type: postgres
options:
host: 127.0.0.1
port: 5433
database: analytics
user: postgres
ssl: null
timeout: 180000
sources/web_analytics/daily_visits.sql:
select * from daily_visits
8.2 排障实录二:密码注入的三次试错
第一次:按旧文档惯例在 connection.yaml 写 password: ${ENV_POSTGRES_PASSWORD}、.env 写 ENV_POSTGRES_PASSWORD=q1w2e3r4,执行 evidence sources 报错:
daily_visits ✖ Error: password authentication failed for user "postgres"
第二次:改 password: ${POSTGRES_PASSWORD} 并在 .env 写 EVIDENCE_VAR__POSTGRES_PASSWORD=q1w2e3r4,同样报 password authentication failed——查 SDK 源码确认 EVIDENCE_VAR__<变量> 只作用于 SQL 查询文件里的 ${} 替换,connection.yaml 的 options 不做任何 ${} 插值,占位符被当字面量发给了数据库。
第三次(正确姿势):connection.yaml 里删掉 password 行,凭据改用环境变量 EVIDENCE_SOURCE__<源名>__<选项名> 注入,.env:
EVIDENCE_SOURCE__web_analytics__password=q1w2e3r4
重跑即成功:
$ npx evidence sources
-----
[Processing] needful_things
- Processing...
orders ✔ Finished, wrote 10000 rows.
-----
[Processing] web_analytics
- Processing...
daily_visits ✔ Finished, wrote 122 rows.
-----
[INFO]: Evaluated sources, saving manifest
[INFO]: ✅ Done!
密码机制完整规则(含 base64 的 connection.options.yaml、.env 只加载 EVIDENCE_/VITE_ 前缀)见 《Evidence 40.1.8 配置参数详解》 第六节。
九、启动 dev 服务器实测
$ npx evidence dev --port 8137
VITE v5.4.21 ready in 2057 ms
➜ Local: http://localhost:8137/
➜ Network: use --host to expose
说明两点:evidence dev 底层就是 vite dev --port 3000(CLI 源码硬编码默认 3000),追加的参数原样透传给 Vite,后出现的 --port 覆盖默认值;需要局域网可访问时加 --host 0.0.0.0。
页面验证(含本文第八节的 Postgres 源数据页,见下节):
$ curl -s -o /dev/null -w "%{http_code}\n" http://localhost:8137/
200
$ curl -s -o /dev/null -w "%{http_code}\n" http://localhost:8137/visits/
200
dev 服务器改页面即时热更,Ctrl+C 即停,无常驻进程。
十、第一页报表:双源混排 + 构建静态站
新建 pages/visits.md,同一页面混用 Postgres 与 DuckDB 两个源的查询和三类组件:
---
title: Daily Visits
---
```sql daily
select date, sum(visits) as visits
from web_analytics.daily_visits
group by date order by date
select category, sum(sales) as revenue
from needful_things.orders
group by category order by revenue desc limit 5
构建静态站:
$ npx evidence build
...(vite 编译输出,节选)
> Using @sveltejs/adapter-static
Wrote site to "./build"
✔ done
Build complete --> ./build
实测产物 build/ 目录 87M(含全部 parquet 数据与浏览器端 DuckDB-WASM 运行时),build/visits/index.html 已预渲染。本地验证产物:
$ npx evidence preview --listen 8138
INFO Accepting connections at http://localhost:8138
浏览器打开 http://localhost:8138/visits/ 即可看到折线图与柱状图——此时服务的是纯静态文件,查询在浏览器内对 parquet 快照执行。
构建期踩过的第三个坑(排障):凭直觉把 SQL 写成 sum(order_total),构建报:
[!ERROR] Binder Error: Referenced column "order_total" not found.
LINE 4: sum(order_total) as revenue
错误信息会列出候选列名(order_datetime、order_month、zipcode、channel_group、channel_month),据此核对真实表结构后改为 sum(sales) 通过。教训:SQL 里引用源表列前先 DESCRIBE 确认真实列名,别照抄文档示例字段。
十一、配置说明
工程配置分散在四类载体,逐项详解见 《Evidence 40.1.8 配置参数详解》:
evidence.config.yaml:外观appearance、主题色板theme、组件/数据源插件声明plugins;sources/<源名>/connection.yaml:数据源连接参数(敏感值不落此文件,走环境变量注入);.env:EVIDENCE_/VITE_前缀白名单加载,凭据用EVIDENCE_SOURCE__<源名>__<选项名>;pages/*.md组件属性:图表/表格级配置。
十二、常见问题(FAQ)
Q1: npm init evidence / npx evidence create 起不了项目?
A: 脚手架已失效(见 3.1 实录),用本文第四/五节从模板仓库取工程。
Q2: connection.yaml 写了 password: ${...} 仍报 password authentication failed?
A: connection.yaml 的值域不做 ${} 插值(8.2 实录二),删掉 password 行,改用 .env 中 EVIDENCE_SOURCE__<源名>__password 注入。
Q3: 构建报 Binder Error: Referenced column ... not found?
A: SQL 引用了源表不存在的列(第十节实录),按报错列出的候选列名核对真实表结构后改正。
十三、收尾:卸载与清理
Evidence 项目无系统级安装:删除项目目录即卸载;.env 含凭据,随目录一并清理;构建中间产物在 .evidence/、build/、.svelte-kit/,可安全删除。dev/preview 服务器为前台进程,Ctrl+C 退出,无残留服务。
十四、参考链接
- 官方模板仓库:https://github.com/evidence-dev/template
- npm 包页:https://www.npmjs.com/package/@evidence-dev/evidence
- 40.x 对应文档(legacy):https://legacy-docs.evidence.dev/
- CLI 各子命令的参数细节与更多实测回显,见 《Evidence 40.1.8 常用 CLI 命令详解》;产品背景与选型(含 2026 年官方主线转向 Evidence Studio 的说明)见 《Evidence 40.1.8 介绍与选型指南》。