5htp 0.0.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/package.json +94 -0
- package/src/commands/build.ts +32 -0
- package/src/commands/deploy/app.ts +29 -0
- package/src/commands/deploy/web.ts +62 -0
- package/src/commands/dev.ts +100 -0
- package/src/compiler/client/identite.ts +70 -0
- package/src/compiler/client/index.ts +335 -0
- package/src/compiler/common/babel/index.ts +261 -0
- package/src/compiler/common/babel/plugins/form.ts +191 -0
- package/src/compiler/common/babel/plugins/icones-svg.ts +350 -0
- package/src/compiler/common/babel/plugins/importations.ts +337 -0
- package/src/compiler/common/babel/plugins/injection-dependances/index.ts +223 -0
- package/src/compiler/common/babel/plugins/injection-dependances/remplacerFonction.ts +226 -0
- package/src/compiler/common/babel/plugins/models.ts +241 -0
- package/src/compiler/common/babel/plugins/pages.ts +185 -0
- package/src/compiler/common/babel/plugins/queries/index.ts +166 -0
- package/src/compiler/common/files/autres.ts +37 -0
- package/src/compiler/common/files/images.ts +19 -0
- package/src/compiler/common/files/style.ts +64 -0
- package/src/compiler/common/index.ts +148 -0
- package/src/compiler/common/plugins/indexage/_utils/Stringify.ts +72 -0
- package/src/compiler/common/plugins/indexage/_utils/annotations.ts +88 -0
- package/src/compiler/common/plugins/indexage/_utils/iterateur.ts +52 -0
- package/src/compiler/common/plugins/indexage/icones-svg/index.ts +198 -0
- package/src/compiler/common/plugins/indexage/index.ts +132 -0
- package/src/compiler/common/plugins/indexage/indexeur.ts +13 -0
- package/src/compiler/common/plugins/indexage/injection-dependances/index.ts +68 -0
- package/src/compiler/index.ts +86 -0
- package/src/compiler/server/index.ts +177 -0
- package/src/index.ts +192 -0
- package/src/paths.ts +158 -0
- package/src/print.ts +12 -0
- package/src/utils/index.ts +22 -0
- package/src/utils/keyboard.ts +78 -0
- package/tsconfig.json +38 -0
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
/*----------------------------------
|
|
2
|
+
- DEPENDANCES
|
|
3
|
+
----------------------------------*/
|
|
4
|
+
|
|
5
|
+
// Npm
|
|
6
|
+
import fs from 'fs-extra';
|
|
7
|
+
import webfont from 'webfont';
|
|
8
|
+
import defaultMetadataProvider from 'svgicons2svgfont/src/metadata';
|
|
9
|
+
|
|
10
|
+
// Libs
|
|
11
|
+
import Indexeur from '../indexeur';
|
|
12
|
+
import cli from '@cli';
|
|
13
|
+
|
|
14
|
+
// Configs
|
|
15
|
+
const formats = ['woff2'];
|
|
16
|
+
const dossierIcones = cli.paths.core.src + '/client/assets/icons/';
|
|
17
|
+
const dossierSortie = cli.paths.app.bin + '/public/';
|
|
18
|
+
|
|
19
|
+
const cacheTypes = cli.paths.core.src + '/types/icons.d.ts';
|
|
20
|
+
const cacheIndex = dossierIcones + 'index.json';
|
|
21
|
+
|
|
22
|
+
// Types
|
|
23
|
+
import type { TIndexIcones } from '../../../babel/plugins/icones-svg';
|
|
24
|
+
|
|
25
|
+
/*----------------------------------
|
|
26
|
+
- UTILS
|
|
27
|
+
----------------------------------*/
|
|
28
|
+
const refExistant = (dir: string): string[] => {
|
|
29
|
+
|
|
30
|
+
let filelist: string[] = [];
|
|
31
|
+
|
|
32
|
+
let files = fs.readdirSync(dossierIcones + dir);
|
|
33
|
+
for (const file of files)
|
|
34
|
+
if (fs.statSync(dossierIcones + dir + file).isDirectory())
|
|
35
|
+
filelist = [
|
|
36
|
+
...filelist,
|
|
37
|
+
...refExistant(dir + file + '/')
|
|
38
|
+
];
|
|
39
|
+
else if (file.endsWith('.svg'))
|
|
40
|
+
filelist.push(dir + file.substring(0, file.length - 4));
|
|
41
|
+
|
|
42
|
+
return filelist;
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
/*----------------------------------
|
|
46
|
+
- PLUGIN
|
|
47
|
+
----------------------------------*/
|
|
48
|
+
export default class SelecteursApi extends Indexeur {
|
|
49
|
+
|
|
50
|
+
private icones: TIndexIcones = {};
|
|
51
|
+
private iconesExistantes: string[] = [];
|
|
52
|
+
|
|
53
|
+
public constructor() {
|
|
54
|
+
super();
|
|
55
|
+
|
|
56
|
+
if (fs.existsSync(cacheIndex)) {
|
|
57
|
+
|
|
58
|
+
console.log('[icones] Getting icons list from cache ...');
|
|
59
|
+
this.iconesExistantes = fs.readJSONSync(cacheIndex);
|
|
60
|
+
|
|
61
|
+
} else {
|
|
62
|
+
|
|
63
|
+
console.log('[icones] Référencement des icones existantes ...');
|
|
64
|
+
this.iconesExistantes = refExistant('');
|
|
65
|
+
fs.outputJSONSync(cacheIndex, this.iconesExistantes);
|
|
66
|
+
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
console.log('[icones] ' + this.iconesExistantes.length + ' icones référencées');
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/*----------------------------------
|
|
73
|
+
- EVENTS
|
|
74
|
+
----------------------------------*/
|
|
75
|
+
public Init() {
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
public Maj( donneesMeta: TIndexIcones, fichier: string): boolean {
|
|
82
|
+
|
|
83
|
+
let maj = false;
|
|
84
|
+
|
|
85
|
+
// Pour chacune d'entre elles
|
|
86
|
+
for (const cheminIcone in donneesMeta) {
|
|
87
|
+
|
|
88
|
+
// Verif si existante
|
|
89
|
+
if (!this.iconesExistantes.includes( cheminIcone ))
|
|
90
|
+
console.error(`L'icone ${donneesMeta[cheminIcone].nom} (${cheminIcone}) utilisée dans le fichier ${fichier} n'existe pas.`);
|
|
91
|
+
// Verif si déjà référencée
|
|
92
|
+
else if (this.icones[ cheminIcone ] === undefined) {
|
|
93
|
+
// Sinon, référencement
|
|
94
|
+
this.icones[ cheminIcone ] = donneesMeta[ cheminIcone ];
|
|
95
|
+
|
|
96
|
+
//console.log('Nouvelle icone', donneesMeta[ cheminIcone ].nom);
|
|
97
|
+
maj = true;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
return maj;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
public async Enregistrer() {
|
|
105
|
+
|
|
106
|
+
//return []
|
|
107
|
+
|
|
108
|
+
let cheminIcones: {[chemin: string]: string} = {};
|
|
109
|
+
let typeIcones: string[] = [];
|
|
110
|
+
for (const id in this.icones) {
|
|
111
|
+
const icone = this.icones[id]
|
|
112
|
+
cheminIcones[ dossierIcones + icone.fichier ] = icone.id;
|
|
113
|
+
typeIcones.push('"' + icone.nom + '"');
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
console.log('[icones] Création police avec ' + typeIcones.length +' icones ...');
|
|
117
|
+
//console.log('[icones] Liste des icones rféérencées: ', cheminIcones);
|
|
118
|
+
|
|
119
|
+
const optionsMetadata = {
|
|
120
|
+
// Options par défaut de webfont
|
|
121
|
+
// https://github.com/itgalaxy/webfont/blob/cc4412f0ff1f811bb7d38b5da75e128c270d4e6b/src/standalone.js#L203
|
|
122
|
+
// RAPPEL: startUnicode sera incrémenté dans defaultMetadataProvider (https://github.com/nfroidure/svgicons2svgfont/blob/master/src/metadata.js#L61),
|
|
123
|
+
// c'est pourquoi on déclare les options dans un objet
|
|
124
|
+
prependUnicode: false,
|
|
125
|
+
startUnicode: 0xea01
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
const result = await webfont({
|
|
129
|
+
files: Object.keys(cheminIcones),
|
|
130
|
+
fontName: "icons",
|
|
131
|
+
template: dossierIcones + 'template.css',
|
|
132
|
+
// @ts-ignore
|
|
133
|
+
formats,
|
|
134
|
+
templateClassName: 'svg',
|
|
135
|
+
glyphTransformFn: (obj) => {
|
|
136
|
+
|
|
137
|
+
// Nom classe css = via id
|
|
138
|
+
const icone = this.icones[obj.path]
|
|
139
|
+
if (icone !== undefined)
|
|
140
|
+
obj.name = icone.id;
|
|
141
|
+
|
|
142
|
+
return obj;
|
|
143
|
+
},
|
|
144
|
+
// Par défaut, le nom des icones est déterminé via le nom du fichier uniquement
|
|
145
|
+
// Ici, onrefixe le nom des glyphs de leur set (solid, regular) afin de pouvoir utiliser plusieurs sets pour une même icone
|
|
146
|
+
// ex: solid/home et regular/home
|
|
147
|
+
metadataProvider: (file, callback) => {
|
|
148
|
+
|
|
149
|
+
// BUG: Quand defaultMetadataProvider est appellé manuellement, l'unicode est toujours le même peu importe l'icone
|
|
150
|
+
// Incmrémenter l'unicde manuellement ? https://stackoverflow.com/questions/12504042/what-is-a-method-that-can-be-used-to-increment-letters
|
|
151
|
+
defaultMetadataProvider(optionsMetadata)(file, (err, defaultMetas) => {
|
|
152
|
+
|
|
153
|
+
const idIcone = cheminIcones[ file ];
|
|
154
|
+
if (idIcone === undefined)
|
|
155
|
+
console.warn("Impossible de retrouver l'id de l'icone " + file);
|
|
156
|
+
else
|
|
157
|
+
defaultMetas.name = idIcone;
|
|
158
|
+
|
|
159
|
+
callback(err, defaultMetas);
|
|
160
|
+
|
|
161
|
+
optionsMetadata.startUnicode++;
|
|
162
|
+
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
})
|
|
166
|
+
.catch(error => {
|
|
167
|
+
console.error("Erreur lors de la création de la police d'icones", error);
|
|
168
|
+
throw error;
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
console.log('[icones] Enregistrement de la police avec ' + typeIcones.length +' icones ...');
|
|
172
|
+
|
|
173
|
+
// Enregistrement fichiers
|
|
174
|
+
for (const format of formats)
|
|
175
|
+
fs.outputFileSync(dossierSortie + 'icons.' + format, result[ format ]);
|
|
176
|
+
fs.outputFileSync(dossierSortie + 'icons.css', result.template);
|
|
177
|
+
|
|
178
|
+
fs.outputFileSync(cacheTypes, 'export type TIcones = ' + typeIcones.join('|') );
|
|
179
|
+
|
|
180
|
+
console.log("[icones] Police enregistrée.");
|
|
181
|
+
|
|
182
|
+
return [
|
|
183
|
+
/*{
|
|
184
|
+
fichier: dossierSortie + 'index.css',
|
|
185
|
+
donnees: result.template
|
|
186
|
+
},
|
|
187
|
+
...formats.map((format) => ({
|
|
188
|
+
fichier: dossierSortie + 'icones.' + format,
|
|
189
|
+
donnees: result[ format ]
|
|
190
|
+
}))*/
|
|
191
|
+
];
|
|
192
|
+
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/*----------------------------------
|
|
196
|
+
- OUTILS
|
|
197
|
+
----------------------------------*/
|
|
198
|
+
}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import Indexeur from './indexeur';
|
|
2
|
+
|
|
3
|
+
import { Compiler } from 'webpack';
|
|
4
|
+
|
|
5
|
+
type TListeIndexeurs = {[nom: string]: Indexeur}
|
|
6
|
+
|
|
7
|
+
export default class SelecteursApiPlugin {
|
|
8
|
+
|
|
9
|
+
public static metadataContextFunctionName = "metadataSelecteursApiPlugin";
|
|
10
|
+
|
|
11
|
+
private indexeurs: TListeIndexeurs;
|
|
12
|
+
|
|
13
|
+
public constructor(config: TListeIndexeurs) {
|
|
14
|
+
|
|
15
|
+
this.indexeurs = config;
|
|
16
|
+
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
apply(compiler: Compiler) {
|
|
20
|
+
|
|
21
|
+
const nomCompileur = compiler.options.name;
|
|
22
|
+
|
|
23
|
+
for (const nomIndexeur in this.indexeurs) {
|
|
24
|
+
console.log(`[indexage][${nomCompileur}][${nomIndexeur}] Init`);
|
|
25
|
+
this.indexeurs[nomIndexeur].Init();
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
compiler.hooks.compilation.tap("SelecteursApiPlugin", (compilation) => {
|
|
29
|
+
//console.log("The compiler is starting a new compilation...");
|
|
30
|
+
|
|
31
|
+
compilation.hooks.normalModuleLoader.tap("SelecteursApiPlugin", (context, module) => {
|
|
32
|
+
|
|
33
|
+
// Fonction de récupération des métadatas
|
|
34
|
+
context["metadataSelecteursApiPlugin"] = (metadata) => {
|
|
35
|
+
|
|
36
|
+
//console.log(`[selecteurs-api] Meta reçues ` + module.resource, metadata);
|
|
37
|
+
|
|
38
|
+
for (const nomIndexeur in this.indexeurs)
|
|
39
|
+
if (metadata[nomIndexeur] !== undefined) {
|
|
40
|
+
|
|
41
|
+
const majOk = this.indexeurs[nomIndexeur].Maj(metadata[nomIndexeur], module.resource);
|
|
42
|
+
|
|
43
|
+
if (majOk) {
|
|
44
|
+
|
|
45
|
+
/*if (this.indexeurs[ nomIndexeur ].compile[ module.resource ] !== undefined) {
|
|
46
|
+
console.log(`[indexage][${nomCompileur}][${nomIndexeur}] Màj via le fichier ${module.resource}`);
|
|
47
|
+
}*/
|
|
48
|
+
|
|
49
|
+
this.indexeurs[nomIndexeur].compile[module.resource] = true;
|
|
50
|
+
this.indexeurs[nomIndexeur].derniereModif = new Date().getTime();
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
})
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
// A partir de finishModules, webpack n'accepte plus les modifs de modules
|
|
60
|
+
// https://webpack.js.org/api/compilation-hooks/#seal
|
|
61
|
+
// https://github.com/webpack/webpack/issues/8830
|
|
62
|
+
compiler.hooks.thisCompilation.tap("SelecteursApiPlugin", (compilation) => {
|
|
63
|
+
compilation.hooks.finishModules.tapAsync("SelecteursApiPlugin", async (modules, callback) => {
|
|
64
|
+
|
|
65
|
+
for (const nomIndexeur in this.indexeurs) {
|
|
66
|
+
try {
|
|
67
|
+
if (this.indexeurs[nomIndexeur].derniereModif > this.indexeurs[nomIndexeur].derniereMaj) {
|
|
68
|
+
|
|
69
|
+
console.log(`[indexage][${nomCompileur}][${nomIndexeur}] Enregistrement des modifications`);
|
|
70
|
+
|
|
71
|
+
this.indexeurs[nomIndexeur].derniereMaj = this.indexeurs[nomIndexeur].derniereModif;
|
|
72
|
+
const aEnregistrer = await this.indexeurs[nomIndexeur].Enregistrer();
|
|
73
|
+
/*for (const { fichier, donnees } of aEnregistrer) {
|
|
74
|
+
|
|
75
|
+
console.info("TODO: indexag weback")
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
TODO:
|
|
79
|
+
const moduleAmaj = Array.from(modules).find(
|
|
80
|
+
// m.id peut êtreun nombre ou null. Pour rechercher via le chemin, m.resource
|
|
81
|
+
(m) => m.resource && m.resource.endsWith(fichier)
|
|
82
|
+
);
|
|
83
|
+
|
|
84
|
+
if (!moduleAmaj) {
|
|
85
|
+
console.warn(`[indexage][${nomCompileur}][${nomIndexeur}] Impossible de retrouver le module correspondant au fichier ${fichier}`);
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
console.log(`[indexage][${nomCompileur}][${nomIndexeur}] Màj & recompilation du module ${moduleAmaj.resource} ...`);
|
|
90
|
+
|
|
91
|
+
moduleAmaj._source._value = donnees;
|
|
92
|
+
|
|
93
|
+
// Recompile immédiatement et sans devoir changer le fichier
|
|
94
|
+
moduleAmaj.parser.parse(
|
|
95
|
+
moduleAmaj._source.source(),
|
|
96
|
+
{
|
|
97
|
+
current: moduleAmaj,
|
|
98
|
+
module: moduleAmaj,
|
|
99
|
+
compilation: compilation,
|
|
100
|
+
options: compilation.options
|
|
101
|
+
}
|
|
102
|
+
);
|
|
103
|
+
|
|
104
|
+
// ALTERNATIVE: Rien ne se passe
|
|
105
|
+
//compiler.hooks.invalid.call(moduleAmaj.resource, Date.now());
|
|
106
|
+
compilation.rebuildModule( moduleAmaj, (e) => {
|
|
107
|
+
|
|
108
|
+
if (e) console.error(e);
|
|
109
|
+
else {
|
|
110
|
+
|
|
111
|
+
callback();
|
|
112
|
+
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
}*/
|
|
118
|
+
}
|
|
119
|
+
} catch (e) {
|
|
120
|
+
|
|
121
|
+
console.error(`Erreur lors de l'enregistrement des sélecteurs api: `, e);
|
|
122
|
+
throw e;
|
|
123
|
+
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
callback();
|
|
128
|
+
|
|
129
|
+
});
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
type DonneesAenregistrer = { fichier: string, donnees: string }
|
|
2
|
+
|
|
3
|
+
export default abstract class Indexeur {
|
|
4
|
+
|
|
5
|
+
public compile = {};
|
|
6
|
+
public derniereMaj = 0;
|
|
7
|
+
public derniereModif = 0;
|
|
8
|
+
|
|
9
|
+
public abstract Init(): void;
|
|
10
|
+
public abstract Maj( donneesMetas: any, fichier: string ): boolean;
|
|
11
|
+
public abstract Enregistrer(): Promise< DonneesAenregistrer[] >;
|
|
12
|
+
|
|
13
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/*----------------------------------
|
|
2
|
+
- DEPENDANCES
|
|
3
|
+
----------------------------------*/
|
|
4
|
+
|
|
5
|
+
// Npm
|
|
6
|
+
import fs from 'fs-extra';
|
|
7
|
+
|
|
8
|
+
// Libs
|
|
9
|
+
import Indexeur from '../indexeur';
|
|
10
|
+
import Stringify from '../_utils/Stringify';
|
|
11
|
+
import cli from '@cli';
|
|
12
|
+
|
|
13
|
+
const fichierSortie = cli.paths.app.cache + '/serveur/services.ts';
|
|
14
|
+
|
|
15
|
+
/*----------------------------------
|
|
16
|
+
- TYPES
|
|
17
|
+
----------------------------------*/
|
|
18
|
+
type TService = {
|
|
19
|
+
classe?: any,
|
|
20
|
+
dependances: string[]
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
type TListeServices = {[idService: string]: TService};
|
|
24
|
+
|
|
25
|
+
/*----------------------------------
|
|
26
|
+
- PLUGIN
|
|
27
|
+
----------------------------------*/
|
|
28
|
+
export default class SelecteursApi extends Indexeur {
|
|
29
|
+
|
|
30
|
+
private dependances: TListeServices = {};
|
|
31
|
+
|
|
32
|
+
/*----------------------------------
|
|
33
|
+
- EVENTS
|
|
34
|
+
----------------------------------*/
|
|
35
|
+
public Init() {
|
|
36
|
+
|
|
37
|
+
// Autrement, erreur compilation comme quoi que le module n'existe pas
|
|
38
|
+
// En effet, le dossier cache est vidé avant la compilation
|
|
39
|
+
// Et le fichierd'index des déps n'est généré qu'à la fin de la compilation
|
|
40
|
+
fs.outputFileSync(fichierSortie, 'export default {}');
|
|
41
|
+
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
public Maj(nouveauxServices: TListeServices, fichier: string): boolean {
|
|
45
|
+
|
|
46
|
+
let maj = false;
|
|
47
|
+
|
|
48
|
+
for (const idService in nouveauxServices) {
|
|
49
|
+
|
|
50
|
+
maj = true;
|
|
51
|
+
|
|
52
|
+
this.dependances[idService] = nouveauxServices[idService];
|
|
53
|
+
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return maj;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
public async Enregistrer() {
|
|
60
|
+
|
|
61
|
+
console.log('enregistrer dépendances', this.dependances);
|
|
62
|
+
|
|
63
|
+
fs.outputFileSync(fichierSortie, 'export default ' + Stringify(this.dependances, ['classe']));
|
|
64
|
+
|
|
65
|
+
return [];
|
|
66
|
+
|
|
67
|
+
}
|
|
68
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/*----------------------------------
|
|
2
|
+
- DEPENDANCES
|
|
3
|
+
----------------------------------*/
|
|
4
|
+
|
|
5
|
+
// Npm
|
|
6
|
+
import webpack from 'webpack';
|
|
7
|
+
import fs from 'fs-extra';
|
|
8
|
+
|
|
9
|
+
import SpeedMeasurePlugin from "speed-measure-webpack-plugin";
|
|
10
|
+
const smp = new SpeedMeasurePlugin({ disable: true });
|
|
11
|
+
|
|
12
|
+
// Core
|
|
13
|
+
import createServerConfig from './server';
|
|
14
|
+
import createClientConfig from './client';
|
|
15
|
+
import { TCompileMode } from './common';
|
|
16
|
+
import cli from '../';
|
|
17
|
+
|
|
18
|
+
type TCompilerCallback = () => void
|
|
19
|
+
|
|
20
|
+
/*----------------------------------
|
|
21
|
+
- FONCTION
|
|
22
|
+
----------------------------------*/
|
|
23
|
+
export const compiling: { [compiler: string]: Promise<void> } = {};
|
|
24
|
+
|
|
25
|
+
export default async function createCompilers(
|
|
26
|
+
mode: TCompileMode,
|
|
27
|
+
{ before, after }: {
|
|
28
|
+
before?: TCompilerCallback,
|
|
29
|
+
after?: TCompilerCallback,
|
|
30
|
+
} = {}
|
|
31
|
+
) {
|
|
32
|
+
|
|
33
|
+
// Cleanup
|
|
34
|
+
fs.emptyDirSync( cli.paths.app.bin );
|
|
35
|
+
|
|
36
|
+
// Create compilers
|
|
37
|
+
const multiCompiler = webpack([
|
|
38
|
+
smp.wrap( createServerConfig(mode) ),
|
|
39
|
+
smp.wrap( createClientConfig(mode) )
|
|
40
|
+
]);
|
|
41
|
+
|
|
42
|
+
for (const compiler of multiCompiler.compilers) {
|
|
43
|
+
|
|
44
|
+
const name = compiler.name;
|
|
45
|
+
if (name === undefined)
|
|
46
|
+
throw new Error(`A name must be specified to each compiler.`);
|
|
47
|
+
|
|
48
|
+
let timeStart = new Date();
|
|
49
|
+
|
|
50
|
+
let finished: (() => void);
|
|
51
|
+
compiling[name] = new Promise((resolve) => finished = resolve);
|
|
52
|
+
|
|
53
|
+
compiler.hooks.compile.tap(name, () => {
|
|
54
|
+
|
|
55
|
+
before && before();
|
|
56
|
+
|
|
57
|
+
compiling[name] = new Promise((resolve) => finished = resolve);
|
|
58
|
+
|
|
59
|
+
timeStart = new Date();
|
|
60
|
+
console.info(`[${name}] ########## Compiling ...`);
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
/* TODO: Ne pas résoudre la promise tant que la recompilation des données indexées (icones, identité, ...)
|
|
64
|
+
n'a pas été achevée */
|
|
65
|
+
compiler.hooks.done.tap(name, stats => {
|
|
66
|
+
|
|
67
|
+
// Affiche les détails de la compilation
|
|
68
|
+
console.info(stats.toString(compiler.options.stats));
|
|
69
|
+
|
|
70
|
+
// Shiow status
|
|
71
|
+
const timeEnd = new Date();
|
|
72
|
+
const time = timeEnd.getTime() - timeStart.getTime();
|
|
73
|
+
if (stats.hasErrors()) {
|
|
74
|
+
console.error(`############## Failed to compile '${name}' after ${time} ms`);
|
|
75
|
+
} else {
|
|
76
|
+
console.info(`############## [${name}] Finished compilation after ${time} ms`);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Mark as finished
|
|
80
|
+
finished();
|
|
81
|
+
delete compiling[name];
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return multiCompiler;
|
|
86
|
+
}
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
/*----------------------------------
|
|
2
|
+
- DEPENDANCES
|
|
3
|
+
----------------------------------*/
|
|
4
|
+
|
|
5
|
+
// Npm
|
|
6
|
+
import webpack from 'webpack';
|
|
7
|
+
import TsAlias from 'ts-alias';
|
|
8
|
+
import path from 'path';
|
|
9
|
+
|
|
10
|
+
// Plugins
|
|
11
|
+
var nodeExternals = require('webpack-node-externals');
|
|
12
|
+
|
|
13
|
+
// Minimizers
|
|
14
|
+
const TerserPlugin = require("terser-webpack-plugin");
|
|
15
|
+
//var VirtualModulesPlugin = require('webpack-virtual-modules');
|
|
16
|
+
|
|
17
|
+
// Core
|
|
18
|
+
import cli from '@cli';
|
|
19
|
+
import createCommonConfig, { TCompileMode, regex } from '../common';
|
|
20
|
+
|
|
21
|
+
/*----------------------------------
|
|
22
|
+
- CONFIG
|
|
23
|
+
----------------------------------*/
|
|
24
|
+
export default function createCompiler( mode: TCompileMode ): webpack.Configuration {
|
|
25
|
+
|
|
26
|
+
console.info(`Creating compiler for server (${mode}).`);
|
|
27
|
+
const dev = mode === 'dev';
|
|
28
|
+
|
|
29
|
+
const commonConfig = createCommonConfig('server', mode);
|
|
30
|
+
|
|
31
|
+
const { aliases } = cli.paths.aliases.server.forWebpack(cli.paths.app.root + '/node_modules');
|
|
32
|
+
|
|
33
|
+
const config: webpack.Configuration = {
|
|
34
|
+
|
|
35
|
+
...commonConfig,
|
|
36
|
+
|
|
37
|
+
name: 'server',
|
|
38
|
+
target: 'node',
|
|
39
|
+
entry: {
|
|
40
|
+
server: [
|
|
41
|
+
cli.paths.app.root + '/src/server/index.ts',
|
|
42
|
+
],
|
|
43
|
+
},
|
|
44
|
+
|
|
45
|
+
output: {
|
|
46
|
+
|
|
47
|
+
pathinfo: dev,
|
|
48
|
+
|
|
49
|
+
libraryTarget: 'commonjs2',
|
|
50
|
+
|
|
51
|
+
path: cli.paths.app.bin,
|
|
52
|
+
filename: '[name].js',
|
|
53
|
+
publicPath: '/',
|
|
54
|
+
assetModuleFilename: 'public/[hash][ext]',
|
|
55
|
+
|
|
56
|
+
chunkFilename: 'chunks/[name].js',
|
|
57
|
+
// HMR
|
|
58
|
+
hotUpdateMainFilename: 'updates/[fullhash].hot-update.json',
|
|
59
|
+
hotUpdateChunkFilename: 'updates/[id].[fullhash].hot-update.js',
|
|
60
|
+
|
|
61
|
+
},
|
|
62
|
+
|
|
63
|
+
externalsPresets: { node: true }, // in order to ignore built-in modules like path, fs, etc.
|
|
64
|
+
externals: [
|
|
65
|
+
|
|
66
|
+
'./chunk-manifest.json',
|
|
67
|
+
'./asset-manifest.json',
|
|
68
|
+
|
|
69
|
+
// node_modules
|
|
70
|
+
function ({ request }, callback) {
|
|
71
|
+
|
|
72
|
+
const shouldCompile = request !== undefined && (
|
|
73
|
+
request[0] === '.'
|
|
74
|
+
||
|
|
75
|
+
request[0] === '/'
|
|
76
|
+
||
|
|
77
|
+
cli.paths.aliases.server.containsAlias(request)
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
//console.log('isNodeModule', request, isNodeModule);
|
|
81
|
+
|
|
82
|
+
if (!shouldCompile) {
|
|
83
|
+
|
|
84
|
+
// Externalize to a commonjs module using the request path
|
|
85
|
+
return callback(null, 'commonjs ' + request);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Continue without externalizing the import
|
|
89
|
+
callback();
|
|
90
|
+
},
|
|
91
|
+
],
|
|
92
|
+
|
|
93
|
+
resolve: {
|
|
94
|
+
|
|
95
|
+
...commonConfig.resolve,
|
|
96
|
+
|
|
97
|
+
alias: {
|
|
98
|
+
...aliases,
|
|
99
|
+
"@root": cli.paths.app.root,
|
|
100
|
+
},
|
|
101
|
+
|
|
102
|
+
extensions: ['.ts', '.tsx', ".json", ".sql"],
|
|
103
|
+
},
|
|
104
|
+
|
|
105
|
+
module: {
|
|
106
|
+
// Make missing exports an error instead of warning
|
|
107
|
+
strictExportPresence: true,
|
|
108
|
+
|
|
109
|
+
rules: [
|
|
110
|
+
{
|
|
111
|
+
test: regex.scripts,
|
|
112
|
+
include: [
|
|
113
|
+
|
|
114
|
+
cli.paths.app.root + '/src/client',
|
|
115
|
+
cli.paths.core.root + '/src/client',
|
|
116
|
+
|
|
117
|
+
cli.paths.app.root + '/src/common',
|
|
118
|
+
cli.paths.core.root + '/src/common',
|
|
119
|
+
|
|
120
|
+
// Dossiers server uniquement pour le bundle server
|
|
121
|
+
cli.paths.app.root + '/src/server',
|
|
122
|
+
cli.paths.core.root + '/src/server'
|
|
123
|
+
],
|
|
124
|
+
rules: require('../common/babel')('server', dev)
|
|
125
|
+
},
|
|
126
|
+
|
|
127
|
+
// Les pages étan tà la fois compilées dans le bundle client et serveur
|
|
128
|
+
// On ne compile les ressources (css) qu'une seule fois (coté client)
|
|
129
|
+
{
|
|
130
|
+
test: regex.style,
|
|
131
|
+
loader: 'null-loader'
|
|
132
|
+
},
|
|
133
|
+
|
|
134
|
+
...require('../common/files/images')(dev, false),
|
|
135
|
+
|
|
136
|
+
...require('../common/files/autres')(dev, false),
|
|
137
|
+
|
|
138
|
+
// Exclude dev modules from production build
|
|
139
|
+
/*...(dev ? [] : [
|
|
140
|
+
{
|
|
141
|
+
test: cli.paths.app.root + '/node_modules/react-deep-force-update/lib/index.js'),
|
|
142
|
+
loader: 'null-loader',
|
|
143
|
+
},
|
|
144
|
+
]),*/
|
|
145
|
+
],
|
|
146
|
+
},
|
|
147
|
+
|
|
148
|
+
plugins: [
|
|
149
|
+
|
|
150
|
+
...(commonConfig.plugins || [])
|
|
151
|
+
],
|
|
152
|
+
|
|
153
|
+
optimization: {
|
|
154
|
+
minimizer: [
|
|
155
|
+
new TerserPlugin({
|
|
156
|
+
terserOptions: {
|
|
157
|
+
// Consere les classnames
|
|
158
|
+
keep_classnames: true,
|
|
159
|
+
keep_fnames: true
|
|
160
|
+
}
|
|
161
|
+
}),
|
|
162
|
+
]
|
|
163
|
+
},
|
|
164
|
+
|
|
165
|
+
// https://webpack.js.org/configuration/devtool/#devtool
|
|
166
|
+
devtool: /*dev
|
|
167
|
+
? 'eval-source-map' // Recommended choice for development builds with high quality SourceMaps.
|
|
168
|
+
:*/ 'source-map', // Recommended choice for production builds with high quality SourceMaps.
|
|
169
|
+
|
|
170
|
+
// eval-source-map n'est pas précis
|
|
171
|
+
/*devServer: {
|
|
172
|
+
hot: true,
|
|
173
|
+
},*/
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
return config;
|
|
177
|
+
};
|