diff --git a/docs/deployment/docker-compose-production.md b/docs/deployment/docker-compose-production.md
index 8e19fe0..e9caebe 100644
--- a/docs/deployment/docker-compose-production.md
+++ b/docs/deployment/docker-compose-production.md
@@ -11,7 +11,7 @@ docker build -f web/Dockerfile -t registry.example/a-share-web:<提交SHA> .
docker build -f server/Dockerfile -t registry.example/a-share-server:<提交SHA> .
```
-把四份生产模板复制到服务器的 `/etc/a-share-analysis/`,由运维填写并设置最小权限。Web 配置在镜像构建期固化,因此 `web.env` 只作为发布参数记录,不挂载到容器;API、Scheduler、Worker 分别读取自己的外部 env 文件。所有镜像引用必须使用明确版本或内容摘要,禁止 `latest`。
+把四份生产模板复制到服务器的 `/etc/a-share-analysis/`,由运维填写并设置最小权限。Web 配置在镜像构建期固化,因此 `web.env` 只作为发布参数记录,不挂载到容器;API、Scheduler、Worker 分别读取自己的外部 env 文件。所有生产镜像引用必须使用内容摘要,禁止 `latest` 和任何普通 tag。
## 发布与验证
diff --git a/package.json b/package.json
index db60235..f99147b 100644
--- a/package.json
+++ b/package.json
@@ -36,6 +36,7 @@
},
"devDependencies": {
"@eslint/js": "9.39.5",
+ "@vue/compiler-sfc": "3.5.41",
"eslint": "9.39.5",
"eslint-plugin-vue": "9.33.0",
"globals": "17.11.0",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index c0a513c..1f673fb 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -11,6 +11,9 @@ importers:
'@eslint/js':
specifier: 9.39.5
version: 9.39.5
+ '@vue/compiler-sfc':
+ specifier: 3.5.41
+ version: 3.5.41
eslint:
specifier: 9.39.5
version: 9.39.5
diff --git a/tools/boundaries/verify-project-boundaries.mjs b/tools/boundaries/verify-project-boundaries.mjs
index da2bb5b..117b210 100644
--- a/tools/boundaries/verify-project-boundaries.mjs
+++ b/tools/boundaries/verify-project-boundaries.mjs
@@ -2,6 +2,7 @@ import { readdir, readFile, stat } from 'node:fs/promises';
import path from 'node:path';
import process from 'node:process';
import ts from 'typescript';
+import { parse } from '@vue/compiler-sfc';
const SOURCE_EXTENSIONS = new Set(['.ts', '.tsx', '.mts', '.cts', '.vue']);
const INTERNAL_MESSAGE_MARKERS = ['MessageEnvelope', 'message-contracts'];
@@ -20,16 +21,18 @@ async function collectSourceFiles(directory) {
function extractTypeScriptSource(sourcePath, sourceText) {
if (path.extname(sourcePath) !== '.vue') return sourceText;
- const externalScript = sourceText.match(/\n\n`,
- );
+for (const [name, scriptTag] of [
+ ['双引号', '\n\n`,
+ );
- const result = await runChecker(repositoryRoot);
+ const result = await runChecker(repositoryRoot);
- assert.equal(result.exitCode, 1);
- assert.match(result.stderr, /禁止使用外部 script src/);
- assert.match(result.stderr, /ExternalScript\.vue/);
-});
+ assert.equal(result.exitCode, 1);
+ assert.match(result.stderr, /禁止使用外部 script src/);
+ assert.match(result.stderr, /ExternalScript\.vue/);
+ });
+}
test('接受只消费公开 OpenAPI 类型的 Web 工程', async () => {
const repositoryRoot = await createFixture();