@massimo-cassandro/minimo 1.24.10 → 1.24.12
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 +1 -1
- package/dev-tools/create-favicons/src/parse-params.mjs +3 -3
- package/dev-tools/starter-kit/starter-install.sh +67 -63
- package/dev-tools/starter-kit/templates/__project__.code-workspace +1 -1
- package/dev-tools/starter-kit/templates/app_index.js +1 -0
- package/dev-tools/starter-kit/templates/favicons-readme.md +5 -0
- package/dev-tools/starter-kit/templates/{entry-tpl.critical.css → index-critical.css} +2 -1
- package/dev-tools/starter-kit/templates/jsconfig.json +10 -8
- package/dev-tools/starter-kit/webpack.config.mjs +5 -3
- package/package.json +1 -1
- package/dev-tools/starter-kit/FIX.md +0 -2
- package/dev-tools/starter-kit/src/merge-jsonc.mjs +0 -144
- package/dev-tools/starter-kit/templates/entry-tpl.css +0 -24
- /package/dev-tools/starter-kit/{templates/package-tpl.json → package-tpl.json} +0 -0
package/README.md
CHANGED
|
@@ -25,7 +25,7 @@ To bootstrap a project **before** installing the whole package, download only th
|
|
|
25
25
|
|
|
26
26
|
```bash
|
|
27
27
|
curl -sL "$(npm view @massimo-cassandro/minimo dist.tarball)" | tar xz package/dev-tools/starter-kit
|
|
28
|
-
zsh package/dev-tools/starter-kit/starter-install.sh
|
|
28
|
+
zsh package/dev-tools/starter-kit/starter-install.sh # --no-npm
|
|
29
29
|
rm -rf package
|
|
30
30
|
```
|
|
31
31
|
|
|
@@ -56,9 +56,9 @@ export function parseParams(config_params = null, work_dir = process.cwd()) {
|
|
|
56
56
|
// da un raster non è possibile ricavare una favicon vettoriale
|
|
57
57
|
params.generate_svg_favicon = getImgExt(params.small_src_img?? params.src_img) === 'svg';
|
|
58
58
|
|
|
59
|
-
// creazione dir output se non esiste
|
|
59
|
+
// creazione dir output se non esiste (incluse le dir intermedie mancanti)
|
|
60
60
|
if (!fs.existsSync(params.output_dir)){
|
|
61
|
-
fs.mkdirSync(params.output_dir);
|
|
61
|
+
fs.mkdirSync(params.output_dir, { recursive: true });
|
|
62
62
|
}
|
|
63
63
|
|
|
64
64
|
// definizione snippet_path e creazione dir se necessario
|
|
@@ -69,7 +69,7 @@ export function parseParams(config_params = null, work_dir = process.cwd()) {
|
|
|
69
69
|
params.snippet_path = params.snippet_path?? params.output_dir;
|
|
70
70
|
|
|
71
71
|
if (!params.snippet_target_file && !fs.existsSync(params.snippet_path )){
|
|
72
|
-
fs.mkdirSync(params.snippet_path );
|
|
72
|
+
fs.mkdirSync(params.snippet_path, { recursive: true });
|
|
73
73
|
}
|
|
74
74
|
|
|
75
75
|
params.snippet_language = params.snippet_language.toLowerCase();
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
# IMPORTANTE: questo script è idempotente e deve restare tale.
|
|
4
4
|
# Può essere rilanciato più volte sullo stesso progetto (anche via `npx starter-kit`
|
|
5
5
|
# per aggiornare un setup esistente) senza sovrascrivere nulla né creare duplicati:
|
|
6
|
-
# i file esistenti vengono saltati o copiati con prefisso NEW
|
|
7
|
-
# package.json e *.code-workspace
|
|
6
|
+
# i file esistenti vengono saltati o copiati con prefisso NEW- (o _ per
|
|
7
|
+
# package.json e *.code-workspace).
|
|
8
8
|
# Ogni modifica futura deve conservare questa proprietà.
|
|
9
9
|
|
|
10
10
|
RED='\033[0;31m'
|
|
@@ -19,8 +19,8 @@ if [ -z "$ZSH_VERSION" ]; then
|
|
|
19
19
|
fi
|
|
20
20
|
|
|
21
21
|
# --no-npm: salta le installazioni npm (utile per testare rapidamente lo script)
|
|
22
|
-
# --root / --frontend: posizione della configurazione frontend (salta
|
|
23
|
-
# utile per esecuzioni non interattive)
|
|
22
|
+
# --root / --frontend / --app: posizione della configurazione frontend (salta
|
|
23
|
+
# il prompt, utile per esecuzioni non interattive)
|
|
24
24
|
SKIP_NPM=0
|
|
25
25
|
FRONTEND_CHOICE=""
|
|
26
26
|
for ARG in "$@"; do
|
|
@@ -28,6 +28,7 @@ for ARG in "$@"; do
|
|
|
28
28
|
--no-npm) SKIP_NPM=1 ;;
|
|
29
29
|
--root) FRONTEND_CHOICE=1 ;;
|
|
30
30
|
--frontend) FRONTEND_CHOICE=2 ;;
|
|
31
|
+
--app) FRONTEND_CHOICE=3 ;;
|
|
31
32
|
esac
|
|
32
33
|
done
|
|
33
34
|
|
|
@@ -64,7 +65,11 @@ BLOCKED_FILES=()
|
|
|
64
65
|
|
|
65
66
|
# Wrapper: copia solo se il file non esiste, altrimenti registra il blocco.
|
|
66
67
|
# Con terzo argomento "new", se la destinazione esiste già la copia viene
|
|
67
|
-
# comunque creata con prefisso NEW- (da integrare manualmente o rimuovere)
|
|
68
|
+
# comunque creata con prefisso NEW- (da integrare manualmente o rimuovere).
|
|
69
|
+
# Con terzo argomento "underscore", stesso comportamento ma con prefisso _
|
|
70
|
+
# (usato per package.json e *.code-workspace: il file esistente non viene
|
|
71
|
+
# toccato, il template arriva accanto con un _ davanti al nome, da integrare
|
|
72
|
+
# o rimuovere manualmente)
|
|
68
73
|
safe_cat() {
|
|
69
74
|
local src="$1"
|
|
70
75
|
local dest="$2"
|
|
@@ -74,38 +79,28 @@ safe_cat() {
|
|
|
74
79
|
return 1
|
|
75
80
|
fi
|
|
76
81
|
if [ -e "$dest" ]; then
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
82
|
+
case "$mode" in
|
|
83
|
+
new)
|
|
84
|
+
local new_dest="$(dirname "$dest")/NEW-$(basename "$dest")"
|
|
85
|
+
cat "$src" >| "$new_dest"
|
|
86
|
+
BLOCKED_FILES+=("$dest → copiato come $new_dest")
|
|
87
|
+
;;
|
|
88
|
+
underscore)
|
|
89
|
+
local new_dest="$(dirname "$dest")/_$(basename "$dest")"
|
|
90
|
+
cat "$src" >| "$new_dest"
|
|
91
|
+
BLOCKED_FILES+=("$dest → copiato come $new_dest")
|
|
92
|
+
;;
|
|
93
|
+
*)
|
|
94
|
+
BLOCKED_FILES+=("$dest")
|
|
95
|
+
;;
|
|
96
|
+
esac
|
|
84
97
|
else
|
|
85
98
|
cat "$src" > "$dest"
|
|
86
99
|
fi
|
|
87
100
|
}
|
|
88
101
|
|
|
89
102
|
echo -e "${GREEN}...package.json${NC}"
|
|
90
|
-
|
|
91
|
-
safe_cat "${TEMPLATES_DIR}/package-tpl.json" package.json
|
|
92
|
-
elif [ ! -f "${TEMPLATES_DIR}/package-tpl.json" ]; then
|
|
93
|
-
echo -e "${RED}Sorgente mancante: ${TEMPLATES_DIR}/package-tpl.json${NC}"
|
|
94
|
-
else
|
|
95
|
-
# package.json esistente: merge con il template, aggiungendo in fondo
|
|
96
|
-
# le chiavi del template prefissate con '_' (ordine originale preservato)
|
|
97
|
-
node -e '
|
|
98
|
-
const fs = require("fs");
|
|
99
|
-
const existing = JSON.parse(fs.readFileSync("package.json", "utf8"));
|
|
100
|
-
const tpl = JSON.parse(fs.readFileSync(process.argv[1], "utf8"));
|
|
101
|
-
for (const [key, value] of Object.entries(tpl)) {
|
|
102
|
-
existing["_" + key] = value;
|
|
103
|
-
}
|
|
104
|
-
fs.writeFileSync("package.json", JSON.stringify(existing, null, 2) + "\n");
|
|
105
|
-
' "${TEMPLATES_DIR}/package-tpl.json"
|
|
106
|
-
echo -e "${YELLOW}package.json esistente: chiavi del template aggiunte in fondo con prefisso '_' (da integrare o rimuovere)${NC}"
|
|
107
|
-
BLOCKED_FILES+=("package.json → merge: chiavi template aggiunte con prefisso \`_\`")
|
|
108
|
-
fi
|
|
103
|
+
safe_cat "${BASE_URL}/package-tpl.json" package.json underscore
|
|
109
104
|
|
|
110
105
|
echo -e "${GREEN}...gitignore${NC}"
|
|
111
106
|
safe_cat "${TEMPLATES_DIR}/_gitignore" .gitignore new
|
|
@@ -116,20 +111,24 @@ else
|
|
|
116
111
|
echo -e "\n${GREEN}Where do you want to install the frontend configuration?${NC}"
|
|
117
112
|
echo "1) Root directory"
|
|
118
113
|
echo "2) 'frontend' Directory"
|
|
119
|
-
|
|
120
|
-
choice
|
|
114
|
+
echo "3) 'app' Directory"
|
|
115
|
+
read "?Choose (1, 2 or 3) [default: 2]: " choice < /dev/tty
|
|
116
|
+
choice=${choice:-2}
|
|
121
117
|
fi
|
|
122
118
|
|
|
123
|
-
if [ "$choice" = "
|
|
124
|
-
FRONTEND_INSTALL_PATH="./frontend"
|
|
125
|
-
echo -e "${GREEN}Files will be installed in: ./frontend${NC}"
|
|
126
|
-
else
|
|
119
|
+
if [ "$choice" = "1" ]; then
|
|
127
120
|
FRONTEND_INSTALL_PATH="."
|
|
128
121
|
echo -e "${GREEN}Files will be installed in: root directory${NC}"
|
|
122
|
+
elif [ "$choice" = "3" ]; then
|
|
123
|
+
FRONTEND_INSTALL_PATH="./app"
|
|
124
|
+
echo -e "${GREEN}Files will be installed in: ./app${NC}"
|
|
125
|
+
else
|
|
126
|
+
FRONTEND_INSTALL_PATH="./frontend"
|
|
127
|
+
echo -e "${GREEN}Files will be installed in: ./frontend${NC}"
|
|
129
128
|
fi
|
|
130
129
|
|
|
131
|
-
if [ "$FRONTEND_INSTALL_PATH"
|
|
132
|
-
mkdir -p
|
|
130
|
+
if [ "$FRONTEND_INSTALL_PATH" != "." ]; then
|
|
131
|
+
mkdir -p "$FRONTEND_INSTALL_PATH"
|
|
133
132
|
fi
|
|
134
133
|
|
|
135
134
|
|
|
@@ -138,8 +137,8 @@ echo -e "\n${GREEN}...config files & utilities${NC}"
|
|
|
138
137
|
safe_cat "${TEMPLATES_DIR}/_browserslistrc" .browserslistrc new
|
|
139
138
|
safe_cat "${TEMPLATES_DIR}/_editorconfig" .editorconfig new
|
|
140
139
|
safe_cat "${TEMPLATES_DIR}/_prettierrc" .prettierrc new
|
|
141
|
-
safe_cat "${TEMPLATES_DIR}/_root_htaccess" _root_htaccess
|
|
142
|
-
safe_cat "${TEMPLATES_DIR}/_root_robots.txt" _root_robots.txt
|
|
140
|
+
safe_cat "${TEMPLATES_DIR}/_root_htaccess" "${FRONTEND_INSTALL_PATH}/_root_htaccess"
|
|
141
|
+
safe_cat "${TEMPLATES_DIR}/_root_robots.txt" "${FRONTEND_INSTALL_PATH}/_root_robots.txt"
|
|
143
142
|
|
|
144
143
|
# jsconfig.json: sta SEMPRE nella root del progetto (è anche il file di
|
|
145
144
|
# riferimento di vscode). I suoi path sono quindi relativi alla root: il
|
|
@@ -148,7 +147,7 @@ safe_cat "${TEMPLATES_DIR}/_root_robots.txt" _root_robots.txt
|
|
|
148
147
|
if [ "$FRONTEND_INSTALL_PATH" = "." ]; then
|
|
149
148
|
FRONTEND_REL="./"
|
|
150
149
|
else
|
|
151
|
-
FRONTEND_REL="
|
|
150
|
+
FRONTEND_REL="${FRONTEND_INSTALL_PATH}/"
|
|
152
151
|
fi
|
|
153
152
|
JSCONFIG_TPL="${TEMPLATES_DIR}/jsconfig.json"
|
|
154
153
|
if [ ! -f "$JSCONFIG_TPL" ]; then
|
|
@@ -161,23 +160,15 @@ else
|
|
|
161
160
|
fi
|
|
162
161
|
|
|
163
162
|
# code-workspace: se un file .code-workspace esiste già (qualunque sia il nome),
|
|
164
|
-
#
|
|
163
|
+
# il template viene copiato accanto con un _ davanti al nome esistente
|
|
165
164
|
WORKSPACE_TPL="${TEMPLATES_DIR}/__project__.code-workspace"
|
|
166
165
|
WORKSPACE_FILES=( *.code-workspace(N) )
|
|
167
166
|
if [ ${#WORKSPACE_FILES[@]} -gt 1 ]; then
|
|
168
|
-
echo -e "${RED}Trovati più file .code-workspace (${WORKSPACE_FILES[*]}):
|
|
167
|
+
echo -e "${RED}Trovati più file .code-workspace (${WORKSPACE_FILES[*]}): copia saltata${NC}"
|
|
169
168
|
elif [ ${#WORKSPACE_FILES[@]} -eq 0 ]; then
|
|
170
169
|
safe_cat "$WORKSPACE_TPL" __project__.code-workspace
|
|
171
|
-
elif [ ! -f "$WORKSPACE_TPL" ]; then
|
|
172
|
-
echo -e "${RED}Sorgente mancante: ${WORKSPACE_TPL}${NC}"
|
|
173
170
|
else
|
|
174
|
-
|
|
175
|
-
if node "${BASE_URL}/src/merge-jsonc.mjs" "$WORKSPACE_TPL" "$WORKSPACE_FILE"; then
|
|
176
|
-
echo -e "${YELLOW}${WORKSPACE_FILE} esistente: chiavi del template aggiunte in fondo con prefisso '_' (da integrare o rimuovere)${NC}"
|
|
177
|
-
BLOCKED_FILES+=("${WORKSPACE_FILE} → merge: chiavi template aggiunte con prefisso \`_\`")
|
|
178
|
-
else
|
|
179
|
-
echo -e "${RED}Merge di ${WORKSPACE_FILE} non riuscito${NC}"
|
|
180
|
-
fi
|
|
171
|
+
safe_cat "$WORKSPACE_TPL" "${WORKSPACE_FILES[1]}" underscore
|
|
181
172
|
fi
|
|
182
173
|
|
|
183
174
|
|
|
@@ -260,14 +251,17 @@ for CANDIDATE in "./node_modules/@massimo-cassandro/minimo" "${BASE_URL}/../..";
|
|
|
260
251
|
done
|
|
261
252
|
|
|
262
253
|
if [ -z "$MINIMO_PKG_DIR" ]; then
|
|
263
|
-
|
|
264
|
-
|
|
254
|
+
if [ "$SKIP_NPM" = "1" ]; then
|
|
255
|
+
echo -e "${YELLOW}(--no-npm) css di base, index.css, tokens-config e config favicons non copiati: npm i è stato saltato, quindi @massimo-cassandro/minimo non è ancora installato in node_modules (rilancia lo script senza --no-npm per completare la copia)${NC}"
|
|
256
|
+
BLOCKED_FILES+=("css di base + index.css + tokens-config.mjs + create-favicons-cfg.mjs → saltati (--no-npm)")
|
|
257
|
+
else
|
|
258
|
+
echo -e "${RED}Sorgenti di minimo non trovati (né in ./node_modules/@massimo-cassandro/minimo né in ${BASE_URL}/../..): css di base, index.css, tokens-config e config favicons non copiati${NC}"
|
|
259
|
+
BLOCKED_FILES+=("css di base + index.css + tokens-config.mjs + create-favicons-cfg.mjs → sorgenti minimo non trovati")
|
|
260
|
+
fi
|
|
265
261
|
else
|
|
266
262
|
echo "sorgenti minimo: ${MINIMO_PKG_DIR}"
|
|
267
263
|
|
|
268
|
-
# css di partenza del progetto: solo i file destinati a essere personalizzati
|
|
269
|
-
# minimo.css NON viene copiato: i moduli css del framework vanno importati dal
|
|
270
|
-
# pacchetto (`@import '@minimo/css/...'`, vedi entry-tpl.css)
|
|
264
|
+
# css di partenza del progetto: solo i file destinati a essere personalizzati
|
|
271
265
|
for FILE in custom-properties.css custom-media.css fonts.css; do
|
|
272
266
|
safe_cat "${MINIMO_PKG_DIR}/src/${FILE}" "${FRONTEND_INSTALL_PATH}/src/css/${FILE}"
|
|
273
267
|
done
|
|
@@ -275,18 +269,28 @@ else
|
|
|
275
269
|
# config di build-tokens: collocato accanto al css generato (custom-properties.css).
|
|
276
270
|
# NB: i percorsi relativi nel file vanno adattati alla sua posizione effettiva
|
|
277
271
|
safe_cat "${MINIMO_PKG_DIR}/design-tokens/tokens-config-sample.mjs" "${FRONTEND_INSTALL_PATH}/src/css/tokens-config.mjs"
|
|
272
|
+
|
|
273
|
+
# entry css principale del progetto: copia diretta di minimo.css, rinominato
|
|
274
|
+
# index.css e collocato sulla root di installazione (non in /src)
|
|
275
|
+
safe_cat "${MINIMO_PKG_DIR}/src/minimo.css" "${FRONTEND_INSTALL_PATH}/index.css"
|
|
276
|
+
|
|
277
|
+
# favicons: config di default per `npx create-favicons`
|
|
278
|
+
safe_cat "${MINIMO_PKG_DIR}/dev-tools/create-favicons/src/default-params.mjs" "${FRONTEND_INSTALL_PATH}/favicons/create-favicons-cfg.mjs"
|
|
278
279
|
fi
|
|
279
280
|
|
|
280
|
-
#
|
|
281
|
-
#
|
|
282
|
-
safe_cat "${TEMPLATES_DIR}/
|
|
283
|
-
safe_cat "${TEMPLATES_DIR}/
|
|
281
|
+
# entry css critical (inlinata nei template html) e entry js, sulla root di
|
|
282
|
+
# installazione accanto a index.css
|
|
283
|
+
safe_cat "${TEMPLATES_DIR}/index-critical.css" "${FRONTEND_INSTALL_PATH}/index-critical.css"
|
|
284
|
+
safe_cat "${TEMPLATES_DIR}/app_index.js" "${FRONTEND_INSTALL_PATH}/index.js"
|
|
285
|
+
|
|
286
|
+
# favicons: istruzioni d'uso di `npx create-favicons`
|
|
287
|
+
safe_cat "${TEMPLATES_DIR}/favicons-readme.md" "${FRONTEND_INSTALL_PATH}/favicons/readme.md"
|
|
284
288
|
|
|
285
289
|
set +C
|
|
286
290
|
|
|
287
291
|
# Riepilogo finale dei file già esistenti
|
|
288
292
|
if [ ${#BLOCKED_FILES[@]} -gt 0 ]; then
|
|
289
|
-
echo -e "\n${YELLOW}*** File già esistenti (non copiati o copiati con prefisso NEW
|
|
293
|
+
echo -e "\n${YELLOW}*** File già esistenti (non copiati o copiati con prefisso NEW-/_): ***${NC}"
|
|
290
294
|
for F in "${BLOCKED_FILES[@]}"; do
|
|
291
295
|
echo -e "${YELLOW} ✗ $F${NC}"
|
|
292
296
|
done
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import './index.css';
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/*
|
|
2
|
-
|
|
2
|
+
Entry css critical di default (index-critical.css) — adattare al progetto.
|
|
3
|
+
Per ulteriori entry critical specifiche di pagina, copiare e rinominare.
|
|
3
4
|
|
|
4
5
|
Le entry con suffisso `.critical` generano asset destinati a essere
|
|
5
6
|
INLINATI nei template html: devono restare AUTOSUFFICIENTI e minimi.
|
|
@@ -9,14 +9,16 @@
|
|
|
9
9
|
"target": "es2023",
|
|
10
10
|
"module": "ES6",
|
|
11
11
|
"paths": {
|
|
12
|
-
"@css/*": ["
|
|
13
|
-
"@src/*": ["
|
|
14
|
-
"@icons/*": ["
|
|
15
|
-
"@imgs/*": ["
|
|
16
|
-
|
|
17
|
-
"@
|
|
18
|
-
|
|
12
|
+
"@css/*": ["app/css/*"],
|
|
13
|
+
"@src/*": ["app/src/*"],
|
|
14
|
+
"@icons/*": ["app/icons/*"],
|
|
15
|
+
"@imgs/*": ["app/imgs/*"],
|
|
16
|
+
|
|
17
|
+
"@frontend/*": ["fromtend/*"],
|
|
18
|
+
|
|
19
|
+
"@minimo/*": ["./node_modules/@massimo-cassandro/minimo/src/*"],
|
|
20
|
+
"@minimoCharts/*": ["./node_modules/@massimo-cassandro/minimo/charts/*"]
|
|
19
21
|
}
|
|
20
22
|
},
|
|
21
|
-
"exclude": ["
|
|
23
|
+
"exclude": ["node_modules", "dist", "docs", "build", "public"]
|
|
22
24
|
}
|
|
@@ -150,12 +150,12 @@ const CopyWebpackPluginPatterns = [
|
|
|
150
150
|
// =>> entries
|
|
151
151
|
// NB: percorsi dalla root del progetto
|
|
152
152
|
const entries = {
|
|
153
|
-
'xxxxxx': './
|
|
153
|
+
'xxxxxx': './index.js'
|
|
154
154
|
|
|
155
155
|
// css critici inlinati nei template html: il suffisso `.critical` nel nome
|
|
156
156
|
// della entry attiva l'istanza PurgeCSS dedicata con purge stretto
|
|
157
157
|
// (vedi purgecss-setup.mjs) e la regola dedicata in css-rules.mjs
|
|
158
|
-
// ,'xxxxxx.critical': './
|
|
158
|
+
// ,'xxxxxx.critical': './index-critical.css'
|
|
159
159
|
};
|
|
160
160
|
|
|
161
161
|
|
|
@@ -364,7 +364,6 @@ const config = {
|
|
|
364
364
|
]
|
|
365
365
|
),
|
|
366
366
|
|
|
367
|
-
// TODO author dinamico https://docs.npmjs.com/cli/v11/configuring-npm/package-json#people-fields-author-contributors
|
|
368
367
|
// =>> plugins: BannerPlugin
|
|
369
368
|
new webpack.BannerPlugin({
|
|
370
369
|
banner: () => {
|
|
@@ -411,6 +410,7 @@ const config = {
|
|
|
411
410
|
// webpack.config.mjs NON è in una sottodirectory)
|
|
412
411
|
// path.resolve(__dirname, '../templates/**/*.twig'),
|
|
413
412
|
// path.resolve(__dirname, '../src/**/*.php'),
|
|
413
|
+
path.resolve(__dirname, './index.js'), // entry js di default (vedi starter-install.sh)
|
|
414
414
|
path.resolve(__dirname, './src/**/*.{js,mjs,jsx}'),
|
|
415
415
|
path.resolve(__dirname, './src/**/*.ejs'), // template html di webpack
|
|
416
416
|
path.resolve(__dirname, './error-pages/**/*.js'),
|
|
@@ -450,6 +450,8 @@ const config = {
|
|
|
450
450
|
// delle dipendenze (vedi webpack-modules/purgecss-variables-safelist.mjs)
|
|
451
451
|
variablesSafelist: {
|
|
452
452
|
declarationGlobs: [
|
|
453
|
+
path.resolve(__dirname, './index.css'), // entry css di default (vedi starter-install.sh)
|
|
454
|
+
path.resolve(__dirname, './index-critical.css'),
|
|
453
455
|
path.resolve(__dirname, './src/**/*.css'),
|
|
454
456
|
path.resolve(__dirname, './error-pages/**/*.css'),
|
|
455
457
|
`${minimo_path}/src/**/*.css`,
|
package/package.json
CHANGED
|
@@ -1,144 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
// Merge JSONC: aggiunge in fondo al file di destinazione le chiavi di primo
|
|
3
|
-
// livello del template, prefissate con '_', preservando commenti e
|
|
4
|
-
// formattazione di entrambi i file.
|
|
5
|
-
// Uso: node merge-jsonc.mjs <template> <destinazione>
|
|
6
|
-
|
|
7
|
-
import fs from 'fs';
|
|
8
|
-
|
|
9
|
-
// Analizza un testo JSONC ignorando stringhe e commenti: individua
|
|
10
|
-
// l'oggetto principale, le virgole a profondità 1 e la posizione
|
|
11
|
-
// dell'ultimo carattere significativo (non spazio, non commento)
|
|
12
|
-
function scan(text) {
|
|
13
|
-
let depth = 0;
|
|
14
|
-
let open = -1;
|
|
15
|
-
let close = -1;
|
|
16
|
-
let last = -1;
|
|
17
|
-
const commas = [];
|
|
18
|
-
let i = 0;
|
|
19
|
-
while (i < text.length) {
|
|
20
|
-
const c = text[i];
|
|
21
|
-
const next = text[i + 1];
|
|
22
|
-
if (c === '"') {
|
|
23
|
-
i++;
|
|
24
|
-
while (i < text.length && text[i] !== '"') {
|
|
25
|
-
if (text[i] === '\\') i++;
|
|
26
|
-
i++;
|
|
27
|
-
}
|
|
28
|
-
last = i;
|
|
29
|
-
} else if (c === '/' && next === '/') {
|
|
30
|
-
while (i < text.length && text[i] !== '\n') i++;
|
|
31
|
-
continue;
|
|
32
|
-
} else if (c === '/' && next === '*') {
|
|
33
|
-
i += 2;
|
|
34
|
-
while (i < text.length && !(text[i] === '*' && text[i + 1] === '/')) i++;
|
|
35
|
-
i++;
|
|
36
|
-
} else {
|
|
37
|
-
if (c === '{' || c === '[') {
|
|
38
|
-
if (depth === 0 && open === -1 && c === '{') open = i;
|
|
39
|
-
depth++;
|
|
40
|
-
} else if (c === '}' || c === ']') {
|
|
41
|
-
depth--;
|
|
42
|
-
if (depth === 0 && close === -1) close = i;
|
|
43
|
-
} else if (c === ',' && depth === 1) {
|
|
44
|
-
commas.push(i);
|
|
45
|
-
}
|
|
46
|
-
if (!/\s/.test(c)) last = i;
|
|
47
|
-
}
|
|
48
|
-
i++;
|
|
49
|
-
}
|
|
50
|
-
return { open, close, commas, last };
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
// Posizione della prima doppia virgoletta fuori dai commenti
|
|
54
|
-
function firstQuotePos(text) {
|
|
55
|
-
let i = 0;
|
|
56
|
-
while (i < text.length) {
|
|
57
|
-
const c = text[i];
|
|
58
|
-
const next = text[i + 1];
|
|
59
|
-
if (c === '/' && next === '/') {
|
|
60
|
-
while (i < text.length && text[i] !== '\n') i++;
|
|
61
|
-
} else if (c === '/' && next === '*') {
|
|
62
|
-
i += 2;
|
|
63
|
-
while (i < text.length && !(text[i] === '*' && text[i + 1] === '/')) i++;
|
|
64
|
-
i += 2;
|
|
65
|
-
} else if (c === '"') {
|
|
66
|
-
return i;
|
|
67
|
-
} else {
|
|
68
|
-
i++;
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
return -1;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
// Voci di primo livello di un oggetto JSONC (spezzate sulle virgole a profondità 1)
|
|
75
|
-
function topLevelEntries(text, s) {
|
|
76
|
-
const body = text.slice(s.open + 1, s.close);
|
|
77
|
-
const offset = s.open + 1;
|
|
78
|
-
const bounds = s.commas.map((p) => p - offset).concat(body.length);
|
|
79
|
-
const entries = [];
|
|
80
|
-
let prev = 0;
|
|
81
|
-
for (const b of bounds) {
|
|
82
|
-
entries.push(body.slice(prev, b));
|
|
83
|
-
prev = b + 1;
|
|
84
|
-
}
|
|
85
|
-
return entries;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
// Nome della chiave di una voce (contenuto della prima stringa fuori dai commenti)
|
|
89
|
-
function keyName(entry) {
|
|
90
|
-
const q = firstQuotePos(entry);
|
|
91
|
-
if (q < 0) return null;
|
|
92
|
-
let key = '';
|
|
93
|
-
let i = q + 1;
|
|
94
|
-
while (i < entry.length && entry[i] !== '"') {
|
|
95
|
-
if (entry[i] === '\\') i++;
|
|
96
|
-
key += entry[i];
|
|
97
|
-
i++;
|
|
98
|
-
}
|
|
99
|
-
return key;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
const [tplPath, destPath] = process.argv.slice(2);
|
|
103
|
-
|
|
104
|
-
try {
|
|
105
|
-
const tpl = fs.readFileSync(tplPath, 'utf8');
|
|
106
|
-
const dest = fs.readFileSync(destPath, 'utf8');
|
|
107
|
-
const t = scan(tpl);
|
|
108
|
-
const d = scan(dest);
|
|
109
|
-
if (t.open < 0 || t.close < 0) throw new Error(tplPath + ': oggetto JSON non trovato');
|
|
110
|
-
if (d.open < 0 || d.close < 0) throw new Error(destPath + ': oggetto JSON non trovato');
|
|
111
|
-
|
|
112
|
-
// chiavi di primo livello già presenti nella destinazione
|
|
113
|
-
const destKeys = new Set(
|
|
114
|
-
topLevelEntries(dest, d).map((entry) => keyName(entry)).filter((k) => k !== null)
|
|
115
|
-
);
|
|
116
|
-
|
|
117
|
-
// prefissa con '_' la chiave di ogni voce del template, saltando le voci di
|
|
118
|
-
// soli commenti/spazi e le chiavi già presenti nella destinazione
|
|
119
|
-
// (così rilanciare lo script non produce duplicati)
|
|
120
|
-
const renamed = [];
|
|
121
|
-
for (const entry of topLevelEntries(tpl, t)) {
|
|
122
|
-
const cleaned = entry.replace(/^\s+/, '').replace(/\s+$/, '');
|
|
123
|
-
const key = keyName(cleaned);
|
|
124
|
-
if (key === null || destKeys.has('_' + key)) continue;
|
|
125
|
-
const q = firstQuotePos(cleaned);
|
|
126
|
-
renamed.push('\n ' + cleaned.slice(0, q + 1) + '_' + cleaned.slice(q + 1));
|
|
127
|
-
}
|
|
128
|
-
if (renamed.length === 0) process.exit(0);
|
|
129
|
-
|
|
130
|
-
// aggiunge le voci prima della chiusura dell'oggetto principale della
|
|
131
|
-
// destinazione, inserendo una virgola dopo l'ultima voce esistente se serve
|
|
132
|
-
const dBody = dest.slice(d.open + 1, d.close);
|
|
133
|
-
const b = scan(dBody);
|
|
134
|
-
const needsComma = b.last >= 0 && dBody[b.last] !== ',';
|
|
135
|
-
const insertAt = d.open + 1 + b.last + 1;
|
|
136
|
-
const out = needsComma
|
|
137
|
-
? dest.slice(0, insertAt) + ',' + dest.slice(insertAt, d.close) + renamed.join(',') + '\n' + dest.slice(d.close)
|
|
138
|
-
: dest.slice(0, d.close) + renamed.join(',') + '\n' + dest.slice(d.close);
|
|
139
|
-
|
|
140
|
-
fs.writeFileSync(destPath, out);
|
|
141
|
-
} catch (err) {
|
|
142
|
-
console.error('merge-jsonc: ' + err.message);
|
|
143
|
-
process.exit(1);
|
|
144
|
-
}
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
Template di entry css (globale o di pagina) — rinominare e adattare.
|
|
3
|
-
|
|
4
|
-
NB: OGNI entry css (globale, di pagina, `.critical`) deve importare
|
|
5
|
-
direttamente custom-properties.css: PurgeCSS elabora gli asset css
|
|
6
|
-
SINGOLARMENTE e mantiene in ciascuno solo le custom properties
|
|
7
|
-
effettivamente usate nell'asset stesso (`variables: true`, che
|
|
8
|
-
sostituisce postcss-jit-props). L'import diretto non produce quindi
|
|
9
|
-
duplicazioni nel css finale.
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
@import '@css/custom-properties.css';
|
|
13
|
-
/* @import '@css/fonts.css'; */
|
|
14
|
-
|
|
15
|
-
/* @import '@css/custom-media.css'; */ /* NON necessario: iniettato da postcss-global-data */
|
|
16
|
-
|
|
17
|
-
/* moduli minimo: importare solo quelli effettivamente usati */
|
|
18
|
-
/* @import '@minimo/css/reset.css'; */
|
|
19
|
-
/* @import '@minimo/css/layout-base.css'; */
|
|
20
|
-
/* @import '@minimo/css/container.css'; */
|
|
21
|
-
/* @import '@minimo/css/forms/forms.css'; */
|
|
22
|
-
/* @import '@minimo/css/buttons/buttons.css'; */
|
|
23
|
-
/* @import '@minimo/css/alerts.css'; */
|
|
24
|
-
/* ... */
|
|
File without changes
|