@massimo-cassandro/minimo 1.16.0 → 1.16.2
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 +12 -3
- package/design-tokens/_src/typography.minimo.tokens.mjs +1 -1
- package/dev-tools/README.md +11 -7
- package/dev-tools/starter-kit/TODO.md +135 -0
- package/dev-tools/{webpack-setup/merge-jsonc.cjs → starter-kit/src/merge-jsonc.mjs} +40 -15
- package/dev-tools/{webpack-setup → starter-kit}/starter-install.sh +22 -3
- package/dev-tools/starter-kit/templates/_root_htaccess +68 -0
- package/dev-tools/starter-kit/templates/_root_robots.txt +5 -0
- package/dev-tools/starter-kit/templates/entry-tpl.critical.css +18 -0
- package/dev-tools/starter-kit/templates/entry-tpl.css +24 -0
- package/dev-tools/starter-kit/templates/tokens-config.mjs +33 -0
- package/dev-tools/{webpack-setup → starter-kit}/webpack-modules/css-rules.mjs +6 -1
- package/dev-tools/{webpack-setup → starter-kit}/webpack-modules/postcss.config.mjs +14 -34
- package/dev-tools/starter-kit/webpack-modules/purgecss-variables-safelist.mjs +92 -0
- package/dev-tools/{webpack-setup → starter-kit}/webpack.config.mjs +169 -59
- package/package.json +4 -2
- package/src/css/dimensions.css +3 -0
- package/src/css/margin-padding-bootstrap-media.css +1844 -0
- package/src/css/margin-padding-bootstrap.css +464 -0
- package/src/css/margin-padding-media.css +1843 -0
- package/src/css/margin-padding.css +405 -45
- package/src/custom-media.css +12 -0
- package/src/minimo.css +5 -0
- /package/dev-tools/{webpack-setup → starter-kit}/templates/__project__.code-workspace +0 -0
- /package/dev-tools/{webpack-setup → starter-kit}/templates/_browserslistrc +0 -0
- /package/dev-tools/{webpack-setup → starter-kit}/templates/_editorconfig +0 -0
- /package/dev-tools/{webpack-setup → starter-kit}/templates/_gitignore +0 -0
- /package/dev-tools/{webpack-setup → starter-kit}/templates/_prettierrc +0 -0
- /package/dev-tools/{webpack-setup → starter-kit}/templates/eslint.config.mjs +0 -0
- /package/dev-tools/{webpack-setup → starter-kit}/templates/jsconfig.json +0 -0
- /package/dev-tools/{webpack-setup → starter-kit}/templates/package-tpl.json +0 -0
- /package/dev-tools/{webpack-setup → starter-kit}/templates/stylelint.config.mjs +0 -0
- /package/dev-tools/{webpack-setup → starter-kit}/webpack-modules/get-jsConfig-aliases.mjs +0 -0
- /package/dev-tools/{webpack-setup → starter-kit}/webpack-modules/mini-svg-data-uri-loader.cjs +0 -0
- /package/dev-tools/{webpack-setup → starter-kit}/webpack-modules/svg-rules.mjs +0 -0
- /package/dev-tools/{webpack-setup → starter-kit}/webpack-modules/svgo.config.mjs +0 -0
- /package/dev-tools/{webpack-setup → starter-kit}/webpack-template.ejs +0 -0
package/README.md
CHANGED
|
@@ -12,14 +12,23 @@ npm i -D @massimo-cassandro/eslint-config
|
|
|
12
12
|
npm i -D @massimo-cassandro/stylelint-config
|
|
13
13
|
```
|
|
14
14
|
|
|
15
|
-
> Note: **minimo** is designed to be used with WebPack using the configuration you can find in the [
|
|
15
|
+
> Note: **minimo** is designed to be used with WebPack using the configuration you can find in the [starter-kit folder](./dev-tools/starter-kit/) of this repository. If changes are made (for example, to how SVG files are imported), things may not work as expected.
|
|
16
16
|
>
|
|
17
17
|
|
|
18
|
-
For a complete install of all required webpack modules, use the install script at `./
|
|
18
|
+
For a complete install of all required webpack modules, use the install script at `./dev-tools/starter-kit/starter-install.sh` launching:
|
|
19
19
|
|
|
20
20
|
```bash
|
|
21
|
-
zsh ./node_modules/@massimo-cassandro/minimo/
|
|
21
|
+
zsh ./node_modules/@massimo-cassandro/minimo/dev-tools/starter-kit/starter-install.sh
|
|
22
22
|
```
|
|
23
|
+
|
|
24
|
+
To bootstrap a project **before** installing the whole package, download only the `starter-kit` folder from the npm tarball and run the script from there:
|
|
25
|
+
|
|
26
|
+
```bash
|
|
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
|
|
29
|
+
rm -rf package
|
|
30
|
+
```
|
|
31
|
+
|
|
23
32
|
---
|
|
24
33
|
|
|
25
34
|
## Dev Tools
|
|
@@ -5,7 +5,7 @@ export default {
|
|
|
5
5
|
$type: 'fontFamily'
|
|
6
6
|
},
|
|
7
7
|
'family-mono': {
|
|
8
|
-
$value:
|
|
8
|
+
$value: '\'Monaspace Neon Var\', \'Monaspace Neon\', \'Aptos Mono\', \'Roboto Mono\', \'SFMono-Regular\', \'Menlo\', \'Monaco\', \'Consolas\', \'Liberation Mono\', \'Andale Mono\', \'Courier New\', monospace',
|
|
9
9
|
$type: 'fontFamily'
|
|
10
10
|
},
|
|
11
11
|
|
package/dev-tools/README.md
CHANGED
|
@@ -6,27 +6,31 @@ A collection of standalone Node.js CLI utilities to help manage a web project's
|
|
|
6
6
|
* [Svg Icons Tools](./svg-icons-tools/README.md) — optimizes SVG icons and combines/converts them into symbols, JSX, or SCSS variables
|
|
7
7
|
* [Create favicons](./create-favicons/README.md) — generates the full favicon set (SVG, PNG, ICO, webmanifest, HTML snippet) from a source image
|
|
8
8
|
* [upd@m](./upd@m/README.md) — updates all `@massimo-cassandro/*` packages installed in `node_modules`
|
|
9
|
-
* [
|
|
9
|
+
* [starter-kit](#starter-kit) — script for installing minimo environment
|
|
10
10
|
|
|
11
|
-
##
|
|
11
|
+
## starter-kit
|
|
12
12
|
|
|
13
|
-
`
|
|
13
|
+
`starter-kit/starter-install.sh` bootstraps a new frontend project: it copies the starter config files (`package.json`, `.gitignore`, `jsconfig.json`, eslint/stylelint configs, webpack config and modules, ...) and installs all the required dev dependencies.
|
|
14
14
|
|
|
15
15
|
The script **requires zsh** (it exits with an error if launched with `sh` or `bash`). Existing files are never overwritten: root config files are copied with a `NEW-` prefix, while `package.json` and the `*.code-workspace` file are merged (template keys are appended at the end, prefixed with `_`).
|
|
16
16
|
|
|
17
17
|
### If minimo is already installed
|
|
18
18
|
|
|
19
|
+
The script is exposed as a `bin` of the package:
|
|
20
|
+
|
|
19
21
|
```bash
|
|
20
|
-
|
|
22
|
+
npx starter-kit
|
|
21
23
|
```
|
|
22
24
|
|
|
25
|
+
Since the installation is fully overwrite-safe, the script can also be **re-run at any time to update** an existing setup (e.g. to refresh the webpack modules or reinstall the dev dependencies): existing files are skipped or copied with the `NEW-` prefix, and the `package.json` / `*.code-workspace` merges are idempotent (running the script again neither duplicates nor overwrites anything).
|
|
26
|
+
|
|
23
27
|
### Without installing minimo
|
|
24
28
|
|
|
25
|
-
To bootstrap a project **before**
|
|
29
|
+
To bootstrap a project **before** installing the whole package, download only the `starter-kit` folder from the npm tarball and run the script from there:
|
|
26
30
|
|
|
27
31
|
```bash
|
|
28
|
-
curl -sL "$(npm view @massimo-cassandro/minimo dist.tarball)" | tar xz package/dev-tools/
|
|
29
|
-
zsh package/dev-tools/
|
|
32
|
+
curl -sL "$(npm view @massimo-cassandro/minimo dist.tarball)" | tar xz package/dev-tools/starter-kit
|
|
33
|
+
zsh package/dev-tools/starter-kit/starter-install.sh
|
|
30
34
|
rm -rf package
|
|
31
35
|
```
|
|
32
36
|
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
# TODO — Starter kit: config come punto di regia, moduli autonomi
|
|
2
|
+
|
|
3
|
+
## Obiettivo
|
|
4
|
+
|
|
5
|
+
`webpack.config.mjs` deve diventare **solo** un punto di impostazione di scelte e
|
|
6
|
+
parametri (in piccolo già lo è: `useSass`, `useSvgo`, `purgeCSSDebug`, ecc.).
|
|
7
|
+
Tutta la logica deve migrare nei moduli di `webpack-modules/`, che devono diventare
|
|
8
|
+
**completamente autonomi e indipendenti dalle impostazioni e dal layout del progetto**:
|
|
9
|
+
in questo modo potranno essere aggiornati/sovrascritti in qualsiasi progetto senza
|
|
10
|
+
danni, perché il timone resta sempre nel config del progetto.
|
|
11
|
+
|
|
12
|
+
## Contratto dei moduli (da rispettare in ogni intervento)
|
|
13
|
+
|
|
14
|
+
1. **Nessun percorso di progetto hardcodato** nei moduli: tutti i path (sorgenti,
|
|
15
|
+
node_modules, template, ecc.) arrivano come parametri dal config.
|
|
16
|
+
2. Ogni modulo esporta **factory pure** (funzioni che ricevono opzioni e
|
|
17
|
+
restituiscono rules/plugin/config): nessun side effect a import time.
|
|
18
|
+
3. Ogni parametro ha un **default sensato** e JSDoc: il modulo deve funzionare
|
|
19
|
+
anche senza opzioni, e un'opzione nuova non deve mai rompere un config vecchio.
|
|
20
|
+
4. **Niente dipendenze implicite tra moduli**: se un modulo ha bisogno di un altro
|
|
21
|
+
(es. css-rules → postcss config), il collegamento avviene via parametro passato
|
|
22
|
+
dal config, non con import/path interni.
|
|
23
|
+
5. Aggiornare un modulo non deve mai richiedere modifiche al config esistente,
|
|
24
|
+
se non per adottare volontariamente opzioni nuove.
|
|
25
|
+
6. **Import opzionali = import dinamici**: i pacchetti usati solo quando una
|
|
26
|
+
scelta li attiva (es. sass-loader con `useSass`, responsive-loader, svgo)
|
|
27
|
+
non vanno importati staticamente: con la nuova struttura ogni import
|
|
28
|
+
condizionato da un flag va fatto con `await import(...)` dentro la factory
|
|
29
|
+
(come già avviene per `svgo.config.mjs` nel config), così un pacchetto non
|
|
30
|
+
installato non rompe il caricamento del config/modulo se la relativa
|
|
31
|
+
funzionalità è disattivata.
|
|
32
|
+
|
|
33
|
+
## Stato attuale (inventario del coupling)
|
|
34
|
+
|
|
35
|
+
| Modulo | Stato | Problemi |
|
|
36
|
+
|---|---|---|
|
|
37
|
+
| `get-jsConfig-aliases.mjs` | ✅ autonomo | riceve il path del jsconfig dal config |
|
|
38
|
+
| `purgecss-variables-safelist.mjs` | ✅ autonomo | tutti i glob/seeds arrivano dal config |
|
|
39
|
+
| `svgo.config.mjs` | ✅ autonomo | nessun riferimento al progetto |
|
|
40
|
+
| `mini-svg-data-uri-loader.cjs` | ✅ autonomo | loader puro |
|
|
41
|
+
| `svg-rules.mjs` | ⚠️ quasi | parametrico, ma da riverificare rispetto al contratto (default, JSDoc) |
|
|
42
|
+
| `css-rules.mjs` | ⚠️ quasi | parametrico, ma riceve `postcssConfig_path` (file di config esterno invece di opzioni); scelte come `localIdentName` non sovrascrivibili dal config |
|
|
43
|
+
| `postcss.config.mjs` | ❌ accoppiato | **hardcoda** `../src/css/custom-media.css` (layout del progetto): non aggiornabile senza danni |
|
|
44
|
+
| `webpack.config.mjs` | ❌ contiene logica | blocchi che sono logica, non scelte: sezione PurgeCSS (opzioni comuni + 2 istanze + log debug), test del cacheGroup `shared`, rules asset (js/ejs/html/img/font/video/favicon), BannerPlugin |
|
|
45
|
+
|
|
46
|
+
## Piano d'azione
|
|
47
|
+
|
|
48
|
+
### 1. Oggetto `settings` unico nel config
|
|
49
|
+
Raggruppare in testa al config un unico oggetto di scelte e percorsi
|
|
50
|
+
(flag attuali + tutti i path oggi sparsi: sorgenti js/css, template twig/php,
|
|
51
|
+
node_modules di minimo, glob shadow-DOM, seeds, favicons, output...).
|
|
52
|
+
Le factory dei moduli ricevono ciò che serve da qui. Il config diventa:
|
|
53
|
+
`settings` → chiamate alle factory → oggetto `config`.
|
|
54
|
+
|
|
55
|
+
### 2. `postcss.config.mjs` → factory senza path hardcodati
|
|
56
|
+
- Trasformarlo in una factory (es. `postcssPlugins({ globalDataFiles, preserveCustomMedia })`)
|
|
57
|
+
che riceve i file per `postcss-global-data` dal config.
|
|
58
|
+
- `css-rules.mjs` non riceve più `postcssConfig_path` (file caricato da
|
|
59
|
+
postcss-loader) ma direttamente l'oggetto `postcssOptions` (o la factory + le sue
|
|
60
|
+
opzioni) costruito nel config: sparisce l'ultimo path relativo al layout progetto.
|
|
61
|
+
- Attenzione a preservare il comportamento attuale di `loaderContext.mode`.
|
|
62
|
+
- **DA CONTROLLARE E VALUTARE — eliminazione del file postcss config**: verificare
|
|
63
|
+
la possibilità di eliminare del tutto il file di config postcss e sostituirlo
|
|
64
|
+
con regole definite direttamente nel webpack config (plugin postcss dichiarati
|
|
65
|
+
inline in `postcssOptions`). Considerare però che in certi casi postcss
|
|
66
|
+
necessita di impostazioni ad hoc per progetto (è il motivo per cui oggi esiste
|
|
67
|
+
il parametro `postcssConfig_path`): in quel caso la strada è mantenere la
|
|
68
|
+
possibilità di override — es. default inline nel config + parametro opzionale
|
|
69
|
+
per un file/oggetto di impostazioni custom. Tenere conto anche degli altri
|
|
70
|
+
consumatori del file: un postcss config a livello di progetto può servire ad
|
|
71
|
+
altri tool (stylelint, editor/IDE, CLI postcss) oltre che a postcss-loader.
|
|
72
|
+
|
|
73
|
+
### 3. Sezione PurgeCSS → `webpack-modules/purgecss-plugins.mjs`
|
|
74
|
+
Factory (es. `purgecssPlugins({ contentGlobs, safelist, variablesSafelistOptions, debug })`)
|
|
75
|
+
che incapsula: opzioni comuni, safelist base (deep `m_`, greedy `&`), le due istanze
|
|
76
|
+
(critical + generale) e il mini-plugin di log `purgedStats`.
|
|
77
|
+
Restituisce l'array di plugin pronto per lo spread nel config.
|
|
78
|
+
Nel config restano SOLO: i glob dei contenuti, le safelist specifiche del progetto
|
|
79
|
+
(standard/seeds), il flag `purgeCSSDebug`. I commenti "strutturali" (problemi a/b/c)
|
|
80
|
+
migrano nel modulo; nel config restano i commenti sulle scelte.
|
|
81
|
+
|
|
82
|
+
### 4. Rules asset generiche → `webpack-modules/asset-rules.mjs`
|
|
83
|
+
Estrarre js/babel, ejs, html, immagini/pdf, font, video, favicons in una factory
|
|
84
|
+
parametrica con on/off per gruppo (es. `assetRules({ favicons_path_regexp, useVideo, ... })`).
|
|
85
|
+
Le parti oggi commentate nel config (responsive-loader, video) diventano opzioni
|
|
86
|
+
documentate del modulo.
|
|
87
|
+
|
|
88
|
+
### 5. splitChunks
|
|
89
|
+
Valutare una piccola factory (es. `sharedCacheGroup({ pathsRegexp })`) che incapsuli
|
|
90
|
+
l'esclusione dei moduli css (`module.type !== 'css/mini-extract'`, requisito PurgeCSS)
|
|
91
|
+
lasciando nel config solo l'elenco dei path. In alternativa lasciarla nel config ma
|
|
92
|
+
con l'esclusione css delegata a una helper del modulo purgecss (è un suo requisito).
|
|
93
|
+
|
|
94
|
+
### 6. `starter-install.sh`
|
|
95
|
+
- Aggiornare l'array `FILES` con i nuovi moduli.
|
|
96
|
+
- Distinguere due categorie nel flusso di copia:
|
|
97
|
+
- `webpack-modules/` = aggiornabili sempre (una volta autonomi, la copia
|
|
98
|
+
NEW- può diventare sovrascrittura diretta o diff);
|
|
99
|
+
- `webpack.config.mjs` e template = mai sovrascritti (proprietà del progetto).
|
|
100
|
+
- **Audit delle dipendenze installate**: verificare la corrispondenza tra i
|
|
101
|
+
pacchetti degli `npm i -D` dello script e quelli effettivamente usati da
|
|
102
|
+
config, moduli e template, per evitare installazioni inutili. Da controllare
|
|
103
|
+
in entrambe le direzioni:
|
|
104
|
+
- installati ma (forse) mai usati: es. `postcss-preset-env` (assente dal
|
|
105
|
+
postcss config), `responsive-loader` (solo in blocchi commentati),
|
|
106
|
+
`style-dictionary` (riguarda i design token, non la build webpack);
|
|
107
|
+
- usati ma non installati: es. `file-loader` (referenziato dalla rule video
|
|
108
|
+
del config) e `sass-loader`/`sass` (necessari con `useSass: true`).
|
|
109
|
+
- i pacchetti legati a funzionalità opzionali (sass, responsive-loader,
|
|
110
|
+
video, svgr...) escono dall'installazione di default: o vengono installati
|
|
111
|
+
su richiesta dallo script (prompt/flag) o documentati come "da installare
|
|
112
|
+
quando si attiva l'opzione X" — coerentemente con la regola degli import
|
|
113
|
+
dinamici del contratto (punto 6).
|
|
114
|
+
|
|
115
|
+
### 7. Versionamento dei moduli
|
|
116
|
+
Aggiungere in testa a ogni modulo un commento con versione (o data) per capire a
|
|
117
|
+
colpo d'occhio, nei progetti, quale revisione è installata.
|
|
118
|
+
|
|
119
|
+
### 8. Documentazione
|
|
120
|
+
README dello starter kit con la mappa: cosa si imposta nel config (e solo lì),
|
|
121
|
+
cosa fa ogni modulo, come aggiornare i moduli in un progetto esistente.
|
|
122
|
+
|
|
123
|
+
## Ordine consigliato
|
|
124
|
+
|
|
125
|
+
2 → 3 → 4 → 5 (refactor moduli, uno per volta, build demo di verifica dopo ognuno)
|
|
126
|
+
→ 1 (consolidamento `settings`) → 6 → 7 → 8.
|
|
127
|
+
|
|
128
|
+
## Note
|
|
129
|
+
|
|
130
|
+
- `merge-jsonc` è già stato spostato in `src/merge-jsonc.mjs` (convertito in ESM):
|
|
131
|
+
la dir `src/` ospita le utility interne dell'installer, NON copiate nei progetti;
|
|
132
|
+
`webpack-modules/` resta la dir dei moduli copiati nei progetti.
|
|
133
|
+
- Criterio di "fatto": si deve poter copiare l'intera `webpack-modules/` aggiornata
|
|
134
|
+
in un progetto esistente senza toccare il suo `webpack.config.mjs` e ottenere
|
|
135
|
+
una build identica (o migliorata) senza errori.
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
// Merge JSONC: aggiunge in fondo al file di destinazione le chiavi di primo
|
|
3
3
|
// livello del template, prefissate con '_', preservando commenti e
|
|
4
4
|
// formattazione di entrambi i file.
|
|
5
|
-
// Uso: node merge-jsonc.
|
|
5
|
+
// Uso: node merge-jsonc.mjs <template> <destinazione>
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
import fs from 'fs';
|
|
8
8
|
|
|
9
9
|
// Analizza un testo JSONC ignorando stringhe e commenti: individua
|
|
10
10
|
// l'oggetto principale, le virgole a profondità 1 e la posizione
|
|
@@ -71,6 +71,34 @@ function firstQuotePos(text) {
|
|
|
71
71
|
return -1;
|
|
72
72
|
}
|
|
73
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
|
+
|
|
74
102
|
const [tplPath, destPath] = process.argv.slice(2);
|
|
75
103
|
|
|
76
104
|
try {
|
|
@@ -81,23 +109,20 @@ try {
|
|
|
81
109
|
if (t.open < 0 || t.close < 0) throw new Error(tplPath + ': oggetto JSON non trovato');
|
|
82
110
|
if (d.open < 0 || d.close < 0) throw new Error(destPath + ': oggetto JSON non trovato');
|
|
83
111
|
|
|
84
|
-
//
|
|
85
|
-
const
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
const entries = [];
|
|
89
|
-
let prev = 0;
|
|
90
|
-
for (const b of bounds) {
|
|
91
|
-
entries.push(body.slice(prev, b));
|
|
92
|
-
prev = b + 1;
|
|
93
|
-
}
|
|
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
|
+
);
|
|
94
116
|
|
|
95
|
-
// prefissa con '_' la chiave di ogni voce
|
|
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)
|
|
96
120
|
const renamed = [];
|
|
97
|
-
for (const entry of
|
|
121
|
+
for (const entry of topLevelEntries(tpl, t)) {
|
|
98
122
|
const cleaned = entry.replace(/^\s+/, '').replace(/\s+$/, '');
|
|
123
|
+
const key = keyName(cleaned);
|
|
124
|
+
if (key === null || destKeys.has('_' + key)) continue;
|
|
99
125
|
const q = firstQuotePos(cleaned);
|
|
100
|
-
if (q < 0) continue;
|
|
101
126
|
renamed.push('\n ' + cleaned.slice(0, q + 1) + '_' + cleaned.slice(q + 1));
|
|
102
127
|
}
|
|
103
128
|
if (renamed.length === 0) process.exit(0);
|
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
#!/bin/zsh
|
|
2
2
|
|
|
3
|
+
# IMPORTANTE: questo script è idempotente e deve restare tale.
|
|
4
|
+
# Può essere rilanciato più volte sullo stesso progetto (anche via `npx starter-kit`
|
|
5
|
+
# per aggiornare un setup esistente) senza sovrascrivere nulla né creare duplicati:
|
|
6
|
+
# i file esistenti vengono saltati o copiati con prefisso NEW-, i merge di
|
|
7
|
+
# package.json e *.code-workspace non duplicano le chiavi già presenti.
|
|
8
|
+
# Ogni modifica futura deve conservare questa proprietà.
|
|
9
|
+
|
|
3
10
|
RED='\033[0;31m'
|
|
4
11
|
YELLOW='\033[0;33m'
|
|
5
12
|
GREEN='\033[0;32m'
|
|
@@ -24,7 +31,7 @@ BASE_URL=${0:A:h}
|
|
|
24
31
|
echo "BASE_URL: ${BASE_URL}"
|
|
25
32
|
|
|
26
33
|
TEMPLATES_DIR="${BASE_URL}/templates"
|
|
27
|
-
# WEBPACK_SOURCE_DIR="$BASE_URL/
|
|
34
|
+
# WEBPACK_SOURCE_DIR="$BASE_URL/starter-kit"
|
|
28
35
|
WEBPACK_SOURCE_DIR="$BASE_URL"
|
|
29
36
|
|
|
30
37
|
# protezione contro la sovrascrittura
|
|
@@ -106,6 +113,9 @@ safe_cat "${TEMPLATES_DIR}/_browserslistrc" .browserslistrc new
|
|
|
106
113
|
safe_cat "${TEMPLATES_DIR}/_editorconfig" .editorconfig new
|
|
107
114
|
safe_cat "${TEMPLATES_DIR}/_prettierrc" .prettierrc new
|
|
108
115
|
safe_cat "${TEMPLATES_DIR}/jsconfig.json" jsconfig.json new
|
|
116
|
+
safe_cat "${TEMPLATES_DIR}/tokens-config.mjs" tokens-config.mjs new
|
|
117
|
+
safe_cat "${TEMPLATES_DIR}/_root_htaccess" _root_htaccess
|
|
118
|
+
safe_cat "${TEMPLATES_DIR}/_root_robots.txt" _root_robots.txt
|
|
109
119
|
|
|
110
120
|
# code-workspace: se un file .code-workspace esiste già (qualunque sia il nome),
|
|
111
121
|
# le chiavi del template vengono aggiunte in fondo con prefisso '_'
|
|
@@ -119,7 +129,7 @@ elif [ ! -f "$WORKSPACE_TPL" ]; then
|
|
|
119
129
|
echo -e "${RED}Sorgente mancante: ${WORKSPACE_TPL}${NC}"
|
|
120
130
|
else
|
|
121
131
|
WORKSPACE_FILE="${WORKSPACE_FILES[1]}"
|
|
122
|
-
if node "${BASE_URL}/merge-jsonc.
|
|
132
|
+
if node "${BASE_URL}/src/merge-jsonc.mjs" "$WORKSPACE_TPL" "$WORKSPACE_FILE"; then
|
|
123
133
|
echo -e "${YELLOW}${WORKSPACE_FILE} esistente: chiavi del template aggiunte in fondo con prefisso '_' (da integrare o rimuovere)${NC}"
|
|
124
134
|
BLOCKED_FILES+=("${WORKSPACE_FILE} → merge: chiavi template aggiunte con prefisso \`_\`")
|
|
125
135
|
else
|
|
@@ -141,7 +151,9 @@ npm i -D webpack-cli webpack-dev-server webpack-manifest-plugin webpack
|
|
|
141
151
|
npm i -D @babel/core @babel/preset-env babel-loader terser-webpack-plugin
|
|
142
152
|
npm i -D webpack-remove-empty-scripts copy-webpack-plugin html-loader html-webpack-plugin
|
|
143
153
|
npm i -D postcss autoprefixer postcss-custom-media @csstools/postcss-global-data postcss-loader postcss-preset-env
|
|
144
|
-
|
|
154
|
+
# NB: niente cssnano: la minificazione è di css-minimizer-webpack-plugin e cssnano
|
|
155
|
+
# nel loader postcss eliminerebbe i commenti `purgecss ignore` prima di PurgeCSS
|
|
156
|
+
npm i -D mini-css-extract-plugin style-loader css-loader css-minimizer-webpack-plugin
|
|
145
157
|
npm i -D responsive-loader
|
|
146
158
|
npm i -D process dotenv-webpack
|
|
147
159
|
npm i -D svgo svg-url-loader svgo-loader svgo-add-viewbox mini-svg-data-uri
|
|
@@ -163,6 +175,7 @@ FILES=(
|
|
|
163
175
|
'svg-rules.mjs'
|
|
164
176
|
'svgo.config.mjs'
|
|
165
177
|
'postcss.config.mjs'
|
|
178
|
+
'purgecss-variables-safelist.mjs'
|
|
166
179
|
)
|
|
167
180
|
|
|
168
181
|
# se la cartella esiste già, i moduli vengono copiati in NEW-webpack-modules
|
|
@@ -186,6 +199,12 @@ mkdir -p "$TEMPLATE_DIR_NAME"
|
|
|
186
199
|
cd "$TEMPLATE_DIR_NAME"
|
|
187
200
|
mkdir -p error-pages imgs icons src src/css favicons design-tokens
|
|
188
201
|
cd ..
|
|
202
|
+
|
|
203
|
+
# template delle entry css (globale/di pagina e critical): ogni entry deve
|
|
204
|
+
# importare direttamente custom-properties.css (vedi commenti nei file stessi)
|
|
205
|
+
safe_cat "${TEMPLATES_DIR}/entry-tpl.css" "${TEMPLATE_DIR_NAME}/src/entry-tpl.css"
|
|
206
|
+
safe_cat "${TEMPLATES_DIR}/entry-tpl.critical.css" "${TEMPLATE_DIR_NAME}/src/entry-tpl.critical.css"
|
|
207
|
+
|
|
189
208
|
set +C
|
|
190
209
|
|
|
191
210
|
# Riepilogo finale dei file già esistenti
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
|
|
2
|
+
# no cache
|
|
3
|
+
# <IfModule mod_headers.c>
|
|
4
|
+
# Header set Cache-Control "no-cache, no-store, must-revalidate"
|
|
5
|
+
# Header set Pragma "no-cache"
|
|
6
|
+
# Header set Expires 0
|
|
7
|
+
# </IfModule>
|
|
8
|
+
|
|
9
|
+
# blocco iframe
|
|
10
|
+
# "deny" = tutti siti
|
|
11
|
+
# "sameorigin" tutti tranne quelli che vengono dalla stessa origine
|
|
12
|
+
# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options
|
|
13
|
+
Header set X-Frame-Options "sameorigin"
|
|
14
|
+
|
|
15
|
+
<IfModule mod_expires.c>
|
|
16
|
+
ExpiresActive On
|
|
17
|
+
AddType application/vnd.ms-fontobject .eot
|
|
18
|
+
AddType application/x-font-ttf .ttf
|
|
19
|
+
AddType application/x-font-opentype .otf
|
|
20
|
+
AddType application/x-font-woff .woff
|
|
21
|
+
AddType application/x-font-woff2 .woff2
|
|
22
|
+
AddType application/font-sfnt otf ttf
|
|
23
|
+
AddType application/font-woff woff
|
|
24
|
+
AddType application/font-woff2 woff2
|
|
25
|
+
AddType image/svg+xml .svg
|
|
26
|
+
|
|
27
|
+
ExpiresByType application/vnd.ms-fontobject "access plus 1 year"
|
|
28
|
+
ExpiresByType application/x-font-ttf "access plus 1 year"
|
|
29
|
+
ExpiresByType application/x-font-opentype "access plus 1 year"
|
|
30
|
+
ExpiresByType application/x-font-woff "access plus 1 year"
|
|
31
|
+
ExpiresByType application/x-font-woff2 "access plus 1 year"
|
|
32
|
+
ExpiresByType application/font-sfnt "access plus 1 year"
|
|
33
|
+
ExpiresByType application/font-woff "access plus 1 year"
|
|
34
|
+
ExpiresByType application/font-woff2 "access plus 1 year"
|
|
35
|
+
|
|
36
|
+
ExpiresByType text/html "access plus 1 hour"
|
|
37
|
+
ExpiresByType text/css "access plus 1 year"
|
|
38
|
+
ExpiresByType text/x-javascript "access plus 1 year"
|
|
39
|
+
ExpiresByType application/javascript "access plus 1 year"
|
|
40
|
+
ExpiresByType application/x-javascript "access plus 1 year"
|
|
41
|
+
|
|
42
|
+
ExpiresByType image/svg+xml "access plus 1 year"
|
|
43
|
+
ExpiresByType image/gif "access plus 1 year"
|
|
44
|
+
ExpiresByType image/png "access plus 1 year"
|
|
45
|
+
ExpiresByType image/jpeg "access plus 1 year"
|
|
46
|
+
ExpiresByType image/pjpeg "access plus 1 year"
|
|
47
|
+
ExpiresByType image/webp "access plus 1 year"
|
|
48
|
+
ExpiresByType image/avif "access plus 1 year"
|
|
49
|
+
|
|
50
|
+
ExpiresByType application/pdf "access plus 1 year"
|
|
51
|
+
|
|
52
|
+
ExpiresByType video/mp4 "access plus 1 year"
|
|
53
|
+
ExpiresByType video/webm "access plus 1 year"
|
|
54
|
+
ExpiresByType video/x-m4v "access plus 1 year"
|
|
55
|
+
ExpiresByType video/quicktime "access plus 1 year"
|
|
56
|
+
ExpiresByType audio/mpeg "access plus 1 year"
|
|
57
|
+
ExpiresByType audio/x-wav "access plus 1 year"
|
|
58
|
+
|
|
59
|
+
ExpiresByType image/x-icon "access plus 1 year"
|
|
60
|
+
ExpiresDefault "access plus 1 year"
|
|
61
|
+
</IfModule>
|
|
62
|
+
|
|
63
|
+
<IfModule !mod_expires.c>
|
|
64
|
+
<IfModule mod_headers.c>
|
|
65
|
+
# 1 year
|
|
66
|
+
Header set Cache-Control 'public, max-age 31536000'
|
|
67
|
+
</IfModule>
|
|
68
|
+
</IfModule>
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Template di entry css critical — rinominare e adattare.
|
|
3
|
+
|
|
4
|
+
Le entry con suffisso `.critical` generano asset destinati a essere
|
|
5
|
+
INLINATI nei template html: devono restare AUTOSUFFICIENTI e minimi.
|
|
6
|
+
Il suffisso attiva l'istanza PurgeCSS dedicata con purge stretto, in dev
|
|
7
|
+
e in prod (vedi purgeCSSPluginCritical in webpack.config.mjs), e la regola
|
|
8
|
+
dedicata in css-rules.mjs.
|
|
9
|
+
|
|
10
|
+
Anche qui va importato direttamente custom-properties.css: PurgeCSS
|
|
11
|
+
elabora gli asset singolarmente e mantiene in questo asset solo le
|
|
12
|
+
custom properties usate in questo file, quindi l'asset resta minimo
|
|
13
|
+
senza dipendere dal css globale della pagina.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
@import '@css/custom-properties.css';
|
|
17
|
+
|
|
18
|
+
/* stili above-the-fold della pagina (layout iniziale, spinner, ecc.) */
|
|
@@ -0,0 +1,24 @@
|
|
|
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
|
+
/* ... */
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
|
|
2
|
+
// import path from 'path';
|
|
3
|
+
|
|
4
|
+
// path relativi a questo file
|
|
5
|
+
|
|
6
|
+
const config = {
|
|
7
|
+
// build tokens
|
|
8
|
+
stylelintConfigPath: '../../stylelint.config.mjs',
|
|
9
|
+
buildPath: '../src/css',
|
|
10
|
+
destFile: 'custom-properties.css',
|
|
11
|
+
source: [
|
|
12
|
+
'../../node_modules/@massimo-cassandro/minimo/design-tokens/_src/**/*.tokens.{mjs,jsonc}',
|
|
13
|
+
'./figma-tokens-OK/*.{jsonc,mjs}',
|
|
14
|
+
],
|
|
15
|
+
|
|
16
|
+
colorScalePrefixes: ['primary', 'secondary', 'neutral'],
|
|
17
|
+
|
|
18
|
+
penpotFormat: 'jsonc',
|
|
19
|
+
penpotBuildPath: null,
|
|
20
|
+
penpotDestFile: null,
|
|
21
|
+
penpotExpressions: 'resolve',
|
|
22
|
+
|
|
23
|
+
// ---------------------------------------------------------------------------
|
|
24
|
+
// check-unresolved-custom-props.mjs settings
|
|
25
|
+
// ---------------------------------------------------------------------------
|
|
26
|
+
extra_custom_props_files: [],
|
|
27
|
+
dir_to_check: '../src', // percorso della dir che include i css da analizzare
|
|
28
|
+
exclude_pattern: [ // patterns per l'esclusione dal controllo unresolved-props
|
|
29
|
+
/^--_/,
|
|
30
|
+
]
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export default config;
|
|
@@ -146,7 +146,12 @@ function css_loaders({
|
|
|
146
146
|
modules: css_modules
|
|
147
147
|
? {
|
|
148
148
|
auto: true,
|
|
149
|
-
|
|
149
|
+
// il prefisso fisso `m_`, presente in ENTRAMBE le modalità, consente
|
|
150
|
+
// il safelist delle classi dei css modules in PurgeCSS (safelist.deep
|
|
151
|
+
// [/^m_/], vedi webpack.config.mjs): le classi hashate non possono
|
|
152
|
+
// comparire nei file di contenuto scansionati, e il purge è attivo
|
|
153
|
+
// anche in dev
|
|
154
|
+
localIdentName: isDevelopment ? 'm_[local]_[hash:base64:6]' : 'm_[hash:base64:8]',
|
|
150
155
|
exportLocalsConvention: 'as-is',
|
|
151
156
|
|
|
152
157
|
// namedExport: false,
|
|
@@ -4,40 +4,34 @@ import { fileURLToPath } from 'url';
|
|
|
4
4
|
import globalData from '@csstools/postcss-global-data';
|
|
5
5
|
import customMedia from 'postcss-custom-media';
|
|
6
6
|
import autoprefixer from 'autoprefixer';
|
|
7
|
-
import cssnano from 'cssnano';
|
|
8
|
-
import jitProps from 'postcss-jit-props';
|
|
9
|
-
// import openProps from './modulo_cjs.cjs';
|
|
10
7
|
|
|
11
8
|
const __filename = fileURLToPath(import.meta.url);
|
|
12
9
|
const __dirname = path.dirname(__filename);
|
|
13
10
|
|
|
11
|
+
// NB: le custom properties NON sono gestite qui (postcss-jit-props rimosso):
|
|
12
|
+
// ogni entry css importa direttamente custom-properties.css e le props
|
|
13
|
+
// non utilizzate vengono rimosse in build da PurgeCSS (`variables: true`,
|
|
14
|
+
// vedi webpack.config.mjs)
|
|
15
|
+
|
|
16
|
+
// NB: la minificazione è gestita da CssMinimizerPlugin (webpack.config.mjs):
|
|
17
|
+
// cssnano NON va aggiunto qui, oltre a duplicare la minificazione
|
|
18
|
+
// rimuoverebbe i commenti speciali `/* purgecss start/end ignore */`
|
|
19
|
+
// prima dell'esecuzione di PurgeCSS
|
|
20
|
+
|
|
14
21
|
export default (loaderContext) => {
|
|
15
22
|
const isDevelopment = loaderContext.mode === 'development';
|
|
16
23
|
|
|
17
24
|
const plugins = [
|
|
25
|
+
// rende disponibili le @custom-media a tutti i file css
|
|
26
|
+
// (il contenuto iniettato viene rimosso a fine elaborazione;
|
|
27
|
+
// NON aggiungere qui custom-properties.css: duplicherebbe le props
|
|
28
|
+
// in ogni asset e interferirebbe con il purge, vedi sopra)
|
|
18
29
|
globalData({
|
|
19
30
|
files: [
|
|
20
|
-
// openProps.
|
|
21
|
-
path.resolve(__dirname, '../src/css/custom-properties.css'),
|
|
22
31
|
path.resolve(__dirname, '../src/css/custom-media.css'),
|
|
23
32
|
]
|
|
24
33
|
}),
|
|
25
34
|
|
|
26
|
-
// https://github.com/GoogleChromeLabs/postcss-jit-props
|
|
27
|
-
// https://github.com/argyleink/open-props
|
|
28
|
-
// require('postcss-jit-props')(require('open-props')),
|
|
29
|
-
// require('postcss-jit-props')({
|
|
30
|
-
// ...require('open-props'),
|
|
31
|
-
// custom_selector: ':where(html)'
|
|
32
|
-
// }),
|
|
33
|
-
jitProps({
|
|
34
|
-
files: [
|
|
35
|
-
// ...openProps,
|
|
36
|
-
path.resolve(__dirname, '../src/css/custom-properties.css')
|
|
37
|
-
],
|
|
38
|
-
custom_selector: ':where(html)'
|
|
39
|
-
}),
|
|
40
|
-
|
|
41
35
|
// per IOS < 17 (test)
|
|
42
36
|
// https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-nesting
|
|
43
37
|
// https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-light-dark-function#readme
|
|
@@ -47,7 +41,6 @@ export default (loaderContext) => {
|
|
|
47
41
|
//}),
|
|
48
42
|
// require('@csstools/postcss-light-dark-function')({preserve: false}), /* NB non funziona benissimo... */
|
|
49
43
|
|
|
50
|
-
|
|
51
44
|
// https://github.com/csstools/postcss-plugins/
|
|
52
45
|
|
|
53
46
|
customMedia({
|
|
@@ -58,19 +51,6 @@ export default (loaderContext) => {
|
|
|
58
51
|
autoprefixer(),
|
|
59
52
|
];
|
|
60
53
|
|
|
61
|
-
if (!isDevelopment) {
|
|
62
|
-
// per IOS < 17
|
|
63
|
-
// require('postcss-nesting')({
|
|
64
|
-
// edition: '2021',
|
|
65
|
-
// noIsPseudoSelector: true
|
|
66
|
-
//}),
|
|
67
|
-
// require('@csstools/postcss-light-dark-function'), /* NB non funziona benissimo... */
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
plugins.push(cssnano({ preset: 'default' }));
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
|
|
74
54
|
return {
|
|
75
55
|
plugins: plugins
|
|
76
56
|
};
|