minista 4.0.0-alpha.9 → 4.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (96) hide show
  1. package/README.md +75 -24
  2. package/bin/minista.js +1 -1
  3. package/package.json +48 -34
  4. package/src/assets.d.ts +12 -0
  5. package/src/assets.js +6 -0
  6. package/src/cli/index.js +28 -0
  7. package/src/cli/utils/arg.js +76 -0
  8. package/src/cli/utils/command.js +38 -0
  9. package/src/cli/utils/file.js +33 -0
  10. package/src/client.d.ts +3 -0
  11. package/src/context.d.ts +3 -0
  12. package/src/context.js +3 -0
  13. package/src/head.d.ts +7 -0
  14. package/src/head.js +1 -0
  15. package/src/node.d.ts +29 -0
  16. package/src/node.js +13 -0
  17. package/src/plugins/archive/index.js +115 -0
  18. package/src/plugins/archive/types.d.ts +14 -0
  19. package/src/plugins/beautify/index.js +103 -0
  20. package/src/plugins/beautify/types.d.ts +14 -0
  21. package/src/plugins/bundle/index.js +180 -0
  22. package/src/plugins/bundle/types.d.ts +6 -0
  23. package/src/plugins/bundle/utils/code.js +10 -0
  24. package/src/plugins/comment/components/comment.js +12 -0
  25. package/src/plugins/comment/index.js +68 -0
  26. package/src/plugins/comment/types.d.ts +13 -0
  27. package/src/plugins/entry/index.js +194 -0
  28. package/src/plugins/entry/types.d.ts +2 -0
  29. package/src/plugins/image/components/image.js +70 -0
  30. package/src/plugins/image/components/picture.js +188 -0
  31. package/src/plugins/image/index.js +509 -0
  32. package/src/plugins/image/types.d.ts +126 -0
  33. package/src/plugins/image/utils/aspect.js +11 -0
  34. package/src/plugins/image/utils/breakpoints.js +36 -0
  35. package/src/plugins/image/utils/format.js +30 -0
  36. package/src/plugins/image/utils/hash.js +11 -0
  37. package/src/plugins/image/utils/option.js +27 -0
  38. package/src/plugins/image/utils/pattern.js +176 -0
  39. package/src/plugins/image/utils/ratio.js +11 -0
  40. package/src/plugins/image/utils/remote.js +46 -0
  41. package/src/plugins/image/utils/sharp.js +35 -0
  42. package/src/plugins/image/utils/size.js +15 -0
  43. package/src/plugins/image/utils/view.js +64 -0
  44. package/src/plugins/island/client.d.ts +20 -0
  45. package/src/plugins/island/index.js +356 -0
  46. package/src/plugins/island/types.d.ts +8 -0
  47. package/src/plugins/island/utils/code.js +198 -0
  48. package/src/plugins/island/utils/directive.js +367 -0
  49. package/src/plugins/island/utils/snippet.js +32 -0
  50. package/src/plugins/mdx/client.d.ts +11 -0
  51. package/src/plugins/mdx/index.js +31 -0
  52. package/src/plugins/mdx/types.d.ts +4 -0
  53. package/src/plugins/mdx/utils/option.js +39 -0
  54. package/src/plugins/search/components/search.js +378 -0
  55. package/src/plugins/search/index.js +232 -0
  56. package/src/plugins/search/types.d.ts +64 -0
  57. package/src/plugins/search/utils/data.js +235 -0
  58. package/src/plugins/sprite/components/sprite.js +24 -0
  59. package/src/plugins/sprite/index.js +266 -0
  60. package/src/plugins/sprite/types.d.ts +14 -0
  61. package/src/plugins/sprite/utils/sprite.js +74 -0
  62. package/src/plugins/ssg/components/head.js +62 -0
  63. package/src/plugins/ssg/index.js +360 -0
  64. package/src/plugins/ssg/types.d.ts +105 -0
  65. package/src/plugins/ssg/utils/attr.js +13 -0
  66. package/src/plugins/ssg/utils/charset.js +9 -0
  67. package/src/plugins/ssg/utils/code.js +22 -0
  68. package/src/plugins/ssg/utils/html.js +77 -0
  69. package/src/plugins/ssg/utils/layout.js +35 -0
  70. package/src/plugins/ssg/utils/page.js +83 -0
  71. package/src/plugins/ssg/utils/tag.js +85 -0
  72. package/src/plugins/ssg/utils/viewport.js +9 -0
  73. package/src/plugins/svg/components/svg.js +21 -0
  74. package/src/plugins/svg/index.js +109 -0
  75. package/src/plugins/svg/types.d.ts +13 -0
  76. package/src/shared/filename.js +8 -0
  77. package/src/shared/obj.js +43 -0
  78. package/src/shared/path.js +46 -0
  79. package/src/shared/reg.js +3 -0
  80. package/src/shared/url.js +111 -0
  81. package/src/shared/vite.js +100 -0
  82. package/src/types.d.ts +7 -0
  83. package/client.d.ts +0 -9
  84. package/dist/node/cli.js +0 -25
  85. package/dist/node/command.js +0 -27
  86. package/dist/node/config.js +0 -29
  87. package/dist/node/define.js +0 -3
  88. package/dist/node/index.js +0 -2
  89. package/dist/node/utils.js +0 -58
  90. package/dist/types/@types/node.d.ts +0 -1
  91. package/dist/types/node/cli.d.ts +0 -1
  92. package/dist/types/node/command.d.ts +0 -1
  93. package/dist/types/node/config.d.ts +0 -1
  94. package/dist/types/node/define.d.ts +0 -2
  95. package/dist/types/node/index.d.ts +0 -1
  96. package/dist/types/node/utils.d.ts +0 -6
