Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,7 @@
},
"dependencies": {
"@jitl/quickjs-singlefile-mjs-release-sync": "^0.32.0",
"quickjs-emscripten-core": "^0.32.0",
"xlsx": "https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz"
"quickjs-emscripten-core": "^0.32.0"
},
"devDependencies": {
"@eslint/js": "^10.0.1",
Expand All @@ -79,7 +78,8 @@
"vitest": "^5.0.5",
"vue": "^3.5.44",
"vue-eslint-parser": "^10.4.1",
"vue-tsc": "^3.3.13"
"vue-tsc": "^3.3.13",
"xlsx": "https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz"
},
"keywords": [
"guichat",
Expand Down
18 changes: 18 additions & 0 deletions plans/fix-193-xlsx-dev-dependency.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# xlsx を devDependencies に移す(#193)

## 問題
- `xlsx` を `dependencies` に SheetJS の配布サイトの URL で書いていた。npm 12 は初期設定(`allow-remote=none`)で URL からの取得を拒むため、このパッケージに依存するものはすべてインストールに失敗する(`mulmoclaude@2.8.0` で確認)

## 方針
- `vite.config.ts` の `external` に `xlsx` は入っていないので、SheetJS はビルド時に `dist/vue.js` / `dist/vue.cjs` に取り込まれている。使う側に `xlsx` は要らない
- `xlsx` を `devDependencies` に移す(ビルドには要る)。URL の指定はそのまま
- `tests/core/test_packageManifest.ts`:`dependencies` / `peerDependencies` / `optionalDependencies` に、URL・git・`file:`・`owner/repo` 形式の指定があれば落ちる

## 公開
- 5.0.1 を `main` から出す
- `mulmoclaude@2.8.0` は `^4.3.0` で指定しているので、4.3.0 のタグから 4.x の枝を切って同じ変更で 4.3.1 を出す(`latest` を動かさないよう `--tag` 付きで公開)

## 確かめたこと
- 変更前後の `package.json` でビルドした `dist/` が完全に一致する
- `npm pack` した物を npm 12.0.2・空の設定でインストールでき、`xlsx` は入らず、`.`・`./vue`・`./core` が読み込める(`./vue` は `require` でも)
- テストは変更前の `package.json` で落ちる
31 changes: 31 additions & 0 deletions tests/core/test_packageManifest.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { describe, it } from "node:test";
import assert from "node:assert/strict";
import { readFileSync } from "node:fs";

const manifest: unknown = JSON.parse(readFileSync(new URL("../../package.json", import.meta.url), "utf8"));

const isRecord = (value: unknown): value is Record<string, unknown> => typeof value === "object" && value !== null && !Array.isArray(value);

const runtimeRanges = (field: string): [string, unknown][] => {
const ranges = isRecord(manifest) ? manifest[field] : undefined;
return isRecord(ranges) ? Object.entries(ranges) : [];
};

// npm 12 refuses URL, git and file specs by default, so one in a published runtime field fails every consumer's install.
const NON_REGISTRY_SPEC = /^(?!npm:)(?:[a-z][a-z0-9+.-]*:|[^@\s/]+\/\S+$)/i;

describe("package.json", () => {
["dependencies", "peerDependencies", "optionalDependencies"].forEach((field) => {
it(`${field} resolve from the registry`, () => {
const offRegistry = runtimeRanges(field).filter(([, spec]) => typeof spec !== "string" || NON_REGISTRY_SPEC.test(spec));
assert.deepEqual(offRegistry, []);
});
});

it("recognises the specs npm 12 refuses", () => {
["https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz", "git+https://github.com/a/b.git", "github:a/b", "file:../x", "a/b"].forEach((spec) =>
assert.ok(NON_REGISTRY_SPEC.test(spec), spec),
);
["^0.32.0", "~6.0.3", ">=1 <2", "1.2.3", "*", "latest", "npm:@scope/pkg@^1"].forEach((spec) => assert.ok(!NON_REGISTRY_SPEC.test(spec), spec));
});
});
Loading