5htp 0.2.3-1 → 0.3.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/package.json +3 -4
- package/readme.md +15 -11
- package/skeleton/src/server/models.ts +117 -0
- package/src/app/config.ts +4 -2
- package/src/app/index.ts +27 -10
- package/src/commands/build.ts +3 -6
- package/src/commands/dev.ts +7 -7
- package/src/compiler/client/index.ts +1 -1
- package/src/compiler/common/babel/index.ts +1 -2
- package/src/compiler/common/babel/plugins/services.ts +122 -90
- package/src/compiler/common/babel/routes/routes.ts +39 -21
- package/src/compiler/common/plugins/indexage/icones-svg/index.ts +11 -12
- package/src/compiler/common/plugins/indexage/index.ts +6 -4
- package/src/compiler/index.ts +193 -73
- package/src/compiler/server/index.ts +3 -3
- package/src/index.ts +9 -8
- package/src/paths.ts +1 -1
- package/src/compiler/common/babel/plugins/models.old.ts +0 -241
- package/src/compiler/common/babel/routes/routes_old.ts +0 -152
- package/src/compiler/common/utils/fixNpmLink.ts +0 -46
|
@@ -9,7 +9,7 @@ import generate from '@babel/generator';
|
|
|
9
9
|
|
|
10
10
|
// Core
|
|
11
11
|
import cli from '@cli';
|
|
12
|
-
import App,
|
|
12
|
+
import { App, TAppSide } from '../../../../app';
|
|
13
13
|
|
|
14
14
|
/*----------------------------------
|
|
15
15
|
- WEBPACK RULE
|
|
@@ -25,7 +25,6 @@ module.exports = (options: TOptions) => (
|
|
|
25
25
|
[Plugin, options]
|
|
26
26
|
)
|
|
27
27
|
|
|
28
|
-
|
|
29
28
|
/*----------------------------------
|
|
30
29
|
- PLUGIN
|
|
31
30
|
----------------------------------*/
|
|
@@ -41,7 +40,8 @@ function Plugin(babel, { app, side, debug }: TOptions) {
|
|
|
41
40
|
const plugin: PluginObj<{
|
|
42
41
|
|
|
43
42
|
filename: string,
|
|
44
|
-
|
|
43
|
+
part: 'routes',
|
|
44
|
+
side: 'front' | 'back',
|
|
45
45
|
processFile: boolean,
|
|
46
46
|
|
|
47
47
|
// Identifier => Name
|
|
@@ -52,30 +52,44 @@ function Plugin(babel, { app, side, debug }: TOptions) {
|
|
|
52
52
|
|
|
53
53
|
this.filename = state.opts.filename as string;
|
|
54
54
|
this.processFile = true;
|
|
55
|
+
|
|
56
|
+
// Relative path
|
|
57
|
+
let relativeFileName: string | undefined;
|
|
58
|
+
if (this.filename.startsWith( cli.paths.appRoot ))
|
|
59
|
+
relativeFileName = this.filename.substring( cli.paths.appRoot.length );
|
|
60
|
+
if (this.filename.startsWith( cli.paths.coreRoot ))
|
|
61
|
+
relativeFileName = this.filename.substring( cli.paths.coreRoot.length );
|
|
62
|
+
if (this.filename.startsWith('/node_modules/5htp-core/'))
|
|
63
|
+
relativeFileName = this.filename.substring( '/node_modules/5htp-core/'.length );
|
|
64
|
+
|
|
65
|
+
// The file isn't a route definition
|
|
66
|
+
if (relativeFileName === undefined) {
|
|
67
|
+
this.processFile = false;
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
55
70
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
||
|
|
59
|
-
this.filename.startsWith( cli.paths.coreRoot + '/src/client/pages' )
|
|
60
|
-
) {
|
|
71
|
+
// Differenciate back / front
|
|
72
|
+
if (relativeFileName.startsWith('/src/client/pages')) {
|
|
61
73
|
|
|
62
|
-
this.
|
|
74
|
+
this.side = 'front';
|
|
75
|
+
this.part = 'routes';
|
|
63
76
|
|
|
64
|
-
} else if (
|
|
77
|
+
} else if (relativeFileName.startsWith('/src/server/routes')) {
|
|
65
78
|
|
|
66
|
-
this.
|
|
67
|
-
|
|
68
|
-
|
|
79
|
+
this.side = 'back';
|
|
80
|
+
this.part = 'routes';
|
|
81
|
+
|
|
82
|
+
} else
|
|
69
83
|
this.processFile = false;
|
|
70
84
|
|
|
85
|
+
// Init output
|
|
71
86
|
this.importedServices = {}
|
|
72
87
|
this.routeDefinitions = []
|
|
73
|
-
|
|
74
88
|
},
|
|
75
89
|
visitor: {
|
|
76
90
|
|
|
77
91
|
// Find @app imports
|
|
78
|
-
// Test: import {
|
|
92
|
+
// Test: import { Router } from '@app';
|
|
79
93
|
// Replace by: nothing
|
|
80
94
|
ImportDeclaration(path) {
|
|
81
95
|
|
|
@@ -98,10 +112,11 @@ function Plugin(babel, { app, side, debug }: TOptions) {
|
|
|
98
112
|
|
|
99
113
|
// Remove this import
|
|
100
114
|
path.replaceWithMultiple([]);
|
|
115
|
+
|
|
101
116
|
},
|
|
102
117
|
|
|
103
|
-
// Find
|
|
104
|
-
// Test:
|
|
118
|
+
// Find Router definitions
|
|
119
|
+
// Test: Router.xxx()
|
|
105
120
|
// Replace by: nothing
|
|
106
121
|
CallExpression(path) {
|
|
107
122
|
|
|
@@ -131,7 +146,7 @@ function Plugin(babel, { app, side, debug }: TOptions) {
|
|
|
131
146
|
|
|
132
147
|
// Client route definition: Add chunk id
|
|
133
148
|
let [routePath, ...routeArgs] = path.node.arguments;
|
|
134
|
-
if (this.
|
|
149
|
+
if (this.side === 'front' && callee.object.name === 'Router') {
|
|
135
150
|
|
|
136
151
|
// Inject chunk id in options (2nd arg)
|
|
137
152
|
const newRouteArgs = injectChunkId(routeArgs, this.filename);
|
|
@@ -160,21 +175,24 @@ function Plugin(babel, { app, side, debug }: TOptions) {
|
|
|
160
175
|
|
|
161
176
|
// Wrap declarations into a exported const app function
|
|
162
177
|
/*
|
|
163
|
-
export const __register = ({
|
|
178
|
+
export const __register = ({ Router }} => {
|
|
164
179
|
|
|
165
|
-
|
|
180
|
+
Router.page(..)
|
|
166
181
|
|
|
167
182
|
}
|
|
168
183
|
*/
|
|
169
184
|
Program: {
|
|
170
185
|
exit: function(path, parent) {
|
|
171
186
|
|
|
187
|
+
if (!this.processFile)
|
|
188
|
+
return;
|
|
189
|
+
|
|
172
190
|
const importedServices = Object.entries(this.importedServices);
|
|
173
191
|
if (importedServices.length === 0)
|
|
174
192
|
return;
|
|
175
193
|
|
|
176
194
|
let exportValue: types.Expression | types.BlockStatement;
|
|
177
|
-
if (this.
|
|
195
|
+
if (this.side === 'front') {
|
|
178
196
|
|
|
179
197
|
const routesDefCount = this.routeDefinitions.length;
|
|
180
198
|
if (routesDefCount !== 1)
|
|
@@ -34,7 +34,7 @@ export default class IconesSVG extends Indexeur {
|
|
|
34
34
|
private cacheTypes: string;
|
|
35
35
|
private cacheIndex: string;
|
|
36
36
|
|
|
37
|
-
public constructor( app: App ) {
|
|
37
|
+
public constructor( app: App, private debug?: boolean ) {
|
|
38
38
|
super();
|
|
39
39
|
|
|
40
40
|
this.formats = ['woff2'];
|
|
@@ -46,18 +46,18 @@ export default class IconesSVG extends Indexeur {
|
|
|
46
46
|
|
|
47
47
|
if (fs.existsSync(this.cacheIndex)) {
|
|
48
48
|
|
|
49
|
-
console.log('[icones] Getting icons list from cache ...');
|
|
49
|
+
this.debug && console.log('[icones] Getting icons list from cache ...');
|
|
50
50
|
this.iconesExistantes = fs.readJSONSync(this.cacheIndex);
|
|
51
51
|
|
|
52
52
|
} else {
|
|
53
53
|
|
|
54
|
-
console.log('[icones] Référencement des icones existantes ...');
|
|
54
|
+
this.debug && console.log('[icones] Référencement des icones existantes ...');
|
|
55
55
|
this.iconesExistantes = this.refExistant('');
|
|
56
56
|
fs.outputJSONSync(this.cacheIndex, this.iconesExistantes);
|
|
57
57
|
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
-
console.log('[icones] ' + this.iconesExistantes.length + ' icones référencées');
|
|
60
|
+
this.debug && console.log('[icones] ' + this.iconesExistantes.length + ' icones référencées');
|
|
61
61
|
}
|
|
62
62
|
|
|
63
63
|
private refExistant = (dir: string): string[] => {
|
|
@@ -121,7 +121,7 @@ export default class IconesSVG extends Indexeur {
|
|
|
121
121
|
typeIcones.push('"' + icone.nom + '"');
|
|
122
122
|
}
|
|
123
123
|
|
|
124
|
-
console.log('[icones] Création police avec ' + typeIcones.length +' icones ...');
|
|
124
|
+
this.debug && console.log('[icones] Création police avec ' + typeIcones.length +' icones ...');
|
|
125
125
|
//console.log('[icones] Liste des icones rféérencées: ', cheminIcones);
|
|
126
126
|
|
|
127
127
|
const optionsMetadata = {
|
|
@@ -170,13 +170,12 @@ export default class IconesSVG extends Indexeur {
|
|
|
170
170
|
|
|
171
171
|
});
|
|
172
172
|
}
|
|
173
|
-
})
|
|
174
|
-
.
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
});
|
|
173
|
+
}).catch(error => {
|
|
174
|
+
console.error("Erreur lors de la création de la police d'icones", error);
|
|
175
|
+
throw error;
|
|
176
|
+
});
|
|
178
177
|
|
|
179
|
-
console.log('[icones] Enregistrement de la police avec ' + typeIcones.length +' icones ...');
|
|
178
|
+
this.debug && console.log('[icones] Enregistrement de la police avec ' + typeIcones.length +' icones ...');
|
|
180
179
|
|
|
181
180
|
// Enregistrement fichiers
|
|
182
181
|
for (const format of this.formats)
|
|
@@ -185,7 +184,7 @@ export default class IconesSVG extends Indexeur {
|
|
|
185
184
|
|
|
186
185
|
fs.outputFileSync(this.cacheTypes, 'export type TIcones = ' + typeIcones.join('|') );
|
|
187
186
|
|
|
188
|
-
console.log("[icones] Police enregistrée.");
|
|
187
|
+
this.debug && console.log("[icones] Police enregistrée.");
|
|
189
188
|
|
|
190
189
|
return [
|
|
191
190
|
/*{
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import Indexeur from './indexeur';
|
|
2
2
|
|
|
3
|
-
import { Compiler } from 'webpack';
|
|
3
|
+
import { Compiler, NormalModule } from 'webpack';
|
|
4
4
|
|
|
5
5
|
type TListeIndexeurs = {[nom: string]: Indexeur}
|
|
6
6
|
|
|
7
|
+
const debug = false;
|
|
8
|
+
|
|
7
9
|
export default class SelecteursApiPlugin {
|
|
8
10
|
|
|
9
11
|
public static metadataContextFunctionName = "metadataSelecteursApiPlugin";
|
|
@@ -21,14 +23,14 @@ export default class SelecteursApiPlugin {
|
|
|
21
23
|
const nomCompileur = compiler.options.name;
|
|
22
24
|
|
|
23
25
|
for (const nomIndexeur in this.indexeurs) {
|
|
24
|
-
console.log(`[indexage][${nomCompileur}][${nomIndexeur}] Init`);
|
|
26
|
+
debug && console.log(`[indexage][${nomCompileur}][${nomIndexeur}] Init`);
|
|
25
27
|
this.indexeurs[nomIndexeur].Init();
|
|
26
28
|
}
|
|
27
29
|
|
|
28
30
|
compiler.hooks.compilation.tap("SelecteursApiPlugin", (compilation) => {
|
|
29
31
|
//console.log("The compiler is starting a new compilation...");
|
|
30
32
|
|
|
31
|
-
compilation.
|
|
33
|
+
NormalModule.getCompilationHooks(compilation).loader.tap("SelecteursApiPlugin", (context, module) => {
|
|
32
34
|
|
|
33
35
|
// Fonction de récupération des métadatas
|
|
34
36
|
context["metadataSelecteursApiPlugin"] = (metadata) => {
|
|
@@ -66,7 +68,7 @@ export default class SelecteursApiPlugin {
|
|
|
66
68
|
try {
|
|
67
69
|
if (this.indexeurs[nomIndexeur].derniereModif > this.indexeurs[nomIndexeur].derniereMaj) {
|
|
68
70
|
|
|
69
|
-
console.log(`[indexage][${nomCompileur}][${nomIndexeur}] Enregistrement des modifications`);
|
|
71
|
+
debug && console.log(`[indexage][${nomCompileur}][${nomIndexeur}] Enregistrement des modifications`);
|
|
70
72
|
|
|
71
73
|
this.indexeurs[nomIndexeur].derniereMaj = this.indexeurs[nomIndexeur].derniereModif;
|
|
72
74
|
const aEnregistrer = await this.indexeurs[nomIndexeur].Enregistrer();
|
package/src/compiler/index.ts
CHANGED
|
@@ -6,116 +6,236 @@
|
|
|
6
6
|
import path from 'path';
|
|
7
7
|
import webpack from 'webpack';
|
|
8
8
|
import fs from 'fs-extra';
|
|
9
|
+
import micromatch from 'micromatch';
|
|
10
|
+
import moduleAlias from 'module-alias';
|
|
9
11
|
|
|
10
12
|
import SpeedMeasurePlugin from "speed-measure-webpack-plugin";
|
|
11
13
|
const smp = new SpeedMeasurePlugin({ disable: true });
|
|
12
14
|
|
|
13
15
|
// Core
|
|
16
|
+
import app from '../app';
|
|
17
|
+
import cli from '..';
|
|
14
18
|
import createServerConfig from './server';
|
|
15
19
|
import createClientConfig from './client';
|
|
16
20
|
import { TCompileMode } from './common';
|
|
17
|
-
import { fixNpmLinkIssues } from './common/utils/fixNpmLink';
|
|
18
|
-
|
|
19
|
-
// types
|
|
20
|
-
import type App from '../app';
|
|
21
21
|
|
|
22
22
|
type TCompilerCallback = () => void
|
|
23
23
|
|
|
24
24
|
/*----------------------------------
|
|
25
25
|
- FONCTION
|
|
26
26
|
----------------------------------*/
|
|
27
|
-
export
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
fs.ensureDirSync( path.join(app.paths.bin, 'public') )
|
|
41
|
-
const publicFiles = fs.readdirSync(app.paths.public);
|
|
42
|
-
for (const publicFile of publicFiles) {
|
|
43
|
-
// Dev: faster to use symlink
|
|
44
|
-
if (mode === 'dev')
|
|
45
|
-
fs.symlinkSync(
|
|
46
|
-
path.join(app.paths.public, publicFile),
|
|
47
|
-
path.join(app.paths.bin, 'public', publicFile)
|
|
48
|
-
);
|
|
49
|
-
// Prod: Symlink not always supported by CI / Containers solutions
|
|
50
|
-
else
|
|
51
|
-
fs.copySync(
|
|
52
|
-
path.join(app.paths.public, publicFile),
|
|
53
|
-
path.join(app.paths.bin, 'public', publicFile)
|
|
54
|
-
);
|
|
27
|
+
export default class Compiler {
|
|
28
|
+
|
|
29
|
+
public compiling: { [compiler: string]: Promise<void> } = {};
|
|
30
|
+
|
|
31
|
+
public constructor(
|
|
32
|
+
private mode: TCompileMode,
|
|
33
|
+
private callbacks: {
|
|
34
|
+
before?: TCompilerCallback,
|
|
35
|
+
after?: TCompilerCallback,
|
|
36
|
+
} = {},
|
|
37
|
+
private debug: boolean = false
|
|
38
|
+
) {
|
|
39
|
+
|
|
55
40
|
}
|
|
56
41
|
|
|
42
|
+
public cleanup() {
|
|
43
|
+
|
|
44
|
+
fs.emptyDirSync( app.paths.bin );
|
|
45
|
+
fs.ensureDirSync( path.join(app.paths.bin, 'public') )
|
|
46
|
+
const publicFiles = fs.readdirSync(app.paths.public);
|
|
47
|
+
for (const publicFile of publicFiles) {
|
|
48
|
+
// Dev: faster to use symlink
|
|
49
|
+
if (this.mode === 'dev')
|
|
50
|
+
fs.symlinkSync(
|
|
51
|
+
path.join(app.paths.public, publicFile),
|
|
52
|
+
path.join(app.paths.bin, 'public', publicFile)
|
|
53
|
+
);
|
|
54
|
+
// Prod: Symlink not always supported by CI / Containers solutions
|
|
55
|
+
else
|
|
56
|
+
fs.copySync(
|
|
57
|
+
path.join(app.paths.public, publicFile),
|
|
58
|
+
path.join(app.paths.bin, 'public', publicFile)
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
57
62
|
/* FIX issue with npm link
|
|
58
63
|
When we install a module with npm link, this module's deps are not installed in the parent project scope
|
|
59
64
|
Which causes some issues:
|
|
60
65
|
- The module's deps are not found by Typescript
|
|
61
66
|
- Including React, so VSCode shows that JSX is missing
|
|
62
67
|
*/
|
|
63
|
-
fixNpmLinkIssues(
|
|
68
|
+
public fixNpmLinkIssues() {
|
|
69
|
+
const corePath = path.join(app.paths.root, '/node_modules/5htp-core');
|
|
70
|
+
if (!fs.lstatSync( corePath ).isSymbolicLink())
|
|
71
|
+
return console.info("Not fixing npm issue because 5htp-core wasn't installed with npm link.");
|
|
72
|
+
|
|
73
|
+
this.debug && console.info(`Fix NPM link issues ...`);
|
|
74
|
+
|
|
75
|
+
const appModules = path.join(app.paths.root, 'node_modules');
|
|
76
|
+
const coreModules = path.join(corePath, 'node_modules');
|
|
77
|
+
|
|
78
|
+
// When the 5htp package is installed from npm link,
|
|
79
|
+
// Modules are installed locally and not glbally as with with the 5htp package from NPM.
|
|
80
|
+
// So we need to symbilnk the http-core node_modules in one of the parents of server.js.
|
|
81
|
+
// It avoids errors like: "Error: Cannot find module 'intl'"
|
|
82
|
+
fs.symlinkSync( coreModules, path.join(app.paths.bin, 'node_modules') );
|
|
83
|
+
|
|
84
|
+
// Same problem: when 5htp-core is installed via npm link,
|
|
85
|
+
// Typescript doesn't detect React and shows mission JSX errors
|
|
86
|
+
const preactCoreModule = path.join(coreModules, 'preact');
|
|
87
|
+
const preactAppModule = path.join(appModules, 'preact');
|
|
88
|
+
const reactAppModule = path.join(appModules, 'react');
|
|
89
|
+
|
|
90
|
+
if (!fs.existsSync( preactAppModule ))
|
|
91
|
+
fs.symlinkSync( preactCoreModule, preactAppModule );
|
|
92
|
+
if (!fs.existsSync( reactAppModule ))
|
|
93
|
+
fs.symlinkSync( path.join(preactCoreModule, 'compat'), reactAppModule );
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
private findServices( dir: string ) {
|
|
97
|
+
const files: string[] = [];
|
|
98
|
+
const dirents = fs.readdirSync(dir, { withFileTypes: true });
|
|
99
|
+
for (const dirent of dirents) {
|
|
100
|
+
const res = path.resolve(dir, dirent.name);
|
|
101
|
+
if (dirent.isDirectory()) {
|
|
102
|
+
files.push( ...this.findServices(res) );
|
|
103
|
+
} else if (dirent.name === 'service.json') {
|
|
104
|
+
files.push( path.dirname(res) );
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return files;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
private indexServices() {
|
|
111
|
+
|
|
112
|
+
const imported: string[] = []
|
|
113
|
+
const exportedType: string[] = []
|
|
114
|
+
const exportedMetas: string[] = []
|
|
115
|
+
|
|
116
|
+
// Index services
|
|
117
|
+
const searchDirs = {
|
|
118
|
+
'@server/services': path.join(cli.paths.core.src, 'server', 'services'),
|
|
119
|
+
'@/server/services': path.join(app.paths.src, 'server', 'services'),
|
|
120
|
+
// TODO: node_modules
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
for (const importationPrefix in searchDirs) {
|
|
124
|
+
|
|
125
|
+
const searchDir = searchDirs[ importationPrefix ];
|
|
126
|
+
const services = this.findServices(searchDir);
|
|
127
|
+
|
|
128
|
+
for (const serviceDir of services) {
|
|
129
|
+
|
|
130
|
+
const metasFile = path.join( serviceDir, 'service.json');
|
|
131
|
+
const { id, name, parent, dependences } = require(metasFile);
|
|
132
|
+
|
|
133
|
+
const importationPath = importationPrefix + serviceDir.substring( searchDir.length );
|
|
134
|
+
|
|
135
|
+
// Generate index & typings
|
|
136
|
+
imported.push(`import type ${name} from "${importationPath}";`);
|
|
137
|
+
exportedType.push(`'${id}': ${name},`);
|
|
138
|
+
// NOTE: only import enabled packages to optimize memory
|
|
139
|
+
// TODO: don't index non-setuped packages in the exported metas
|
|
140
|
+
exportedMetas.push(`'${id}': {
|
|
141
|
+
class: () => require("${importationPath}"),
|
|
142
|
+
id: "${id}",
|
|
143
|
+
name: "${name}",
|
|
144
|
+
parent: "${parent}",
|
|
145
|
+
dependences: ${JSON.stringify(dependences)},
|
|
146
|
+
},`);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// Output the services index
|
|
151
|
+
fs.outputFileSync(
|
|
152
|
+
path.join( app.paths.server.generated, 'services.ts'),
|
|
153
|
+
`${imported.join('\n')}
|
|
154
|
+
export type Services = {
|
|
155
|
+
${exportedType.join('\n')}
|
|
156
|
+
}
|
|
157
|
+
export default {
|
|
158
|
+
${exportedMetas.join('\n')}
|
|
159
|
+
}`
|
|
160
|
+
);
|
|
161
|
+
|
|
162
|
+
fs.outputFileSync(
|
|
163
|
+
path.join( app.paths.server.generated, 'services.d.ts'),
|
|
164
|
+
`declare module "@app" {
|
|
165
|
+
type Services = import("./services").Services;
|
|
166
|
+
const ServerServices: Services & {
|
|
167
|
+
app: import('@server/app').Application<Services>
|
|
168
|
+
}
|
|
169
|
+
export = ServerServices
|
|
170
|
+
}`
|
|
171
|
+
);
|
|
172
|
+
}
|
|
64
173
|
|
|
65
|
-
|
|
66
|
-
const multiCompiler = webpack([
|
|
67
|
-
smp.wrap( createServerConfig(app, mode) ),
|
|
68
|
-
smp.wrap( createClientConfig(app, mode) )
|
|
69
|
-
]);
|
|
174
|
+
public async create() {
|
|
70
175
|
|
|
71
|
-
|
|
176
|
+
this.cleanup();
|
|
72
177
|
|
|
73
|
-
|
|
74
|
-
if (name === undefined)
|
|
75
|
-
throw new Error(`A name must be specified to each compiler.`);
|
|
178
|
+
this.fixNpmLinkIssues();
|
|
76
179
|
|
|
77
|
-
|
|
180
|
+
this.indexServices();
|
|
78
181
|
|
|
79
|
-
|
|
80
|
-
|
|
182
|
+
// Create compilers
|
|
183
|
+
const multiCompiler = webpack([
|
|
184
|
+
smp.wrap( createServerConfig(app, this.mode) ),
|
|
185
|
+
smp.wrap( createClientConfig(app, this.mode) )
|
|
186
|
+
]);
|
|
81
187
|
|
|
82
|
-
compiler.
|
|
188
|
+
for (const compiler of multiCompiler.compilers) {
|
|
83
189
|
|
|
84
|
-
|
|
190
|
+
const name = compiler.name;
|
|
191
|
+
if (name === undefined)
|
|
192
|
+
throw new Error(`A name must be specified to each compiler.`);
|
|
85
193
|
|
|
86
|
-
|
|
194
|
+
let timeStart = new Date();
|
|
87
195
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
});
|
|
196
|
+
let finished: (() => void);
|
|
197
|
+
this.compiling[name] = new Promise((resolve) => finished = resolve);
|
|
91
198
|
|
|
92
|
-
|
|
93
|
-
n'a pas été achevée */
|
|
94
|
-
compiler.hooks.done.tap(name, stats => {
|
|
199
|
+
compiler.hooks.compile.tap(name, () => {
|
|
95
200
|
|
|
96
|
-
|
|
97
|
-
console.info(stats.toString(compiler.options.stats));
|
|
201
|
+
this.callbacks.before && this.callbacks.before();
|
|
98
202
|
|
|
99
|
-
|
|
100
|
-
const timeEnd = new Date();
|
|
101
|
-
const time = timeEnd.getTime() - timeStart.getTime();
|
|
102
|
-
if (stats.hasErrors()) {
|
|
103
|
-
console.error(`[${name}] Failed to compile after ${time} ms`);
|
|
203
|
+
this.compiling[name] = new Promise((resolve) => finished = resolve);
|
|
104
204
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
process.exit(0);
|
|
205
|
+
timeStart = new Date();
|
|
206
|
+
console.info(`[${name}] Compiling ...`);
|
|
207
|
+
});
|
|
109
208
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
209
|
+
/* TODO: Ne pas résoudre la promise tant que la recompilation des données indexées (icones, identité, ...)
|
|
210
|
+
n'a pas été achevée */
|
|
211
|
+
compiler.hooks.done.tap(name, stats => {
|
|
212
|
+
|
|
213
|
+
// Shiow status
|
|
214
|
+
const timeEnd = new Date();
|
|
215
|
+
const time = timeEnd.getTime() - timeStart.getTime();
|
|
216
|
+
if (stats.hasErrors()) {
|
|
217
|
+
|
|
218
|
+
console.info(stats.toString(compiler.options.stats));
|
|
219
|
+
console.error(`[${name}] Failed to compile after ${time} ms`);
|
|
220
|
+
|
|
221
|
+
// Exit process with code 0, so the CI container can understand building failed
|
|
222
|
+
// Only in prod, because in dev, we want the compiler watcher continue running
|
|
223
|
+
if (this.mode === 'prod')
|
|
224
|
+
process.exit(0);
|
|
225
|
+
|
|
226
|
+
} else {
|
|
227
|
+
this.debug && console.info(stats.toString(compiler.options.stats));
|
|
228
|
+
console.info(`[${name}] Finished compilation after ${time} ms`);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
// Mark as finished
|
|
232
|
+
finished();
|
|
233
|
+
delete this.compiling[name];
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
return multiCompiler;
|
|
113
238
|
|
|
114
|
-
// Mark as finished
|
|
115
|
-
finished();
|
|
116
|
-
delete compiling[name];
|
|
117
|
-
});
|
|
118
239
|
}
|
|
119
240
|
|
|
120
|
-
return multiCompiler;
|
|
121
241
|
}
|
|
@@ -179,7 +179,7 @@ export default function createCompiler( app: App, mode: TCompileMode ): webpack.
|
|
|
179
179
|
],
|
|
180
180
|
|
|
181
181
|
optimization: {
|
|
182
|
-
minimizer: [
|
|
182
|
+
minimizer: dev ? [] : [
|
|
183
183
|
new TerserPlugin({
|
|
184
184
|
terserOptions: {
|
|
185
185
|
// Consere les classnames
|
|
@@ -191,9 +191,9 @@ export default function createCompiler( app: App, mode: TCompileMode ): webpack.
|
|
|
191
191
|
},
|
|
192
192
|
|
|
193
193
|
// https://webpack.js.org/configuration/devtool/#devtool
|
|
194
|
-
devtool:
|
|
194
|
+
devtool: dev
|
|
195
195
|
? 'eval-source-map' // Recommended choice for development builds with high quality SourceMaps.
|
|
196
|
-
|
|
196
|
+
: 'source-map', // Recommended choice for production builds with high quality SourceMaps.
|
|
197
197
|
|
|
198
198
|
// eval-source-map n'est pas précis
|
|
199
199
|
/*devServer: {
|
package/src/index.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env -S npx ts-node
|
|
2
2
|
|
|
3
|
+
process.traceDeprecation = true;
|
|
4
|
+
|
|
3
5
|
/*----------------------------------
|
|
4
6
|
- DEPENDANCES
|
|
5
7
|
----------------------------------*/
|
|
6
8
|
|
|
7
9
|
// Npm
|
|
8
|
-
import { Logger } from "tslog";
|
|
9
10
|
import cp from 'child_process';
|
|
10
11
|
|
|
11
12
|
// Libs
|
|
@@ -33,15 +34,15 @@ export class CLI {
|
|
|
33
34
|
|
|
34
35
|
// Context
|
|
35
36
|
public args: TArgsObject = {};
|
|
37
|
+
|
|
38
|
+
public debug: boolean = false;
|
|
36
39
|
|
|
37
40
|
public constructor(
|
|
38
41
|
public paths = new Paths( process.cwd() )
|
|
39
42
|
) {
|
|
40
|
-
console.log(`[cli] 5HTP CLI`, process.env.npm_package_version);
|
|
41
|
-
console.log(`[cli] Start debugger ...`);
|
|
42
|
-
new Logger({ name: "cli", overwriteConsole: true });
|
|
43
|
+
this.debug && console.log(`[cli] 5HTP CLI`, process.env.npm_package_version);
|
|
43
44
|
|
|
44
|
-
console.log(`[cli] Apply aliases ...`);
|
|
45
|
+
this.debug && console.log(`[cli] Apply aliases ...`);
|
|
45
46
|
this.paths.applyAliases();
|
|
46
47
|
|
|
47
48
|
this.start();
|
|
@@ -59,7 +60,7 @@ export class CLI {
|
|
|
59
60
|
}
|
|
60
61
|
|
|
61
62
|
public start() {
|
|
62
|
-
|
|
63
|
+
|
|
63
64
|
const [, , commandName, ...argv] = process.argv;
|
|
64
65
|
|
|
65
66
|
if (this.commands[commandName] === undefined)
|
|
@@ -107,7 +108,7 @@ export class CLI {
|
|
|
107
108
|
|
|
108
109
|
this.args = args;
|
|
109
110
|
|
|
110
|
-
console.info(`Running command ${command}`, this.args);
|
|
111
|
+
this.debug && console.info(`Running command ${command}`, this.args);
|
|
111
112
|
|
|
112
113
|
// Check existance
|
|
113
114
|
if (this.commands[command] === undefined)
|
|
@@ -118,7 +119,7 @@ export class CLI {
|
|
|
118
119
|
// Running
|
|
119
120
|
runner.run().then(() => {
|
|
120
121
|
|
|
121
|
-
console.info(`Command ${command} finished.`);
|
|
122
|
+
this.debug && console.info(`Command ${command} finished.`);
|
|
122
123
|
|
|
123
124
|
}).catch((e) => {
|
|
124
125
|
|
package/src/paths.ts
CHANGED
|
@@ -14,7 +14,7 @@ import { filenameToImportName } from 'babel-plugin-glob-import';
|
|
|
14
14
|
- TYPES
|
|
15
15
|
----------------------------------*/
|
|
16
16
|
|
|
17
|
-
import type App from './app';
|
|
17
|
+
import type { App } from './app';
|
|
18
18
|
import type { TAppSide } from './app';
|
|
19
19
|
|
|
20
20
|
export type TPathInfosOptions = {
|