package/README.md CHANGED
@@ -6,36 +6,45 @@
6
6
 
7
7
  ## About
8
8
 
9
- minista(ミニスタ)は React の JSX から綺麗な HTML を作る日本製のスタティックサイトジェネレーターです。
9
+ minista(ミニスタ)は、React の JSX Vite で 100%静的なサイトを作るスタティックサイトジェネレーターです。
10
10
 
11
- 本体パッケージ `minista` は Vite に指示を出すラッパーです。Vite との違いは、ビルド時に自動で「SSR ビルド + 通常ビルド」の指示を出し、HTML の書き出しを簡略化している点です。
11
+ ## Concept
12
12
 
13
- ## How To Use
13
+ - **すべてを JSX で書き、綺麗な HTML を生成!**
14
+ - 静的 HTML が必要なウェブ制作の現場にも JSX のコンポーネント管理を導入したい
15
+ - 独自構文を使わず、エディタサポートの優れた TypeScript を活用したい
14
16
 
15
- ### Automatic Setup
17
+ ## Features
18
+
19
+ - すべての機能を Vite プラグインとして提供
20
+ - ビルド時に自動で Vite の「SSR ビルド + 通常ビルド」を実行
21
+
22
+ ## Setup
23
+
24
+ ### Automatic
16
25
 
17
26
  ```sh
18
27
  $ npm create minista@latest
19
28
  ```
20
29
 
21
- ### Manual Setup
30
+ ### Manual
22
31
 
23
32
  ```sh
24
- $ npm install --save-dev minista minista-plugin-ssg vite react react-dom
33
+ $ npm install --save-dev minista vite react react-dom
25
34
  $ touch ./minista.config.js
26
35
  $ touch ./src/pages/index.jsx
27
36
  ```
28
37
 
29
38
  ```js
30
39
  // ./minista.config.js
31
- import { pluginSsg } from "minista-plugin-ssg"
40
+ import { pluginSsg } from "minista"
32
41
 
33
42
  export default {
34
43
  plugins: [pluginSsg()],
35
44
  }
36
45
  ```
37
46
 
38
- ```js
47
+ ```jsx
39
48
  // ./src/pages/index.jsx
