minista 0.10.3 → 1.0.0
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.
- package/README.md +190 -19
- package/cli.js +118 -70
- package/index.d.ts +4 -0
- package/main.js +0 -1
- package/package.json +20 -13
- package/webpack.config.js +134 -27
package/README.md
CHANGED
|
@@ -14,11 +14,12 @@
|
|
|
14
14
|
|
|
15
15
|
## About
|
|
16
16
|
|
|
17
|
-
minista(ミニスタ)は、React(JSX)
|
|
17
|
+
minista(ミニスタ)は、React (TSX/JSX)で書けるスタティックサイトジェネレーターです。SaaS の web テンプレートコーディング業務を想定し、ビルド時の納品用データが綺麗(ヒューマンリーダブル)であることを重視しています。
|
|
18
18
|
|
|
19
19
|
- ゼロコンフィグで始められる
|
|
20
|
-
- React(JSX)
|
|
21
|
-
- CSS と JavaScript
|
|
20
|
+
- React (TSX/JSX)から 100%静的な HTML を出力
|
|
21
|
+
- CSS と JavaScript を個別に Minify 出力
|
|
22
|
+
- SVG スプライトアイコンを自動生成
|
|
22
23
|
- Next.js 風のディレクトリ構成
|
|
23
24
|
|
|
24
25
|
## How To Use
|
|
@@ -54,16 +55,15 @@ src
|
|
|
54
55
|
// Page Example
|
|
55
56
|
//----------------------------------------------------
|
|
56
57
|
|
|
57
|
-
import React from "react" // Required!
|
|
58
58
|
import { render } from "minista" // Required!
|
|
59
59
|
|
|
60
|
-
const
|
|
61
|
-
return
|
|
60
|
+
const PageHome = () => {
|
|
61
|
+
return (
|
|
62
62
|
<h1>Hello</h1>
|
|
63
63
|
)
|
|
64
64
|
}
|
|
65
65
|
|
|
66
|
-
export default
|
|
66
|
+
export default render(PageHome) // Required!
|
|
67
67
|
```
|
|
68
68
|
|
|
69
69
|
#### Develop
|
|
@@ -89,11 +89,10 @@ $ minista build
|
|
|
89
89
|
#### Input
|
|
90
90
|
|
|
91
91
|
```js
|
|
92
|
-
import React from "react"
|
|
93
92
|
import { render, Comment } from "minista"
|
|
94
93
|
|
|
95
|
-
const
|
|
96
|
-
return
|
|
94
|
+
const PageHome = () => {
|
|
95
|
+
return (
|
|
97
96
|
<>
|
|
98
97
|
<Comment text="Comment Test" />
|
|
99
98
|
<h1>Hello</h1>
|
|
@@ -101,7 +100,7 @@ const Home = () => {
|
|
|
101
100
|
)
|
|
102
101
|
}
|
|
103
102
|
|
|
104
|
-
export default
|
|
103
|
+
export default render(PageHome)
|
|
105
104
|
```
|
|
106
105
|
|
|
107
106
|
#### output
|
|
@@ -123,7 +122,131 @@ export default Home
|
|
|
123
122
|
|
|
124
123
|
### webpack
|
|
125
124
|
|
|
126
|
-
プロジェクトの root に `webpack.config.js`
|
|
125
|
+
プロジェクトの root に `webpack.config.js` を配置することで設定をマージできます。
|
|
126
|
+
|
|
127
|
+
```js
|
|
128
|
+
//----------------------------------------------------
|
|
129
|
+
// Example: User > webpack.config.js
|
|
130
|
+
//----------------------------------------------------
|
|
131
|
+
|
|
132
|
+
// No installation required.
|
|
133
|
+
const MiniCssExtractPlugin = require("mini-css-extract-plugin")
|
|
134
|
+
const CopyPlugin = require("copy-webpack-plugin")
|
|
135
|
+
|
|
136
|
+
// Example of dev mode
|
|
137
|
+
const isDev = process.env.NODE_ENV !== "production"
|
|
138
|
+
|
|
139
|
+
const webpackConfig = {
|
|
140
|
+
// Merge
|
|
141
|
+
devServer: {
|
|
142
|
+
open: ["/index.html"],
|
|
143
|
+
},
|
|
144
|
+
plugins: [
|
|
145
|
+
// Replace
|
|
146
|
+
new MiniCssExtractPlugin({
|
|
147
|
+
filename: "assets/[name].css",
|
|
148
|
+
}),
|
|
149
|
+
// Replace
|
|
150
|
+
new CopyPlugin({
|
|
151
|
+
patterns: [{ from: "./static", to: "./", noErrorOnMissing: true }],
|
|
152
|
+
}),
|
|
153
|
+
],
|
|
154
|
+
|
|
155
|
+
// All optimization is replaced.
|
|
156
|
+
optimization: {
|
|
157
|
+
minimize: !isDev,
|
|
158
|
+
minimizer: [
|
|
159
|
+
/* Replace plugins */
|
|
160
|
+
],
|
|
161
|
+
},
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
module.exports = webpackConfig
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### TypeScript
|
|
168
|
+
|
|
169
|
+
TypeScript `.tsx` でページを作成する場合はモジュールを追加し `tsconfig.json` をプロジェクトの root に配置。エントリーポイントとして `src/assets/index.ts` があれば `src/assets/index.js` の代わりに使用します。
|
|
170
|
+
|
|
171
|
+
```bash
|
|
172
|
+
$ npm install --save-dev typescript @types/react @types/react-dom
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
```json
|
|
176
|
+
{
|
|
177
|
+
"compilerOptions": {
|
|
178
|
+
"target": "esnext",
|
|
179
|
+
"module": "esnext",
|
|
180
|
+
"baseUrl": ".",
|
|
181
|
+
"allowJs": true,
|
|
182
|
+
"strict": true,
|
|
183
|
+
"noImplicitAny": false,
|
|
184
|
+
"strictNullChecks": true,
|
|
185
|
+
"noUnusedLocals": true,
|
|
186
|
+
"noUnusedParameters": true,
|
|
187
|
+
"noImplicitReturns": true,
|
|
188
|
+
"moduleResolution": "node",
|
|
189
|
+
"esModuleInterop": true,
|
|
190
|
+
"isolatedModules": false,
|
|
191
|
+
"skipLibCheck": true,
|
|
192
|
+
"forceConsistentCasingInFileNames": true,
|
|
193
|
+
"resolveJsonModule": true,
|
|
194
|
+
"jsx": "react-jsx"
|
|
195
|
+
},
|
|
196
|
+
"include": ["**/*.ts", "**/*.tsx"],
|
|
197
|
+
"exclude": ["node_modules", "dist", "webpack.config.js"]
|
|
198
|
+
}
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
```bash
|
|
202
|
+
# ----------------------------------------------------
|
|
203
|
+
# Directory Example
|
|
204
|
+
# ----------------------------------------------------
|
|
205
|
+
|
|
206
|
+
public # Copy root
|
|
207
|
+
src
|
|
208
|
+
├── assets
|
|
209
|
+
│ └── index.ts (or index.js) # Required!
|
|
210
|
+
├── components
|
|
211
|
+
│ └── layout.js
|
|
212
|
+
└── pages # Required!
|
|
213
|
+
├── about
|
|
214
|
+
│ └── index.tsx
|
|
215
|
+
└── index.tsx
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
### Babel
|
|
219
|
+
|
|
220
|
+
Babel はプロジェクトの root に `.babelrc` もしくは `babel.config.js` を配置することで設定を上書きできます。カスタマイズしない場合は以下の設定が適応されます。
|
|
221
|
+
|
|
222
|
+
```js
|
|
223
|
+
// JavaScript
|
|
224
|
+
const babelJsxOptions = {
|
|
225
|
+
presets: [
|
|
226
|
+
"@babel/preset-env",
|
|
227
|
+
[
|
|
228
|
+
"@babel/preset-react",
|
|
229
|
+
{
|
|
230
|
+
runtime: "automatic",
|
|
231
|
+
},
|
|
232
|
+
],
|
|
233
|
+
],
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// TypeScript
|
|
237
|
+
const babelTsxOptions = {
|
|
238
|
+
presets: [
|
|
239
|
+
"@babel/preset-env",
|
|
240
|
+
[
|
|
241
|
+
"@babel/preset-react",
|
|
242
|
+
{
|
|
243
|
+
runtime: "automatic",
|
|
244
|
+
},
|
|
245
|
+
],
|
|
246
|
+
["@babel/preset-typescript"],
|
|
247
|
+
],
|
|
248
|
+
}
|
|
249
|
+
```
|
|
127
250
|
|
|
128
251
|
### PostCSS
|
|
129
252
|
|
|
@@ -131,12 +254,12 @@ PostCSS はゼロコンフィグで以下のプラグインが適応されます
|
|
|
131
254
|
|
|
132
255
|
```js
|
|
133
256
|
module.exports = {
|
|
134
|
-
plugins:
|
|
135
|
-
"postcss-import"
|
|
136
|
-
"postcss-flexbugs-fixes"
|
|
137
|
-
"postcss-sort-media-queries"
|
|
138
|
-
"postcss-preset-env"
|
|
139
|
-
|
|
257
|
+
plugins: [
|
|
258
|
+
"postcss-import",
|
|
259
|
+
"postcss-flexbugs-fixes",
|
|
260
|
+
"postcss-sort-media-queries",
|
|
261
|
+
"postcss-preset-env",
|
|
262
|
+
],
|
|
140
263
|
}
|
|
141
264
|
```
|
|
142
265
|
|
|
@@ -148,18 +271,66 @@ module.exports = {
|
|
|
148
271
|
$ npm install --save-dev sass-loader sass
|
|
149
272
|
```
|
|
150
273
|
|
|
274
|
+
### Style only
|
|
275
|
+
|
|
276
|
+
プロジェクトに JavaScript が全く必要ない場合はエントリーポイントを CSS ファイルに変更します。これにより空の JavaScript ファイルを出力することなく納品用データを生成できます。
|
|
277
|
+
|
|
278
|
+
```js
|
|
279
|
+
//----------------------------------------------------
|
|
280
|
+
// Example: User > webpack.config.js
|
|
281
|
+
//----------------------------------------------------
|
|
282
|
+
|
|
283
|
+
const webpackConfig = {
|
|
284
|
+
entry: { bundle: "./src/assets/index.css" },
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
module.exports = webpackConfig
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
### SVG sprite icons
|
|
291
|
+
|
|
292
|
+
`src/assets/icons` ディレクトリに SVG ファイルを置くと SVG スプライトアイコンの `dist/assets/icons.svg` が生成されます。以下のようなコンポーネントを作ることでアイコンを呼び出せます。
|
|
293
|
+
|
|
294
|
+
```js
|
|
295
|
+
// Example: ./src/components/svg-sprite-icon.tsx
|
|
296
|
+
export interface SvgSpriteIconProps {
|
|
297
|
+
iconId?: string;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
export const SvgSpriteIcon = (props: SvgSpriteIconProps) => {
|
|
301
|
+
const { iconId } = props
|
|
302
|
+
return (
|
|
303
|
+
<svg className="icon" role="img">
|
|
304
|
+
<use xlinkHref={`/assets/icons.svg#${iconId}`} />
|
|
305
|
+
</svg>
|
|
306
|
+
)
|
|
307
|
+
}
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
```html
|
|
311
|
+
<!-- dist html -->
|
|
312
|
+
<svg role="img" class="icon">
|
|
313
|
+
<use xlink:href="/assets/icons.svg#star"></use>
|
|
314
|
+
</svg>
|
|
315
|
+
```
|
|
316
|
+
|
|
151
317
|
## Media
|
|
152
318
|
|
|
153
319
|
- [React(JSX)で書けるコーディング用 SSG - minista v0](https://zenn.dev/qrac/articles/7537521afcd1bf)
|
|
154
320
|
|
|
155
321
|
## Respect
|
|
156
322
|
|
|
157
|
-
- [Charge — an opinionated, zero-config static site generator](https://charge.js.org/)
|
|
158
323
|
- [Next.js by Vercel - The React Framework](https://nextjs.org/)
|
|
324
|
+
- [Charge — an opinionated, zero-config static site generator](https://charge.js.org/)
|
|
325
|
+
- [Eleventy, a simpler static site generator.](https://www.11ty.dev/)
|
|
159
326
|
- [Node Interface | webpack](https://webpack.js.org/api/node/)
|
|
327
|
+
- [natemoo-re/microsite](https://github.com/natemoo-re/microsite)
|
|
328
|
+
- [Astro](https://astro.build/)
|
|
160
329
|
- [テンプレートエンジンに React を使いつつ、きれいな HTML を生成したいんじゃ!!](https://zenn.dev/otsukayuhi/articles/e52651b4e2c5ae7c4a17)
|
|
161
330
|
- [EJS をやめて React で HTML を書く](https://zenn.dev/hisho/scraps/4ef6c6106a6395)
|
|
162
331
|
- [MPA(マルチページアプリ)で webpack を使う](https://www.key-p.com/blog/staff/archives/107125)
|
|
332
|
+
- [HTML コーディングでも React+TypeScript の開発体験を得る](https://zenn.dev/nanaki14/articles/html-template-react)
|
|
333
|
+
- [Astro と microCMS でポートフォリオサイトを作る](https://zenn.dev/takanorip/articles/c75717c280c81d)
|
|
163
334
|
|
|
164
335
|
## License
|
|
165
336
|
|
package/cli.js
CHANGED
|
@@ -1,78 +1,79 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
//----------------------------------------------------
|
|
4
|
-
// Global Require
|
|
5
|
-
//----------------------------------------------------
|
|
6
|
-
|
|
7
2
|
const fs = require("fs")
|
|
8
3
|
const path = require("path")
|
|
9
4
|
const glob = require("glob")
|
|
10
|
-
|
|
11
|
-
//----------------------------------------------------
|
|
12
|
-
// Variables
|
|
13
|
-
//----------------------------------------------------
|
|
14
|
-
|
|
15
|
-
const isDev = process.argv[2] !== "build"
|
|
16
|
-
process.env.NODE_ENV = isDev ? "development" : "production"
|
|
17
|
-
|
|
18
|
-
//----------------------------------------------------
|
|
19
|
-
// webpack
|
|
20
|
-
//----------------------------------------------------
|
|
21
|
-
|
|
22
5
|
const webpack = require("webpack")
|
|
23
|
-
const {
|
|
6
|
+
const { mergeWithCustomize, customizeObject, unique } = require("webpack-merge")
|
|
24
7
|
const webpackDevServer = require("webpack-dev-server")
|
|
25
|
-
const
|
|
26
|
-
|
|
27
|
-
const webpackConfig = require("./webpack.config")
|
|
28
|
-
const userWebpackConfig = fs.existsSync(path.resolve("webpack.config.js"))
|
|
29
|
-
? require(path.resolve("webpack.config"))
|
|
30
|
-
: {}
|
|
31
|
-
const mergedWebpackConfig = merge(webpackConfig, userWebpackConfig)
|
|
8
|
+
const beautify = require("js-beautify")
|
|
32
9
|
|
|
33
|
-
|
|
34
|
-
(
|
|
35
|
-
|
|
36
|
-
const otherPlugins = mergedWebpackConfig.plugins.filter(
|
|
37
|
-
(plugin) => plugin.constructor !== HtmlWebpackPlugin
|
|
38
|
-
)
|
|
39
|
-
const mergedHtmlPlugins = [
|
|
40
|
-
...new Map(
|
|
41
|
-
htmlPlugins.map((plugin) => [plugin.userOptions.filename, plugin])
|
|
42
|
-
).values(),
|
|
43
|
-
]
|
|
44
|
-
const mergedPlugins = [...mergedHtmlPlugins, ...otherPlugins]
|
|
45
|
-
mergedWebpackConfig.plugins = mergedPlugins
|
|
10
|
+
function getWebpackConfig() {
|
|
11
|
+
return require("./webpack.config")
|
|
12
|
+
}
|
|
46
13
|
|
|
47
|
-
|
|
48
|
-
|
|
14
|
+
function getUserWebpackConfig() {
|
|
15
|
+
if (fs.existsSync(path.resolve("webpack.config.js"))) {
|
|
16
|
+
return require(path.resolve("webpack.config"))
|
|
17
|
+
} else {
|
|
18
|
+
return {}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
49
21
|
|
|
50
|
-
|
|
22
|
+
function getMergedWebpackConfig({ config, userConfig }) {
|
|
23
|
+
const mergedConfig = mergeWithCustomize({
|
|
24
|
+
customizeObject: customizeObject({
|
|
25
|
+
optimization: "replace",
|
|
26
|
+
}),
|
|
27
|
+
customizeArray: unique(
|
|
28
|
+
"plugins",
|
|
29
|
+
["MiniCssExtractPlugin", "CopyPlugin"],
|
|
30
|
+
(plugin) => plugin.constructor && plugin.constructor.name
|
|
31
|
+
),
|
|
32
|
+
})(config, userConfig)
|
|
33
|
+
const filterdPlugins = filterWebpackPlugins({
|
|
34
|
+
plugins: mergedConfig.plugins,
|
|
35
|
+
})
|
|
36
|
+
mergedConfig.plugins = filterdPlugins
|
|
37
|
+
return mergedConfig
|
|
38
|
+
}
|
|
51
39
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
colors: true,
|
|
59
|
-
})
|
|
60
|
-
)
|
|
61
|
-
beautifyHTML()
|
|
40
|
+
function filterWebpackPlugins({ plugins }) {
|
|
41
|
+
const filterdHtmlWebpackPlugins = filterHtmlWebpackPlugins({
|
|
42
|
+
plugins: plugins,
|
|
43
|
+
})
|
|
44
|
+
const filteredOtherWebpackPlugins = filterOtherWebpackPlugins({
|
|
45
|
+
plugins: plugins,
|
|
62
46
|
})
|
|
47
|
+
return [...filterdHtmlWebpackPlugins, ...filteredOtherWebpackPlugins]
|
|
48
|
+
}
|
|
63
49
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
50
|
+
function filterHtmlWebpackPlugins({ plugins }) {
|
|
51
|
+
const htmlWebpackPlugins = plugins.filter(
|
|
52
|
+
(plugin) => plugin.constructor.name === "HtmlWebpackPlugin"
|
|
53
|
+
)
|
|
54
|
+
const mergedHtmlWebpackPlugins = [
|
|
55
|
+
...new Map(
|
|
56
|
+
htmlWebpackPlugins.map((plugin) => [plugin.userOptions.filename, plugin])
|
|
57
|
+
).values(),
|
|
58
|
+
]
|
|
59
|
+
return mergedHtmlWebpackPlugins
|
|
60
|
+
}
|
|
67
61
|
|
|
68
|
-
|
|
69
|
-
const
|
|
70
|
-
|
|
71
|
-
|
|
62
|
+
function filterOtherWebpackPlugins({ plugins }) {
|
|
63
|
+
const otherPlugins = plugins.filter(
|
|
64
|
+
(plugin) => plugin.constructor.name !== "HtmlWebpackPlugin"
|
|
65
|
+
)
|
|
66
|
+
return otherPlugins
|
|
72
67
|
}
|
|
73
68
|
|
|
74
|
-
|
|
75
|
-
|
|
69
|
+
function beautifyHtmlFiles({
|
|
70
|
+
htmlFilesPath,
|
|
71
|
+
beautifyOptions = {
|
|
72
|
+
indent_size: 2,
|
|
73
|
+
max_preserve_newlines: 0,
|
|
74
|
+
},
|
|
75
|
+
}) {
|
|
76
|
+
glob.sync(htmlFilesPath).forEach((file) => {
|
|
76
77
|
fs.readFile(file, "utf8", (err, html) => {
|
|
77
78
|
if (err) console.log(err)
|
|
78
79
|
if (err) return
|
|
@@ -86,16 +87,63 @@ const beautifyHTML = () => {
|
|
|
86
87
|
})
|
|
87
88
|
}
|
|
88
89
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
90
|
+
function webpackBuildWithBeautify({
|
|
91
|
+
webpackCompiler,
|
|
92
|
+
runBeautify = true,
|
|
93
|
+
htmlFilesPath,
|
|
94
|
+
}) {
|
|
95
|
+
webpackCompiler.run((err, stats) => {
|
|
96
|
+
err && console.log(err)
|
|
97
|
+
stats &&
|
|
98
|
+
console.log(
|
|
99
|
+
stats.toString({
|
|
100
|
+
colors: true,
|
|
101
|
+
})
|
|
102
|
+
)
|
|
103
|
+
runBeautify && beautifyHtmlFiles({ htmlFilesPath: htmlFilesPath })
|
|
104
|
+
})
|
|
105
|
+
}
|
|
92
106
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
107
|
+
function ministaCommand({
|
|
108
|
+
process,
|
|
109
|
+
webpackCompiler,
|
|
110
|
+
webpackDevServerOptions,
|
|
111
|
+
runBeautify,
|
|
112
|
+
htmlFilesPath,
|
|
113
|
+
}) {
|
|
114
|
+
if (process.argv[2] === undefined || process.argv[2] === "dev") {
|
|
115
|
+
const webpackDev = new webpackDevServer(
|
|
116
|
+
webpackDevServerOptions,
|
|
117
|
+
webpackCompiler
|
|
118
|
+
)
|
|
119
|
+
return webpackDev.start()
|
|
120
|
+
} else if (process.argv[2] === "build") {
|
|
121
|
+
return webpackBuildWithBeautify({
|
|
122
|
+
webpackCompiler: webpackCompiler,
|
|
123
|
+
runBeautify: runBeautify,
|
|
124
|
+
htmlFilesPath: htmlFilesPath,
|
|
125
|
+
})
|
|
126
|
+
} else {
|
|
100
127
|
return console.log("Command error!\nminista dev or minista build")
|
|
128
|
+
}
|
|
101
129
|
}
|
|
130
|
+
|
|
131
|
+
const isDev = process.argv[2] !== "build"
|
|
132
|
+
process.env.NODE_ENV = isDev ? "development" : "production"
|
|
133
|
+
|
|
134
|
+
const webpackConfig = getWebpackConfig()
|
|
135
|
+
const userWebpackConfig = getUserWebpackConfig()
|
|
136
|
+
const mergedWebpackConfig = getMergedWebpackConfig({
|
|
137
|
+
config: webpackConfig,
|
|
138
|
+
userConfig: userWebpackConfig,
|
|
139
|
+
})
|
|
140
|
+
const webpackCompiler = webpack(mergedWebpackConfig)
|
|
141
|
+
const webpackDevServerOptions = Object.assign({}, mergedWebpackConfig.devServer)
|
|
142
|
+
|
|
143
|
+
ministaCommand({
|
|
144
|
+
process: process,
|
|
145
|
+
webpackCompiler: webpackCompiler,
|
|
146
|
+
webpackDevServerOptions: webpackDevServerOptions,
|
|
147
|
+
runBeautify: true,
|
|
148
|
+
htmlFilesPath: "dist/**/*.html",
|
|
149
|
+
})
|
package/index.d.ts
ADDED
package/main.js
CHANGED
package/package.json
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "minista",
|
|
3
3
|
"description": "Mini static site generator that can be written in React (JSX) for web coding",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "1.0.0",
|
|
5
5
|
"bin": {
|
|
6
6
|
"minista": "cli.js"
|
|
7
7
|
},
|
|
8
8
|
"main": "./main.js",
|
|
9
|
+
"types": "./index.d.ts",
|
|
9
10
|
"files": [
|
|
10
11
|
"main.js",
|
|
11
12
|
"cli.js",
|
|
12
|
-
"
|
|
13
|
+
"index.d.ts",
|
|
13
14
|
"webpack.config.js"
|
|
14
15
|
],
|
|
15
16
|
"license": "MIT",
|
|
@@ -27,6 +28,8 @@
|
|
|
27
28
|
"coding",
|
|
28
29
|
"react",
|
|
29
30
|
"jsx",
|
|
31
|
+
"tsx",
|
|
32
|
+
"typescript",
|
|
30
33
|
"webpack",
|
|
31
34
|
"japanese",
|
|
32
35
|
"minista"
|
|
@@ -48,27 +51,31 @@
|
|
|
48
51
|
"react-dom": "^17.0.2"
|
|
49
52
|
},
|
|
50
53
|
"dependencies": {
|
|
51
|
-
"@babel/core": "^7.16.
|
|
52
|
-
"@babel/preset-env": "^7.16.
|
|
53
|
-
"@babel/preset-react": "^7.16.
|
|
54
|
+
"@babel/core": "^7.16.7",
|
|
55
|
+
"@babel/preset-env": "^7.16.8",
|
|
56
|
+
"@babel/preset-react": "^7.16.7",
|
|
57
|
+
"@babel/preset-typescript": "^7.16.7",
|
|
54
58
|
"babel-loader": "^8.2.3",
|
|
55
|
-
"copy-webpack-plugin": "^10.
|
|
59
|
+
"copy-webpack-plugin": "^10.2.0",
|
|
56
60
|
"css-loader": "^6.5.1",
|
|
57
|
-
"css-minimizer-webpack-plugin": "^3.
|
|
61
|
+
"css-minimizer-webpack-plugin": "^3.3.1",
|
|
58
62
|
"glob": "^7.2.0",
|
|
59
63
|
"html-replace-webpack-plugin": "^2.6.0",
|
|
60
64
|
"html-webpack-plugin": "^5.5.0",
|
|
61
65
|
"js-beautify": "^1.14.0",
|
|
62
|
-
"mini-css-extract-plugin": "^2.4.
|
|
63
|
-
"postcss": "^8.4.
|
|
66
|
+
"mini-css-extract-plugin": "^2.4.6",
|
|
67
|
+
"postcss": "^8.4.5",
|
|
64
68
|
"postcss-flexbugs-fixes": "^5.0.2",
|
|
65
69
|
"postcss-import": "^14.0.2",
|
|
66
70
|
"postcss-loader": "^6.2.1",
|
|
67
|
-
"postcss-preset-env": "^7.
|
|
71
|
+
"postcss-preset-env": "^7.2.1",
|
|
68
72
|
"postcss-sort-media-queries": "^4.2.1",
|
|
69
73
|
"react-helmet": "^6.1.0",
|
|
70
|
-
"
|
|
71
|
-
"
|
|
72
|
-
"webpack
|
|
74
|
+
"svg-sprite-loader": "^6.0.11",
|
|
75
|
+
"ts-loader": "^9.2.6",
|
|
76
|
+
"webpack": "^5.66.0",
|
|
77
|
+
"webpack-dev-server": "^4.7.3",
|
|
78
|
+
"webpack-merge": "^5.8.0",
|
|
79
|
+
"webpack-remove-empty-scripts": "^0.7.2"
|
|
73
80
|
}
|
|
74
81
|
}
|
package/webpack.config.js
CHANGED
|
@@ -4,20 +4,89 @@ const glob = require("glob")
|
|
|
4
4
|
|
|
5
5
|
const HtmlWebpackPlugin = require("html-webpack-plugin")
|
|
6
6
|
const HtmlReplaceWebpackPlugin = require("html-replace-webpack-plugin")
|
|
7
|
+
const RemoveEmptyScriptsPlugin = require("webpack-remove-empty-scripts")
|
|
7
8
|
const MiniCssExtractPlugin = require("mini-css-extract-plugin")
|
|
9
|
+
const SpriteLoaderPlugin = require("svg-sprite-loader/plugin")
|
|
8
10
|
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin")
|
|
9
11
|
const TerserPlugin = require("terser-webpack-plugin")
|
|
10
12
|
const CopyPlugin = require("copy-webpack-plugin")
|
|
11
13
|
|
|
12
14
|
const isDev = process.env.NODE_ENV !== "production"
|
|
13
15
|
|
|
16
|
+
const babelJsxOptions = {
|
|
17
|
+
presets: [
|
|
18
|
+
"@babel/preset-env",
|
|
19
|
+
[
|
|
20
|
+
"@babel/preset-react",
|
|
21
|
+
{
|
|
22
|
+
runtime: "automatic",
|
|
23
|
+
},
|
|
24
|
+
],
|
|
25
|
+
],
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const babelTsxOptions = {
|
|
29
|
+
presets: [
|
|
30
|
+
"@babel/preset-env",
|
|
31
|
+
[
|
|
32
|
+
"@babel/preset-react",
|
|
33
|
+
{
|
|
34
|
+
runtime: "automatic",
|
|
35
|
+
},
|
|
36
|
+
],
|
|
37
|
+
["@babel/preset-typescript"],
|
|
38
|
+
],
|
|
39
|
+
}
|
|
40
|
+
|
|
14
41
|
const postcssOptions = {
|
|
15
|
-
plugins:
|
|
16
|
-
"postcss-import"
|
|
17
|
-
"postcss-flexbugs-fixes"
|
|
18
|
-
"postcss-sort-media-queries"
|
|
19
|
-
"postcss-preset-env"
|
|
20
|
-
|
|
42
|
+
plugins: [
|
|
43
|
+
"postcss-import",
|
|
44
|
+
"postcss-flexbugs-fixes",
|
|
45
|
+
"postcss-sort-media-queries",
|
|
46
|
+
"postcss-preset-env",
|
|
47
|
+
],
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function switchEntry() {
|
|
51
|
+
const filepath1 = "src/assets/index.js"
|
|
52
|
+
const filepath2 = "src/assets/index.ts"
|
|
53
|
+
const check = fs.existsSync(path.resolve(filepath1))
|
|
54
|
+
|
|
55
|
+
if (check) {
|
|
56
|
+
return "./" + filepath1
|
|
57
|
+
} else {
|
|
58
|
+
return "./" + filepath2
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function switchBabelOptions(useTsx) {
|
|
63
|
+
const filename1 = "babel.config.js"
|
|
64
|
+
const filename2 = ".babelrc"
|
|
65
|
+
const check1 = fs.existsSync(path.resolve(filename1))
|
|
66
|
+
const check2 = fs.existsSync(path.resolve(filename2))
|
|
67
|
+
|
|
68
|
+
const defaultOptions = useTsx ? babelTsxOptions : babelJsxOptions
|
|
69
|
+
|
|
70
|
+
if (check1) {
|
|
71
|
+
return require(path.resolve(filename1))
|
|
72
|
+
} else if (check2) {
|
|
73
|
+
return JSON.parse(fs.readFileSync(path.resolve(filename2), "utf8"))
|
|
74
|
+
} else {
|
|
75
|
+
return defaultOptions
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function switchPostcssOptions() {
|
|
80
|
+
const filename = "postcss.config.js"
|
|
81
|
+
const check = fs.existsSync(path.resolve(filename))
|
|
82
|
+
|
|
83
|
+
const defaultOptions = postcssOptions
|
|
84
|
+
|
|
85
|
+
if (check) {
|
|
86
|
+
return require(path.resolve(filename))
|
|
87
|
+
} else {
|
|
88
|
+
return defaultOptions
|
|
89
|
+
}
|
|
21
90
|
}
|
|
22
91
|
|
|
23
92
|
const webpackConfig = {
|
|
@@ -41,11 +110,12 @@ const webpackConfig = {
|
|
|
41
110
|
watchOptions: {
|
|
42
111
|
ignored: ["**/.git/**", "**/node_modules/**"],
|
|
43
112
|
},
|
|
44
|
-
entry:
|
|
113
|
+
entry: { bundle: switchEntry() },
|
|
45
114
|
output: {
|
|
46
115
|
path: path.resolve("dist"),
|
|
47
116
|
publicPath: "/",
|
|
48
|
-
filename: "assets/
|
|
117
|
+
filename: "assets/[name].js",
|
|
118
|
+
assetModuleFilename: "assets/images/[name].[ext]",
|
|
49
119
|
},
|
|
50
120
|
module: {
|
|
51
121
|
rules: [
|
|
@@ -54,9 +124,21 @@ const webpackConfig = {
|
|
|
54
124
|
use: [
|
|
55
125
|
{
|
|
56
126
|
loader: "babel-loader",
|
|
57
|
-
options:
|
|
58
|
-
|
|
59
|
-
|
|
127
|
+
options: switchBabelOptions(),
|
|
128
|
+
},
|
|
129
|
+
],
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
test: /\.ts(|x)$/,
|
|
133
|
+
exclude: /node_modules/,
|
|
134
|
+
use: [
|
|
135
|
+
{
|
|
136
|
+
loader: "babel-loader",
|
|
137
|
+
options: switchBabelOptions(true),
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
loader: "ts-loader",
|
|
141
|
+
options: { transpileOnly: true },
|
|
60
142
|
},
|
|
61
143
|
],
|
|
62
144
|
},
|
|
@@ -73,12 +155,10 @@ const webpackConfig = {
|
|
|
73
155
|
},
|
|
74
156
|
{
|
|
75
157
|
loader: "postcss-loader",
|
|
76
|
-
options:
|
|
77
|
-
|
|
78
|
-
:
|
|
79
|
-
|
|
80
|
-
postcssOptions: postcssOptions,
|
|
81
|
-
},
|
|
158
|
+
options: {
|
|
159
|
+
sourceMap: isDev,
|
|
160
|
+
postcssOptions: switchPostcssOptions(),
|
|
161
|
+
},
|
|
82
162
|
},
|
|
83
163
|
],
|
|
84
164
|
},
|
|
@@ -95,12 +175,10 @@ const webpackConfig = {
|
|
|
95
175
|
},
|
|
96
176
|
{
|
|
97
177
|
loader: "postcss-loader",
|
|
98
|
-
options:
|
|
99
|
-
|
|
100
|
-
:
|
|
101
|
-
|
|
102
|
-
postcssOptions: postcssOptions,
|
|
103
|
-
},
|
|
178
|
+
options: {
|
|
179
|
+
sourceMap: isDev,
|
|
180
|
+
postcssOptions: switchPostcssOptions(),
|
|
181
|
+
},
|
|
104
182
|
},
|
|
105
183
|
{
|
|
106
184
|
loader: "sass-loader",
|
|
@@ -120,6 +198,19 @@ const webpackConfig = {
|
|
|
120
198
|
filename: "assets/fonts/[name].[ext]",
|
|
121
199
|
},
|
|
122
200
|
},
|
|
201
|
+
{
|
|
202
|
+
test: /icons\/.*\.svg$/,
|
|
203
|
+
use: [
|
|
204
|
+
{
|
|
205
|
+
loader: "svg-sprite-loader",
|
|
206
|
+
options: {
|
|
207
|
+
extract: true,
|
|
208
|
+
spriteFilename: "assets/icons.svg",
|
|
209
|
+
runtimeCompat: true,
|
|
210
|
+
},
|
|
211
|
+
},
|
|
212
|
+
],
|
|
213
|
+
},
|
|
123
214
|
],
|
|
124
215
|
},
|
|
125
216
|
plugins: [
|
|
@@ -129,8 +220,12 @@ const webpackConfig = {
|
|
|
129
220
|
replacement: "<!-- $1 -->",
|
|
130
221
|
},
|
|
131
222
|
]),
|
|
223
|
+
new RemoveEmptyScriptsPlugin(),
|
|
132
224
|
new MiniCssExtractPlugin({
|
|
133
|
-
filename: "assets/
|
|
225
|
+
filename: "assets/[name].css",
|
|
226
|
+
}),
|
|
227
|
+
new SpriteLoaderPlugin({
|
|
228
|
+
plainSprite: true,
|
|
134
229
|
}),
|
|
135
230
|
new CopyPlugin({
|
|
136
231
|
patterns: [
|
|
@@ -140,15 +235,27 @@ const webpackConfig = {
|
|
|
140
235
|
],
|
|
141
236
|
optimization: {
|
|
142
237
|
minimize: !isDev,
|
|
143
|
-
minimizer: [
|
|
238
|
+
minimizer: [
|
|
239
|
+
new CssMinimizerPlugin({
|
|
240
|
+
minimizerOptions: {
|
|
241
|
+
preset: [
|
|
242
|
+
"default",
|
|
243
|
+
{
|
|
244
|
+
cssDeclarationSorter: false,
|
|
245
|
+
},
|
|
246
|
+
],
|
|
247
|
+
},
|
|
248
|
+
}),
|
|
249
|
+
new TerserPlugin({}),
|
|
250
|
+
],
|
|
144
251
|
},
|
|
145
252
|
resolve: {
|
|
146
|
-
extensions: [".js", ".jsx"],
|
|
253
|
+
extensions: [".js", ".jsx", ".ts", ".tsx"],
|
|
147
254
|
},
|
|
148
255
|
}
|
|
149
256
|
|
|
150
257
|
glob
|
|
151
|
-
.sync("**/*.js", {
|
|
258
|
+
.sync("**/*.{js,jsx,ts,tsx}", {
|
|
152
259
|
cwd: "src/pages",
|
|
153
260
|
})
|
|
154
261
|
.forEach((file) => {
|