40
49
  export default function () {
41
50
  return <h1>Hello!</h1>
@@ -45,30 +54,72 @@ export default function () {
45
54
  `package.json` を開き、以下のスクリプトを追加します。
46
55
 
47
56
  ```json
48
- "scripts": {
49
- "dev": "minista",
50
- "build": "minista build",
51
- "preview": "minista preview",
57
+ {
58
+ "scripts": {
59
+ "dev": "minista",
60
+ "build": "minista build",
61
+ "preview": "minista preview"
62
+ }
52
63
  }
53
64
  ```
54
65
 
55
- ## Commands
66
+ ## CLI
67
+
68
+ | コマンド | 内容 |
69
+ | ------------------------ | ---------------------------------------------- |
70
+ | `minista [root]` | 開発モード(`Ctrl + C` で停止) |
71
+ | `minista build [root]` | 静的書き出し(SSR ビルド後に連続で通常ビルド) |
72
+ | `minista preview [root]` | 静的書き出し後の動作確認 |
73
+
74
+ [Vite の CLI コマンドオプション](https://ja.vitejs.dev/guide/cli.html)がすべて使えるほか、以下の独自オプションがあります。
75
+
76
+ | 独自のオプション | 内容 |
77
+ | ---------------- | ------------------------------------------------- |
78
+ | `--oneBuild` | minista のビルドを 1 回に制限(連続ビルドしない) |
56
79
 
57
- [Vite の CLI コマンドとオプション](https://ja.vitejs.dev/guide/cli.html)がすべて使えます。
80
+ ## Config
58
81
 
59
- | コマンド | 内容 |
60
- | ------------------------ | ------------------------------- |
61
- | `minista [root]` | 開発モード(`Ctrl + C` で停止) |
62
- | `minista build [root]` | 静的書き出し |
63
- | `minista preview [root]` | 静的書き出し後の動作確認 |
82
+ [Vite のコンフィグ](https://ja.vitejs.dev/config/)がすべて使えます。コンフィグファイルは `minista.config.{ts,js}`・`vite.config.{ts,js}` のどちらでも動作し、`defineConfig` も使用できます。
64
83
 
65
- | minista 独自のオプション | 内容 |
66
- | ------------------------ | --------------------------------- |
67
- | `--oneBuild` | minista のビルドを 1 回に制限する |
84
+ ```ts
85
+ // ./minista.config.ts
86
+ import { defineConfig, pluginSsg } from "minista"
68
87
 
69
- ## Settings
88
+ export default defineConfig({
89
+ plugins: [pluginSsg()],
90
+ })
91
+ ```
92
+
93
+ minista は Vite の SSR ビルドと通常ビルドを連続で行うため、ビルドの一括設定がエラーに繋がる場合があります。これは設定を SSR ビルド用・通常ビルド用に切り分けることで解消できます。
94
+
95
+ ```ts
96
+ // ./minista.config.ts
97
+ import { defineConfig, pluginSsg } from "minista"
98
+
99
+ export default defineConfig(({ command, isSsrBuild }) => {
100
+ const isDev = command === "serve"
101
+ const isSsr = command === "build" && isSsrBuild
102
+ const isBuild = command === "build" && !isSsrBuild
103
+ return { plugins: [pluginSsg()], build: { minify: isBuild ? false : true } }
104
+ })
105
+ ```
70
106
 
71
- [Vite の 設定](https://ja.vitejs.dev/config/)がすべて使えます。コンフィグファイルは `minista.config.{ts|js}` または `vite.config.{ts|js}` のどちらでも動作します。
107
+ ## Plugins
108
+
109
+ minista の各機能は同封されているプラグインをコンフィグに登録することで動作します。
110
+
111
+ - [pluginSsg](https://minista.qranoko.jp/docs/plugins/ssg): React の JSX を静的な HTML に変換
112
+ - [pluginMdx](https://minista.qranoko.jp/docs/plugins/mdx): MDX・Markdown を HTML の変換に対応させる
113
+ - [pluginBundle](https://minista.qranoko.jp/docs/plugins/bundle): JSX 内で import した CSS・画像を出力
114
+ - [pluginEntry](https://minista.qranoko.jp/docs/plugins/entry): CSS・JS・画像をビルドプロセスに乗せる
115
+ - [pluginImage](https://minista.qranoko.jp/docs/plugins/image): 画像を最適化・リモート画像をダウンロード
116
+ - [pluginSvg](https://minista.qranoko.jp/docs/plugins/svg): SVG ファイルを HTML にインライン展開
117
+ - [pluginSprite](https://minista.qranoko.jp/docs/plugins/sprite): SVG ファイルを スプライト化して出力
118
+ - [pluginComment](https://minista.qranoko.jp/docs/plugins/comment): HTML にコメントを出力
119
+ - [pluginIsland](https://minista.qranoko.jp/docs/plugins/island): ページの一部を React App 化
120
+ - [pluginSearch](https://minista.qranoko.jp/docs/plugins/search): 全文検索機能を追加
121
+ - [pluginBeautify](https://minista.qranoko.jp/docs/plugins/beautify): ビルド時に HTML・CSS・JS を整形
122
+ - [pluginArchive](https://minista.qranoko.jp/docs/plugins/archive): ビルド時に圧縮ファイルを生成
72
123
 
73
124
  ## License
74
125
 
package/bin/minista.js CHANGED
@@ -1,2 +1,2 @@
1
1
  #!/usr/bin/env node
2
- import("../dist/node/cli.js")
2
+ import("../src/cli/index.js")
package/package.json CHANGED
@@ -1,28 +1,43 @@
1
1
  {
2
2
  "name": "minista",
3
- "version": "4.0.0-alpha.9",
3
+ "version": "4.0.1",
4
4
  "type": "module",
5
- "engines": {
6
- "node": "^18.0.0 || >=20.0.0"
7
- },
8
5
  "bin": {
9
6
  "minista": "./bin/minista.js"
10
7
  },
11
- "types": "dist/types/@types/node.d.ts",
12
- "main": "dist/node/index.js",
8
+ "main": "./src/node.js",
9
+ "types": "./src/node.d.ts",
13
10
  "exports": {
14
11
  ".": {
15
- "types": "./dist/types/@types/node.d.ts",
16
- "default": "./dist/node/index.js"
12
+ "import": "./src/node.js",
13
+ "types": "./src/node.d.ts"
14
+ },
15
+ "./types": {
16
+ "types": "./src/types.d.ts"
17
17
  },
18
18
  "./client": {
19
- "types": "./client.d.ts"
19
+ "types": "./src/client.d.ts"
20
+ },
21
+ "./context": {
22
+ "import": "./src/context.js",
23
+ "types": "./src/context.d.ts"
24
+ },
25
+ "./head": {
26
+ "import": "./src/head.js",
27
+ "types": "./src/head.d.ts"
28
+ },
29
+ "./assets": {
30
+ "import": "./src/assets.js",
31
+ "types": "./src/assets.d.ts"
32
+ },
33
+ "./package.json": {
34
+ "import": "./package.json"
20
35
  }
21
36
  },
22
37
  "files": [
23
38
  "bin",
24
- "dist",
25
- "client.d.ts"
39
+ "src",
40
+ "types"
26
41
  ],
27
42
  "license": "MIT",
28
43
  "homepage": "https://minista.qranoko.jp",
@@ -37,35 +52,34 @@
37
52
  "keywords": [
38
53
  "static-site-generator",
39
54
  "ssg",
40
- "coding",
41
55
  "react",
42
- "jsx",
43
- "tsx",
44
- "typescript",
45
- "esbuild",
46
- "vite",
47
- "japanese",
56
+ "vite-plugin",
48
57
  "minista"
49
58
  ],
50
- "author": {
51
- "name": "Qrac",
52
- "url": "https://qrac.jp"
53
- },
54
- "organization": {
55
- "name": "QRANOKO",
56
- "url": "https://qranoko.jp"
57
- },
58
- "scripts": {
59
- "build": "npm run clean && npm run build-src && npm run build-type",
60
- "build-src": "esbuild ./src/node/*.ts --outbase=src --outdir=dist",
61
- "build-type": "tsc",
62
- "clean": "rimraf ./dist",
63
- "prepublishOnly": "npm run build"
59
+ "engines": {
60
+ "node": ">=20.0.0"
64
61
  },
65
62
  "peerDependencies": {
66
- "vite": ">=5.0.0"
63
+ "react": ">=18.0.0",
64
+ "react-dom": ">=18.0.0",
65
+ "vite": ">=6.3.0"
67
66
  },
68
67
  "dependencies": {
69
- "minista-shared-utils": "^4.0.0-alpha.9"
68
+ "@mdx-js/rollup": "^3.1.1",
69
+ "@swc/core": "^1.15.21",
70
+ "archiver": "^7.0.1",
71
+ "cross-spawn": "^7.0.6",
72
+ "image-size": "^2.0.2",
73
+ "js-beautify": "^1.15.4",
74
+ "mime-types": "^3.0.2",
75
+ "mojigiri": "^0.3.0",
76
+ "node-html-parser": "^7.1.0",
77
+ "picocolors": "^1.1.1",
78
+ "picomatch": "^4.0.4",
79
+ "remark-frontmatter": "^5.0.0",
80
+ "remark-mdx-frontmatter": "^5.2.0",
81
+ "sharp": "^0.34.5",
82
+ "svgo": "^4.0.1",
83
+ "tinyglobby": "^0.2.15"
70
84
  }
71
85
  }
@@ -0,0 +1,12 @@
1
+ import type { ImageProps, PictureProps } from "./plugins/image/types"
2
+ import type { SvgProps } from "./plugins/svg/types"
3
+ import type { SpriteProps } from "./plugins/sprite/types"
4
+ import type { CommentProps } from "./plugins/comment/types"
5
+ import type { SearchProps } from "./plugins/search/types"
6
+
7
+ export declare function Image(props: ImageProps): React.ReactElement
8
+ export declare function Picture(props: PictureProps): React.ReactElement
9
+ export declare function Svg(props: SvgProps): React.ReactElement
10
+ export declare function Sprite(props: SpriteProps): React.ReactElement
11
+ export declare function Comment(props: CommentProps): React.ReactElement
12
+ export declare function Search(props: SearchProps): React.ReactElement
package/src/assets.js ADDED
@@ -0,0 +1,6 @@
1
+ export { Image } from "./plugins/image/components/image.js"
2
+ export { Picture } from "./plugins/image/components/picture.js"
3
+ export { Svg } from "./plugins/svg/components/svg.js"
4
+ export { Sprite } from "./plugins/sprite/components/sprite.js"
5
+ export { Comment } from "./plugins/comment/components/comment.js"
6
+ export { Search } from "./plugins/search/components/search.js"
@@ -0,0 +1,28 @@
1
+ import {
2
+ findRootArg,
3
+ checkOneBuildArg,
4
+ resolveConfigArg,
5
+ resolveOneBuildArg,
6
+ resolveSsrArg,
7
+ } from "./utils/arg.js"
8
+ import { findConfigFile } from "./utils/file.js"
9
+ import { runMinista } from "./utils/command.js"
10
+
11
+ async function main() {
12
+ let args = process.argv.slice(2)
13
+
14
+ const rootArg = findRootArg(args)
15
+ const isOneBuild = checkOneBuildArg(args)
16
+ const configFile = findConfigFile(rootArg)
17
+
18
+ args = resolveConfigArg(args, configFile)
19
+ args = resolveOneBuildArg(args, isOneBuild)
20
+ args = resolveSsrArg(args, isOneBuild)
21
+
22
+ await runMinista(args, isOneBuild)
23
+ }
24
+
25
+ main().catch((error) => {
26
+ console.error(error)
27
+ process.exit(1)
28
+ })
@@ -0,0 +1,76 @@
1
+ /**
2
+ * @param {string[]} args
3
+ * @returns {string}
4
+ */
5
+ export function findRootArg(args) {
6
+ if (!args.length) {
7
+ return ""
8
+ }
9
+ const commands = /^(dev|build|optimize|preview)$/
10
+
11
+ if (!args[0].startsWith("-") && !args[0].match(commands)) {
12
+ return args[0]
13
+ }
14
+ if (args.length >= 2 && args[0].match(commands) && !args[1].startsWith("-")) {
15
+ return args[1]
16
+ }
17
+ return ""
18
+ }
19
+
20
+ /**
21
+ * @param {string[]} args
22
+ * @returns {boolean}
23
+ */
24
+ export function checkOneBuildArg(args) {
25
+ return args.includes("--oneBuild")
26
+ }
27
+
28
+ /**
29
+ * @param {string[]} args
30
+ * @param {string} [configFile]
31
+ * @returns {string[]}
32
+ */
33
+ export function resolveConfigArg(args, configFile) {
34
+ if (args.includes("--config") || args.includes("-c")) {
35
+ return args
36
+ }
37
+ if (configFile) {
38
+ return [...args, "--config", configFile]
39
+ }
40
+ return args
41
+ }
42
+
43
+ /**
44
+ * @param {string[]} args
45
+ * @param {boolean} [isOneBuild]
46
+ * @returns {string[]}
47
+ */
48
+ export function resolveOneBuildArg(args, isOneBuild) {
49
+ if (!args.length) {
50
+ return args
51
+ }
52
+ if (isOneBuild) {
53
+ const oneBuildIndex = args.indexOf("--oneBuild")
54
+ return args.filter((_, index) => index !== oneBuildIndex)
55
+ }
56
+ return args
57
+ }
58
+
59
+ /**
60
+ * @param {string[]} args
61
+ * @param {boolean} [isOneBuild]
62
+ * @returns {string[]}
63
+ */
64
+ export function resolveSsrArg(args, isOneBuild) {
65
+ if (!args.length || isOneBuild || !args.includes("build")) {
66
+ return args
67
+ }
68
+ const ssrIndex = args.indexOf("--ssr")
69
+ if (ssrIndex === -1) {
70
+ return args
71
+ }
72
+ const hasSsrFile = !(args[ssrIndex + 1] || "").startsWith("-")
73
+ return args.filter(
74
+ (_, i) => i !== ssrIndex && !(hasSsrFile && i === ssrIndex + 1)
75
+ )
76
+ }
@@ -0,0 +1,38 @@
1
+ import { spawn } from "cross-spawn"
2
+
3
+ /**
4
+ * @param {string[]} args
5
+ * @returns {Promise<number>}
6
+ */
7
+ async function runVite(args) {
8
+ return new Promise((resolve, reject) => {
9
+ const process = spawn("vite", args, { stdio: "inherit" })
10
+
11
+ process.on("close", (code) => {
12
+ if (code === 0) {
13
+ resolve(code)
14
+ } else {
15
+ reject(new Error(`Process exited with code ${code}`))
16
+ }
17
+ })
18
+ })
19
+ }
20
+
21
+ /**
22
+ * @param {string[]} args
23
+ * @param {boolean} [isOneBuild]
24
+ * @returns {Promise<void>}
25
+ */
26
+ export async function runMinista(args, isOneBuild) {
27
+ const isBuild = args.includes("build")
28
+
29
+ try {
30
+ if (isBuild && !isOneBuild) {
31
+ await runVite([...args, "--ssr"])
32
+ }
33
+ await runVite(args)
34
+ } catch (error) {
35
+ console.error(error)
36
+ process.exit(1)
37
+ }
38
+ }
@@ -0,0 +1,33 @@
1
+ import fs from "node:fs"
2
+ import path from "node:path"
3
+
4
+ /**
5
+ * @param {string} [rootArg]
6
+ * @returns {string}
7
+ */
8
+ export function findConfigFile(rootArg) {
9
+ const cwd = process.cwd()
10
+ const configFileList = [
11
+ "minista.config.js",
12
+ "minista.config.cjs",
13
+ "minista.config.mjs",
14
+ "minista.config.ts",
15
+ "minista.config.cts",
16
+ "minista.config.mts",
17
+ ]
18
+ if (rootArg) {
19
+ for (const fileName of configFileList) {
20
+ const filePath = path.resolve(cwd, rootArg, fileName)
21
+ if (fs.existsSync(filePath)) {
22
+ return path.resolve(rootArg, fileName)
23
+ }
24
+ }
25
+ }
26
+ for (const fileName of configFileList) {
27
+ const filePath = path.resolve(cwd, fileName)
28
+ if (fs.existsSync(filePath)) {
29
+ return fileName
30
+ }
31
+ }
32
+ return ""
33
+ }
@@ -0,0 +1,3 @@
1
+ /// <reference types="vite/client" />
2
+ /// <reference path="./plugins/mdx/client.d.ts" />
3
+ /// <reference path="./plugins/island/client.d.ts" />
@@ -0,0 +1,3 @@
1
+ import type { Context } from "react"
2
+
3
+ export declare const HeadContext: Context<{}>
package/src/context.js ADDED
@@ -0,0 +1,3 @@
1
+ import { createContext } from "react"
2
+
3
+ export const HeadContext = createContext({})
package/src/head.d.ts ADDED
@@ -0,0 +1,7 @@
1
+ import type { HeadData } from "./plugins/ssg/types"
2
+
3
+ export declare function Head(
4
+ props: HeadData & {
5
+ children?: React.ReactNode
6
+ }
7
+ ): null
package/src/head.js ADDED
@@ -0,0 +1 @@
1
+ export { Head } from "./plugins/ssg/components/head.js"
package/src/node.d.ts ADDED
@@ -0,0 +1,29 @@
1
+ import type { Plugin } from "vite"
2
+ import { defineConfig as defineViteConfig } from "vite"
3
+
4
+ import type { UserPluginOptions as PluginSsgOptions } from "./plugins/ssg/types"
5
+ import type { UserPluginOptions as PluginBundleOptions } from "./plugins/bundle/types"
6
+ import type { UserPluginOptions as PluginEntryOptions } from "./plugins/entry/types"
7
+ import type { UserPluginOptions as PluginMdxOptions } from "./plugins/mdx/types"
8
+ import type { UserPluginOptions as PluginImageOptions } from "./plugins/image/types"
9
+ import type { UserPluginOptions as PluginSvgOptions } from "./plugins/svg/types"
10
+ import type { UserPluginOptions as PluginSpriteOptions } from "./plugins/sprite/types"
11
+ import type { UserPluginOptions as PluginCommentOptions } from "./plugins/comment/types"
12
+ import type { UserPluginOptions as PluginIslandOptions } from "./plugins/island"
13
+ import type { UserPluginOptions as PluginSearchOptions } from "./plugins/search/types"
14
+ import type { UserPluginOptions as PluginBeautifyOptions } from "./plugins/beautify"
15
+ import type { UserPluginOptions as PluginArchiveOptions } from "./plugins/archive/types"
16
+
17
+ export declare const defineConfig: typeof defineViteConfig
18
+ export declare function pluginSsg(options?: PluginSsgOptions): Plugin
19
+ export declare function pluginBundle(options?: PluginBundleOptions): Plugin
20
+ export declare function pluginEntry(options?: PluginEntryOptions): Plugin
21
+ export declare function pluginMdx(options?: PluginMdxOptions): Plugin
22
+ export declare function pluginImage(options?: PluginImageOptions): Plugin
23
+ export declare function pluginSvg(options?: PluginSvgOptions): Plugin
24
+ export declare function pluginSprite(options?: PluginSpriteOptions): Plugin
25
+ export declare function pluginComment(options?: PluginCommentOptions): Plugin
26
+ export declare function pluginIsland(options?: PluginIslandOptions): Plugin
27
+ export declare function pluginSearch(options?: PluginSearchOptions): Plugin
28
+ export declare function pluginBeautify(options?: PluginBeautifyOptions): Plugin
29
+ export declare function pluginArchive(options?: PluginArchiveOptions): Plugin
package/src/node.js ADDED
@@ -0,0 +1,13 @@
1
+ export { defineConfig } from "vite"
2
+ export { pluginSsg } from "./plugins/ssg/index.js"
3
+ export { pluginBundle } from "./plugins/bundle/index.js"
4
+ export { pluginEntry } from "./plugins/entry/index.js"
5
+ export { pluginMdx } from "./plugins/mdx/index.js"
6
+ export { pluginImage } from "./plugins/image/index.js"
7
+ export { pluginSvg } from "./plugins/svg/index.js"
8
+ export { pluginSprite } from "./plugins/sprite/index.js"
9
+ export { pluginComment } from "./plugins/comment/index.js"
10
+ export { pluginIsland } from "./plugins/island/index.js"
11
+ export { pluginSearch } from "./plugins/search/index.js"
12
+ export { pluginBeautify } from "./plugins/beautify/index.js"
13
+ export { pluginArchive } from "./plugins/archive/index.js"
@@ -0,0 +1,115 @@
1
+ /** @typedef {import('vite').Plugin} Plugin */
2
+ /** @typedef {import('./types').PluginOptions} PluginOptions */
3
+ /** @typedef {import('./types').UserPluginOptions} UserPluginOptions */
4
+
5
+ import fs from "node:fs"
6
+ import path from "node:path"
7
+ import archiver from "archiver"
8
+ import pc from "picocolors"
9
+ import { normalizePath } from "vite"
10
+
11
+ import { getRootDir, getTempDir } from "../../shared/path.js"
12
+
13
+ /** @type {PluginOptions} */
14
+ export const defaultOptions = {
15
+ archives: [
16
+ {
17
+ srcDir: "dist",
18
+ outName: "dist",
19
+ },
20
+ ],
21
+ }
22
+
23
+ /**
24
+ * @param {UserPluginOptions} uOpts
25
+ * @returns {Plugin}
26
+ */
27
+ export function pluginArchive(uOpts = {}) {
28
+ /** @type {PluginOptions} */
29
+ const opts = { ...defaultOptions, ...uOpts }
30
+ const cwd = process.cwd()
31
+
32
+ let isDev = false
33
+ let isSsr = false
34
+ let isBuild = false
35
+
36
+ let rootDir = ""
37
+ let tempDir = ""
38
+ let archiveDir = ""
39
+
40
+ return {
41
+ name: "vite-plugin:minista-archive",
42
+ enforce: "post",
43
+ apply(_, { command, isSsrBuild }) {
44
+ isDev = command === "serve"
45
+ isSsr = command === "build" && Boolean(isSsrBuild)
46
+ isBuild = command === "build" && !isSsrBuild
47
+ return isBuild
48
+ },
49
+ config: (config) => {
50
+ rootDir = getRootDir(cwd, config.root || "")
51
+ tempDir = getTempDir(cwd, rootDir)
52
+ archiveDir = path.resolve(tempDir, "archive")
53
+ },
54
+ async writeBundle(options) {
55
+ const dist = options.dir
56
+ if (!dist) return
57
+
58
+ await fs.promises.mkdir(archiveDir, { recursive: true })
59
+ await Promise.all(
60
+ opts.archives.map(async (archive) => {
61
+ const { srcDir, outName } = archive
62
+ const ignore = archive.ignore || []
63
+ const format = archive.format || "zip"
64
+ const archOpts = archive.options || { zlib: { level: 9 } }
65
+ const outFile = `${outName}.${format}`
66
+ const archiveFile = path.resolve(archiveDir, outFile)
67
+
68
+ try {
69
+ await new Promise((resolve, reject) => {
70
+ const archive = archiver(format, archOpts)
71
+ const output = fs.createWriteStream(archiveFile)
72
+
73
+ output.on("error", reject)
74
+ archive.on("error", reject)
75
+ archive.on("warning", (err) => {
76
+ if (err.code === "ENOENT") {
77
+ console.warn(pc.yellow(`Archive warning: ${err.message}`))
78
+ } else {
79
+ reject(err)
80
+ }
81
+ })
82
+ output.on("close", () => resolve(undefined))
83
+
84
+ archive.pipe(output)
85
+ archive.glob(`${normalizePath(srcDir)}/**/*`, {
86
+ cwd: rootDir,
87
+ ignore,
88
+ })
89
+ archive.finalize()
90
+ })
91
+
92
+ const finalPath = path.resolve(dist, outFile)
93
+ await fs.promises.copyFile(archiveFile, finalPath)
94
+
95
+ const rel = path.relative(rootDir, path.dirname(finalPath))
96
+ console.log(
97
+ pc.gray(
98
+ normalizePath(rel + path.sep) +
99
+ pc.green(path.basename(finalPath)),
100
+ ),
101
+ )
102
+ } catch (err) {
103
+ if (err instanceof Error) {
104
+ console.error(
105
+ pc.red(`Error creating archive ${outName}: ${err.message}`),
106
+ )
107
+ } else {
108
+ console.error(pc.red(`An unknown error occurred: ${err}`))
109
+ }
110
+ }
111
+ }),
112
+ )
113
+ },
114
+ }
115
+ }
@@ -0,0 +1,14 @@
1
+ import type { Format as ArchiverFormat, ArchiverOptions } from "archiver"
2
+
3
+ export type ArchiveOptions = {
4
+ srcDir: string
5
+ outName: string
6
+ ignore?: string | string[]
7
+ format?: ArchiverFormat
8
+ options?: ArchiverOptions
9
+ }
10
+
11
+ export type PluginOptions = {
12
+ archives: ArchiveOptions[]
13
+ }
14
+ export type UserPluginOptions = Partial<PluginOptions>