
Research
Security News
Lazarus Strikes npm Again with New Wave of Malicious Packages
The Socket Research Team has discovered six new malicious npm packages linked to North Korea’s Lazarus Group, designed to steal credentials and deploy backdoors.
hornet-js-builder
Advanced tools
Builder/loader des Applications Hornet, Wrapper NPM permettant de fixer les versions des dépendances
hornet-js-builder
a été développé dans le but premier de masquer la complexité des différentes tâches nécessaires à la construction d'un projet. Son second objectif est d'accompagner le développeur en lui fournissant des outils tout au long du developpement d'un projet.
A cet effet, il surcharge les librairies gulp
et npm
pour fournir des tâches se rapprochant de la philosophie maven
ainsi que des utilitaires pour simplifier et pérenniser la gestion des dépendances.
Les versions de chaque dépendance déclarée doivent également être fixes (sans ^, ~ ou *) afin de pérenniser les versions.
npm install -g hornet-js-builder
s'assurer que les liens symboliques hornetbuilder
et hb
ont bien été crées dans le répertoire "~/bin". Si ce n'est pas le cas:
se positionner dans le répertoire "~/bin", puis:
ln -s ${cheminAccesHornetBuilderInstalléDansNode}/bin/builder-cli.js hb
ln -s ${cheminAccesHornetBuilderInstalléDansNode}/bin/builder-cli.js hornetbuilder
Installer hornet-js-builder
de manière globale:
npm install -g
En cas de MAJ à partir d'une version antérieure de hornet-js-builder
: supprimer les dossiers node_modules
de chaque projet
Suite à cette installation, les commandes hornetbuilder
et hb
(alias de la première) sont accessibles en globale dans les scripts
Le builder organise les dépendances de manière "flat" et gère la transitivité des dépendances.
Il impose la déclaration de dépendance en version fixe (sans ^, ~ ou *) afin de pérenniser les versions.
Il impose également une structure du fichier `package.json légèrement différente de celle par défaut :
dependencies
doivent impérativement être définies dans la clé appDependencies
devDependencies
doivent impérativement être définies dans la clé buildDependencies
devDependencies
doivent impérativement être définies dans la clé testDependencies
Afin que les dépendances applicatives et les dépendances de construction/test ne rentrent pas en conflit, les dépendances sont installées dans deux répertoires différents à l'intérieur du répertoire node_modules
:
Pour que le serveur nodejs sache lire les dépendances dans ce nouveau répertoire node_modules/app
un fichier "bootstrap" nommé index.ts
permet de démarrer le serveur.
Lorsque le builder détecte par transitivité une dépendance dont la version n'est pas fixe (ex: ^3.0.0), il récupère la dernière version correspondante sur le repository courant et la fixe dans un objet ____HORNET-BUILDER____DO_NOT_MODIFY_THIS_OBJECT____
qui est sauvegardé à la fin du fichier package.json
.
Cet objet ne doit surtout pas être modifié manuellement !!
Exemple d'un fichier package.json
complet avec version fixée par le builder :
{
"name": "applitutoriel",
"version": "5.x.x",
"main": "index.js",
"description": "Application tutoriel utilisant le Framework hornet 5.x.x",
"tsDefinitionDependencies": {
...
},
"appDependencies": {
...
},
"buildDependencies": {
...
},
"testDependencies": {
...
},
"author": "MEAE - Ministère de l'Europe et des Affaires étrangères",
"____HORNET-BUILDER____DO_NOT_MODIFY_THIS_OBJECT____": {
"current": "b9265f7937e0a4a52491f52fe18fe26a537052e8",
"history": {
"b9265f7937e0a4a52491f52fe18fe26a537052e8": {
"version": "5.x.x",
"date": "2017-03-09T10:02:18.543Z",
"deps": {"amdefine":"X.X.X",...}
}
}
}
}
Exemple:
cd /home/user/Dev/workspace-js/applitutoriel-modules/
hornetbuilder
(ou hb
) suivi de la tâche à exécuter. Exemple:hb test
Une aide est fournie en tapant la commande
hb --help
Les options suivantes sont alors proposées:
Option | Rôle |
---|---|
-V, --version | Affiche la version du builder |
-d, --debug | Active les messages de logs du builder en mode debug |
-D, --docker [options]' | Exécute les commandes du Builder dans le container Docker nodeJS |
--show-webpack-files | Active le listing des fichiers embarqués par webpack lors de la construction du bundle de fichiers clients. Note: Les fichiers sont triés par taille croissante |
--webpackVisualizer | Visualisation de la répartition des sources projets et node modules dans un chart, /static/dev/webpack-visualizer.html |
-i, --ide | Indique que c'est l'IDE qui gère la compilation des fichiers .ts, .d.ts et .map. Dans ce mode la compilation des fichiers TypeScripts est désactivée ainsi que les watchers associés. De même, la tâche clean ne supprime plus ces fichiers. Cette option doit être utilisée dès lors qu'un IDE est lancé sur les projets |
-r, --registry | Permet d'utiliser un repository spécifique. Par défaut le repository défini dans le fichier .npmrc est utilisé |
--publish-registry | Permet de spécifier un repository npm spécifique pour la publication autre que celui par défaut. Par défaut le repository défini dans le fichier .npmrc est utilisé |
-f, --force | Permet de forcer la mise à jour des dépendances |
--ignoreApp | ne prend pas la version de dépendance applicative, mais la plus récente |
--skipTests | Permet de ne pas exécuter les tests si ceux-ci doivent être exécutés (ex: tâche package ) |
--stopOnError | Permet de stopper toutes les tâches sur une erreur dans les tests |
--skipMinified | Permet de ne pas minifier les chuncks |
--noWarn | Permet de ne pas afficher les warning |
-p, --debugPort | Indique le port utilisé par node pour permettre la connexion d'un debugger externe" |
--lintRules | Indique un fichier de rules tslint.json autre que celui utilisé par le builder |
--lintReport | Indique le format de sortie pour tslint : prose (défaut), json , verbose , full , msbuild |
--file | Indique le chemin d'un fichier |
--dev | active le mode developpement |
--offline | active le mode offline pour la récupération des dépendances, ex : coupure réseau. Prerequis avoir les node_modules, ajouter fetch-retries=0 dans .npmrc |
--versionFix | Indique la version ou suffixe si commence par '-', '.' ou si null calcule un suffixe avec timestamp. |
--versionSearch | préfixe de la dernière version" |
Le principe du mode interactive est d'être immergé dans les commandes du builder sans pour autant à avoir à retaper "hb ..." et de bénéficier d'un mode intuitif d'autocompletion.
hb
Résultat :
[17:08:30] Démarrage de hornet-js-builder dans /home/heurtes/Dev/workspace-vscode/applitutoriel-modules/applitutoriel-js-lite
[17:08:30] Builder lancé sur le projet applitutoriel-js-lite en version 5.2.0
[17:08:30] Utilisation du registry configuré dans NPM : http://artifactory.app.diplomatie.gouv.fr/artifactory-dev/api/npm/repository-npm-mae-dev
[17:08:31] Chargement des tâches du projet 'applitutoriel-js-lite'
[17:08:31] Auto resolving module externe 'applitutoriel-js-common@5.2.0 in '/home/heurtes/Dev/workspace-vscode/applitutoriel-modules/applitutoriel-js-common'
[17:08:31] Auto resolving module externe 'applitutoriel-js-common-dts@5.2.0 in '/home/heurtes/Dev/workspace-vscode/applitutoriel-modules/applitutoriel-js-common-dts'
[17:08:31] _Starting 'default'...
[17:08:31] __Starting 'interactive'...
[17:08:31] __Finished 'interactive' after 294 μs
[17:08:31] _Finished 'default' after 1.59 ms
hb$
le prompt "hb$" s'affiche et permet alors de lancer n'importe quelle commande du builder.
Il est possible de lister toutes les commandes avec un double "tab" ou bien d'utiliser l'aide
hb$ help
L'arrêt du mode interactive ce fait avec la commande "exit".
hb$ exit
package.json
cf : Principe de gestion des dépendances
Le package.json
diffère de la norme npm concernant l'ajout de dépendances ceci afin de gérer les dépendances fixes avec le builder.
dependencies
=> appDependencies
devDependencies
=> testDependencies
buildDependencies
{
"appDependencies": {
"hornet-js-components": "5.x.x"
...
},
"testDependencies": {
"hornet-js-test": "5.x.x"
...
},
"buildDependencies": {
"md-loader": "x.x.x"
...
}, ...
}
Afin de bénéficier de la compilation Typescript pour les modules d'un projet, il est possible de spécifier les fichiers de définition typescript spécifique au projet dans la section tsDefinitionDependencies
. Celles-ci sont automatiquement ajoutées au répertoire definition-ts
à la racine du projet.
Le projet peut également avoir ses propres fichiers de définition en plus de ceux proposés par le framework.
"tsDefinitionDependencies": {
"hornet-js-ts-typings": "5.x.x",
"hornet-js-utils-dts": "5.x.x",
"hornet-js-core-dts": "5.x.x"
...
}
package.json
{
"name": "applitutoriel",
"version": "5.x.x",
"main": "index.js",
"description": "Application tutoriel utilisant le Framework hornet 5.x.x",
"bugs": {
"url": "https://github.com/diplomatiegouvfr/applitutoriel-js/issues"
},
"repository": {
"type": "git",
"url": "git+https://github.com/diplomatiegouvfr/applitutoriel-js.git"
},
"tsDefinitionDependencies": {
"applitutoriel-js-common-dts": "5.x.x",
"hornet-js-ts-typings": "5.x.x",
"hornet-js-utils-dts": "5.x.x",
"hornet-js-core-dts": "5.x.x",
"hornet-js-components-dts": "5.x.x",
"hornet-js-react-components-dts": "5.1.",
"hornet-js-react-component-chart-dts": "5.x.x",
"hornet-js-passport-dts": "5.x.x",
"hornet-js-test-dts": "5.x.x"
},
"appDependencies": {
"hornet-js-bean": "5.x.x",
"hornet-js-components": "5.x.x",
"hornet-js-react-components": "5.x.x",
"hornet-js-react-component-chart": "5.x.x",
"hornet-js-core": "5.x.x",
"hornet-js-utils": "5.x.x",
"hornet-js-passport": "5.x.x",
"hornet-themes-intranet": "5.x.x",
"jsonwebtoken": "7.3.0",
"connect-flash": "0.1.1",
"passport": "0.2.1",
"passport-local": "1.0.0",
"sha1": "1.1.1"
},
"buildDependencies": {},
"testDependencies": {
"hornet-js-test": "5.x.x"
},
"author": "MEAE - Ministère de l'Europe et des Affaires étrangères",
"____HORNET-BUILDER____DO_NOT_MODIFY_THIS_OBJECT____": {
"current": "92f3196ce9c86b9708e3273152885f52e18443a3",
"history": {
"92f3196ce9c86b9708e3273152885f52e18443a3": {
"version": "5.x.x",
"date": "2017-03-09T13:23:55.506Z",
"deps": {"amdefine":"X.X.X", ...}
}
}
}
}
tsconfig.json
Les projets doivent impérativement avoir un fichier tsconfig.json
à la racine.
Celui-ci regroupe les informations de compilation typescript nécessaire au projet.
ex :
{
"compilerOptions": {
"target": "ES5",
"module": "commonjs",
"moduleResolution": "classic",
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"jsx": "react",
"sourceMap": true,
"noResolve": true,
"importHelpers": true,
"baseUrl": "./",
"paths": {
"tslib": [
"definition-ts/hornet-js-ts-typings/tslib/tslib.d.ts"
]
}
},
"include": [
"./**/*.ts*",
"./definition-ts/**/*.d.ts"
],
"exclude": [
"istanbul",
"node_modules",
"static"
]
}
builder.js
Les projets doivent comporter à la racine un fichier builder.js
afin de déterminer le type de l'application : application
, module
, ... ainsi que les différentes tâches à éxécuter nécessaires à la construction.
Ce fichier doit comporter au minimum le code suivant pour hornet.js
:
module.exports = {
type: "application",
authorizedPrerelease: "true",
gulpTasks: function (gulp, project, conf, helper) {
//Add task if needed
/*gulp.beforeTask("compile", function () {
helper.info("Exemple before compile task");
});
gulp.afterTask("compile", function () {
helper.info("Exemple after compile task");
});*/
// Cas PARTICULIER de l'application tuto pour pouvoir la générer en mode SPA et ISOMORPHIC sur la PIC
// => on force la tâche prepare-package:spa tout le temps
// si mode fullSpa : on redéfini les tâches 'watch' & 'watch-prod' pour y inclure la tâche "prepare-package-spa"
//gulp.task("watch", ["compile", "prepare-package:spa", "watch:client"]);
//gulp.task("watch-prod", ["compile", "prepare-package:spa", "watch:client-prod"]);
gulp.addTaskDependency("package-zip-static", "prepare-package:spa");
// conf.template.messages = require("applitutoriel-js-common/src/resources/messages.json")
conf.template.forEach((elt, idx) => {
if (conf.template[idx].context.forEach) {
conf.template[idx].context.forEach((elt, idx2) => {
conf.template[idx].context[idx2].messages = {"applicationTitle": "Application TUTORIEL"};
});
} else {
conf.template[idx].context.messages = {"applicationTitle": "Application TUTORIEL"};
}
});
},
externalModules: {
enabled: false,
directories: [
]
},
config: {
routesDirs: ["." + path.sep + "routes"],
// Exemple d'exclusion de fichiers/répertoires local à l'application et de modules
// Cet exemple n'est pas forcement cohérent puisque le client.js n'est pas dépendant des middlewares
// Il est là à titre d'exemple uniquement
clientExclude: {
dirs: [
path.join("src", "services", "data"),
"src/middleware",
"nodemailer",
"applitutoriel-js-common/src/actions"],
filters: [
path.join("src", "services", "data") + "/.*-data-\.*",
".*/src/actions/.*",
"^config/*"
],
modules: [
"config",
"continuation-local-storage",
"carbone",
"pdfmake",
"pdfmake/src/printer",
"pdfkit",
"nodemailer",
"fontkit"
]
},
clientContext: [
[/moment[\/\\]locale$/, /fr|en/],
[/intl[\/\\]locale-data[\/\\]jsonp$/, /fr|en/],
[/.appender/, /console/]
],
typescript: { //bin: "~/Dev/node-v4.5.0-linux-x64/lib/node_modules/typescript"
},
template: [
{
context: [{
error: "404",
suffixe: "_404",
message: "Oops! Nous ne trouvons pas ce que vous cherchez!"
}, {error: "500", suffixe: "_500", message: "Oops! Une erreur est survenue!"}],
dir: "./template/error",
dest: "/error"
}, {
context: {message: "test template"}
}
],
spaResources: [path.join("..", "applitutoriel-js-common", "src", "resources") + "**/*.json"],
dev: {
dllEntry: {vendor: ["ajv", "react-dom", "react", "bluebird", "moment", "intl", "moment-timezone", "lodash"]}
}
}
};
Ce fichier doit comporter au minimum le code suivant pour hornet.js-lite
:
module.exports = {
type: "application",
gulpTasks: function (gulp, project, conf, helper) {
helper.excludeNodeModulesFromWebpack(
["config", "continuation-local-storage", "sequelize", "pdfmake", "carbone", "csv-parser", "nodemailer"],
conf.webPackConfiguration
);
conf.template.forEach((elt, idx) => {
if (conf.template[idx].context.forEach) {
conf.template[idx].context.forEach((elt, idx2) => {
conf.template[idx].context[idx2].messages = {"applicationTitle": "Application TUTORIEL"};
});
} else {
conf.template[idx].context.messages = {"applicationTitle": "Application TUTORIEL"};
}
});
},
externalModules: {
enabled: false,
directories: [
]
},
config: {
routesDirs: ["." + path.sep + "routes"],
ressources: ["database/**/*"],
// Exemple d'exclusion de fichiers/répertoires local à l'application et de modules
// Cet exemple n'est pas forcement cohérent puisque le client.js n'est pas dépendant des middlewares
// Il est là à titre d'exemple uniquement
clientExclude: {
dirs: [
path.join("src", "services", "data"),
path.join("src", "dao"),
"src/middleware",
"nodemailer"],
filters: [
path.join("src", "services", "data") + "/.*-data-\.*"
],
modules: [
"hornet-js-database",
"config",
"continuation-local-storage",
"sequelize",
"pdfmake",
"carbone",
"csv-parser",
"nodemailer",
"tls"
]
},
clientContext: [
[/moment[\/\\]locale$/, /fr|en/],
[/intl[\/\\]locale-data[\/\\]jsonp$/, /fr|en/],
[/.appender/, /console/]
],
typescript: { //bin: "~/Dev/node-v4.5.0-linux-x64/lib/node_modules/typescript"
},
karma: {
template: {
debug: "./test/template/debug.html",
context: "./test/template/context.html",
clientContext: "./test/template/client_with_context.html"
}
},
template: [
{
context: [{error: "404", suffixe: "_404", message: "Oops! Nous ne trouvons pas ce que vous cherchez!"}, {error: "500", suffixe: "_500", message: "Oops! Une erreur est survenue!"}],
dir: "./template/error",
dest: "/error"
}, {
context: {message: "test template"}
}
]
dev: {
dllEntry: {vendor: ["hornet-js-react-components", "hornet-js-components", "hornet-js-utils"]}//"ajv", "d3", "react-dom", "react", "bluebird", "moment", "intl", "moment-timezone", "lodash"
}
}
};
type
indique au builder le type de projet actuel. Pour une application le type doit toujours être application
(types possibles : "parent", "application", "application-server", "module", "theme", "custom", "composant").gulpTasks
permet :
gulp
gulp.beforeTask(taskName, func)
et gulp.afterTask(taskName, func)
gulp.addTaskDependency(taskName, dependencyTaskName)
externalModules
permet de déclarer des dépendances à partir de répertoires externesconfig
permet de surcharger la configuration du builder dans chaque application
autoGenerateIndex
permet d'autogénérer des index.js
, index.ts
et index.d.ts
(utile pour le mode dev et dll, ou l'import auto des dts)routesDirs
permet de spécifier les répertoires des routes pour le code splitting automatiqueclientExclude
est un raccourci pour modifier la conf webpack et rajouter des externalsclientNoParse
est un raccourci pour modifier la conf webpack et rajouter des module.noParsetypescript.bin
permet de préciser une autre version de typescript pour la transpilation que celle utiliser ambarquée par le builderwebpack
permet de configurer WebPack pour des projet ayant besoin de loader particulier...karma
permet de configurer karma (autre navigateur...)spaResources
liste de filtres permettant d'ajouter des ressources pour la génération de chunck SPAdllEntry
permet de préciser des dll webpack (gain de temps de construction des chunck)template
permet de configurer la tâche de templating html
dir
répertoire des templates (par défault 'template')context
objet disponible pour le templatingdest
répertoire de destinationclientContext
Filtre les modules ex moment et intl : [/moment[/\]locale$/, /fr|en/], [intl[/\]locale-data[/\]jsonp$/, /fr|en/]spaFilter
Filtre les ressources pour le packaging spa, copie des fichiers ressource dans /staticdev
Expérimentation du builder
dllEntry
optimisation de chargement des librairies en devcontext
contiendra par défaut :
{
project:
{
name: project.name,
version: project.version,
static: "static-" + project.version + "/"
}
}
Exemple:
...
gulpTasks: function (gulp, project, conf, helper) {
gulp.task("maNouvelleTache", function(done) {
helper.info("Execution de 'maNouvelleTache'");
done();
});
},
...
hb maNouvelleTache
La configuration par défaut du builder est la suivante:
const testReportDir = "test_report";
const testWorkDir = "istanbul";
const defaultConf = {
src: "src",
test: "test",
static: "static",
js: "js",
config: "./config",
generatedTypings: {
dir: ".",
file: "definition.d.ts"
},
clientJs: "client.js",
routesDirs: ["." + path.sep + "routes"],
componentsDirs: [path.join("..", "src")],
buildWorkDir: "target",
testReportDir: testReportDir,
testWorkDir: testWorkDir,
templateDir: "html",
mocha: {
reporter: process.env.NODE_ENV === "integration" ? "xunit" : "spec",
reporterOptions: {
output: "test-results.xml"
}
//,"grep": "Router constructor"
},
istanbul: {
dir: path.join(testWorkDir, "coverage"),
reporters: ["lcov", "text", "text-summary", "cobertura", "json", "html"],
reportOpts: {
dir: path.join(testReportDir, "mocha"),
lcov: {dir: path.join(testReportDir, "mocha", "lcov"), file: "lcov.info"},
html: {dir: path.join(testReportDir, "mocha", "html")},
json: {dir: path.join(testReportDir, "mocha"), file: "coverage_mocha.json"},
cobertura: {dir: path.join(testReportDir, "mocha")}
}
},
karma: {
reporters: ["mocha", "coverage"],
reportOpts: {
dir: path.join(testReportDir, "karma"),
lcov: {dir: path.join(testReportDir, "karma", "lcov"), file: "lcov.info"},
html: {dir: path.join(testReportDir, "karma", "html")},
json: {dir: path.join(testReportDir, "karma"), file: "converage_karma.json"}
}
},merge: {
reporters: ["lcov", "text", "text-summary", "cobertura", "json", "html"],
reportOpts: {
dir: path.join(testReportDir, "merge"),
lcov: {dir: path.join(testReportDir, "merge", "lcov"), file: "lcov.info"},
html: {dir: path.join(testReportDir, "merge", "html")},
json: {dir: path.join(testReportDir, "merge"), file: "coverage_mocha.json"},
cobertura: {dir: path.join(testReportDir, "merge")}
}
},
istanbulOpt: {
includeUntested: true
},
webPackConfiguration: {
module: {}
},
webPackMinChunks: 3,
template: {
context: {}
}
hornetbuilder
fournit les tâches suivantes afin de gérer les dépendances d'un projet :
Tâche | Rôle | Dépendances |
---|---|---|
dependencies:clean | supprime les dépendances applicatives (répertoire node_modules/app) | |
dependencies:clean-build | supprime les dépendances de construction/test (répertoire node_modules/buildntest) | |
dependencies:clean-all | supprime toutes les dépendances | |
dependencies:clean-fix | supprime toutes les dépendances fixées, à utiliser avec l'option -f | |
dependencies:check-app | vérifie la conformité des versions des dépendances applicatives déclarées | |
dependencies:check-ts-definition | vérifie la conformité des versions des fichiers de définition Typescript | |
dependencies:change-app | vérifie si les dépendances applicatives ont été modifiées | dependencies:check-app |
dependencies:fix-app | Calcule l'arbre de dépendances applicatives et fixe les versions des dépendances transitives déclarées avec un ^, ~ ou *. Si plusieurs versions la plus récente est prise sauf si elle est fixée dans les depenances applicatives. | dependencies:change-app |
dependencies:install-ts-definition | Installe les fichiers de définition | dependencies:check-ts-definition |
dependencies:install-app | Installe les dépendances applicatives | dependencies:fix-app |
dependencies:install-app-themes | Installe les dépendances applicatives de type theme dans les staic de l'application | dependencies:fix-app |
dependencies:install-test | Installe les dépendances de test | |
dependencies:install | Installe les dépendances applicatives et les fichiers de définitions | dependencies:install-ts-definition et dependencies:install-app |
install | Alias de "dependencies:install" | dependencies:install |
versions:set | permet de changer la version du projet | |
dependency:set | permet de changer la version d'un module de dépendance du projet |
hornetbuilder
fournit les tâches suivantes afin de compiler les sources d'un projet :
Tâche | Rôle | Dépendances |
---|---|---|
compile:ts | Transpile les sources TS en Javascript. S'exécute uniquement si l'option "-i" (--ide) n'est pas utilisée. | clean |
compile | Transpile les sources TS en Javascript. Cette tâche exécutera un dependencies:install en plus de la tâche clean de la commande compile:ts | dependencies:install compile:ts |
hornetbuilder
fournit les tâches suivantes afin d'exécuter les tests d'un projet :
Tâche | Rôle | Dépendances |
---|---|---|
prepare:testSources | Copie les sources originales et compilées dans le répertoire de travail des tests : istanbul | compile |
test:instrument | Défini les instruments de couverture de code sur les sources | prepare:testSources |
test | Exécute les tests unitaires et la mesure de couverture de code | dependencies:install test:instrument |
test:karma | Exécute les tests basées sur KarmaJs | dependencies:install compile |
test:mocha | Exécute les tests basées sur MochaJs | dependencies:install compile |
test:merge-reports | Merge des rapports de test Mocha/Karma | clean-test:merge |
test:remap-reports | Remap des rapports mergés sur les sources TypeScript | clean-test:remap |
hornetbuilder
fournit les tâches suivantes afin de nettoyer un projet :
Tâche | Rôle | Répertoire/fichier | Dépendances |
---|---|---|---|
clean | Supprime les fichiers générés (.js, .map et .d.ts dans le dossier de sources) | "clean:src", "clean:test" | |
clean:build | Supprime le répertoire de build | ./target | |
clean:test | Supprime le dossier istanbul ainsi que les fichiers générés (.js, .map et .d.ts dans le dossier de tests) | test, test_report, karma_html | |
clean:static | Supprime les fichiers statics générés par webpack | ./static/js | |
clean:static-dll | Supprime les fichiers dll statics générés par webpack | ./static/js/dll | |
clean:static-all | Supprime les fichiers dll statics générés par webpack + les dll | ./static/js/dll/* | |
clean:theme | Supprime le thème de l'application dans le répêrtoire static | ./static/themeName | |
clean:src | Supprime les fichiers généré dans le répertoire source ./src | extended/.js", "**/.json", "**/*.jsx | |
clean:template | Supprime les templates générées dans la partie static | ./static/templateDir | |
clean-all | Supprime tous les fichiers et dépendances | "clean", "clean:build", "dependencies:clean-all", "clean:static", "clean:template" |
hornetbuilder
fournit les tâches suivantes afin de construire les livrables d'un projet :
Tâche | Rôle | Dépendances |
---|---|---|
prepare-package-dll | Lance WebPack pour la construction des dll's js client | |
prepare-package | Lance WebPack pour la construction du js client en mode production et copie les livrables dans le répertoire target | prepare-package:minified, prepare-all-package |
prepare-package:dev | Lance WebPack pour la construction du js client en mode debug et copie les livrables dans le répertoire target | prepare-package:minified, prepare-all-package |
prepare-package:minified | Lance WebPack avec la minification pour la construction du js client, mode Production par défaut | |
prepare-package-spa | Prépare les fichiers à packager pour un projet en FullSpa mode Production | |
prepare-package-spa:dev | Prépare les fichiers à packager pour un projet en FullSpa mode Dev | |
prepare-all-package | copie les livrables dans le répertoire target | |
template-html | Lance le templating html | |
zip-static | Construit le livrable statique (zip) | |
zip-dynamic | Construit le livrable dynamique (zip) | |
zip-environment | Construit le livrable environment (zip) | |
zip-database | Construit le livrable database (zip) | |
package-zip-static | Construit le livrable statique (zip) | prepare-package-client:minified, zip-static |
package-zip-dynamic | Construit le livrable dynamique (zip) | prepare-package-client:minified, zip-dynamic |
package-zip-static:dev | Construit le livrable statique (zip) | prepare-package-client:dev, zip-static |
package-zip-dynamic:dev | Construit le livrable dynamique (zip) | prepare-package-client:dev, zip-dynamic |
package | Package global de l'application en mode Production | compile, test, template-html, prepare-package, zip-static, zip-dynamic, zip-environment, zip, database |
package:dev | Package global de l'application en mode Dev | compile, test, template-html, prepare-package:dev, zip-static, zip-dynamic, zip-environment, zip, database |
package-spa | Package SPA de l'application en mode Production | compile, test, template-html, prepare-package-spa, zip-static, zip-dynamic, zip-environment, zip, database |
package-spa:dev | Package SPA de l'application en mode Dev | compile, test, template-html, prepare-package-spa:dev, zip-static, zip-dynamic, zip-environment, zip, database |
hornetbuilder
fournit les tâches suivantes afin d'outiller le démarrage d'une application en développement
Tâche | Rôle | Dépendances |
---|---|---|
watch:ts | Ecoute les modifications sur les fichiers TS et les recompile à la volée. S'exécute uniquement si l'option "-i" (--ide) n'est pas utilisée | |
watch:serveur | Ecoute les modifications sur les fichiers et redémarre le serveur node pour les prendre en compte. Démarre nodejs en mode development | watch:ts |
watch:serveur-prod | Equivalent à watch:serveur mais avec nodejs en mode production | watch:ts |
watch:client | Ecoute les modifications sur les fichiers et relance WebPack à la volée. Lance WebPack en mode development. | watch:ts |
watch:client-prod | Equivalent à watch:client mais avec WebPack en mode production | watch:ts |
watch | Compile et écoute les modifications pour redémarrer nodejs et relancer WebPack si besoin. mode : development | compile watch:client watch:serveur |
watch-prod | Compile et écoute les modifications pour redémarrer nodejs et relancer WebPack si besoin. mode : production | compile watch:client-prod watch:serveur-prod |
w | Alias de "watch" | watch |
wp | Alias de "watch-prod" | watch-prod |
hornetbuilder
fournit les tâches suivantes afin de construire des rapports de qualimétrie :
Tâche | Rôle | Dépendances |
---|---|---|
lint | Lance le tslint sur les sources ts (qualité de code) |
hb lint
hb lint --lintReport json
Lors de la première utilisation du builder et peu importe la commande, le builder va installer les dépendances de construction/test afin que celles-ci soient disponibles dans le fichier builder.js
. Cela permet d'ajouter à un projet des tâches de construction dépendantes de modules non fournies par le framework. Il sera ainsi possible d'écrire dans le fichier builder.js
:
var maDependanceSpecifique = require("maDependanceSpecifique");
Dès la première utilisation du builder sur un projet, il est possible d'utiliser la commande :
hb watch
Dans un ide qui compile automatiquement les fichiers typescript, il est recommandé d'utiliser l'option -i
hb watch -i
ou bien :
hb w -i
Les dépendances entre les tâches du builder font que l'arbre des dépendances applicatives va être calculé, que les versions non fixées vont l'être, que l'ensemble des dépendances vont s'installer, que les sources vont se compiler, que le serveur nodejs va démarrer et que les modifications des fichiers seront écoutées.
Il est néanmoins possible de lancer indépendemment les différentes tâches :
hb dependencies:install
hb compile
hb watch
hb test
Exécute les tests et fournit sur la console :
Les fichiers exécutés doivent se trouver dans le répertoire ./test et se nommer *-spec.js sachant que la phase de compile passe avant.
hb test:karma
hb test:karma --file ./test/page/test.karma.js
Le test à exécuter est donné par le paramètre -file ou si aucun n'est précisé, il prend la configuration karma et par défaut c'est tests.webpack.js. Ce dernier référence tous les tests à exécuter grace à require, exemple qui tire tous les fichiers *.karma.js dans le répertoire test:
var context = require.context('./test', true, /\.karma\.js$/);
context.keys().forEach(context);
Les rapports sont générés dans le répertoire ./test_report
Le navigateur utilisé par défaut est Firefox. Pour en ajouter ou en utiliser un autre, il faut surcharger la configuration dans le fichier builder.js, exemple :
config : {
....
..
karma: {
browsers: ["Chrome", "Firefox"],
}
}
Par défaut, lorsque les tests sont ouverts dans un navigateur, aucune feuille de style hornet n'est chargée. Il est possible de surcharger les templates karma:
config : {
....
..
karma: {
template: {
debug: "./test/template/debug.html",
context: "./test/template/context.html",
clientContext: "./test/template/client_with_context.html"
}
}
}
les templates fournis nécessitent de démarrer un serveur de thèmes.
hb template-html
Lance le templating basé sur EJS et écrit les fichiers dans 'static/html' du projet.
Si l'objet de configuration template est un tableau, il lancera autant de templating que d'éléments dans le tableau, exemple :
template: [
{
context: [{error: "404", suffixe: "_404", message: "Oops! Nous ne trouvons pas ce que vous cherchez!"}, {error: "500", suffixe: "_500", message: "Oops! Une erreur est survenue!"}],
dir: "./template/error",
dest: "/error"
}, {
context: {message: "test template"}
}
]
Dans cet exemple, le templating suivant est lancé :
hb package
Construit les différents livrables et les place dans le répertoire target
à la racine du projet.
hb publish --publish-registry <URL>
Publie le module sur un repository spécifique.
hb versions:set --versionFix=1.2.3
Modifie la version du projet ou des projets si on est sur un type parent en '1.2.3'.
hb versions:set --versionFix=
Modifie la version du projet en suffixant par un timestamp 'YYYYMMDDHHmmss'.
hb versions:set --versionFix=\'-123\'
Modifie la version du projet en suffixant par '-123', il faut echapper les caractères `.
hb dependency:set --versionFix=1.2.3 --dependencyVersionFix=monpackage
Reprend les principes de versions:set
mais sur les dépendances d'un projet.
hb dependency:set-snapshot --dependencyVersionFix=monpackage --module=monpackage
hb versions:get --versionSearch=5.0.2 --module=hornet-js-core
Retourne la dernière version commencant par 5.0.2 du module hornet-js-core, exemple : 5.0.2-20180109183247. Si le module n'est pas renseigné, c'est sur le projet lui-même que la recherche est faite, et si versionSearch
n'est pas renseigné c'est la dernière version qui est retournée (sans contrainte de préfixe)
hb versions:get --versionSearch=snapshot --module=hornet-js-core
Permet d'avoir la dernière version snapshot d'un module présent dans les dépendances du projet (appDependencies, buildDependencies, ...).
Il est possible de requêter via le builder une instance de postgresql.
Tâche | Rôle | Dépendances |
---|---|---|
pg | lance une commande postgres |
hb pg -q "select * from table"
Par défaut, c'est la clé "database.config.uri" d'un projet Hornet qui est pris comme uri de connexion. Il est possible de spécifier celle-ci via l'option "-uri".
hb pg -q "select * from table" --uri "postgres://applitutorieljs_dvlt_00_usr:pwd_usr@localhost:5432/applitutorieljs_dvlt_00"
2 modes sont possibles:
builder.js
composant
une configuration par défaut est déclarée au niveau de hornet-js-builder
:
sassConfiguration: {
sass: {
merge: true,
inputFilter: "./src/**/*.scss",
options: {
outputStyle: process.env.NODE_ENV !== "production" ? "expanded": "compressed",
data: ""
},
output: {
dir: path.join(staticDir, "css"),
fileName: process.env.NODE_ENV !== "production" ? "appli.css": "appli.min.css"
}
},
img: {
inputFilter: "./img/**/*.+(jpeg|jpg|png|gif|svg|ttf)",
output: {
dir: path.join(staticDir, "img")
},
template: path.join(__dirname, "..", "builders", "tasks", "sass", "sass-image-template.mustache")
}
}
Il est possible de surcharger cette configuration via le builder.js
tel que:
conf : {
sassConfiguration: {
sass: {
inputFilter: "src/**/sources/*.scss",
},
img: {
inputFilter: "src/**/sources/*.+(jpeg|jpg|png|gif|svg)",
}
}
}
....
2 tâches sont prévues pour manipuler des fichiers SCSS:
hb process:sass
Cette tâche permet de générer un fichier CSS (par défaut, le fichier sera ./static/css/generated.css
comme indiqué dans la conf.)
hb watch:sass
Cette tâche permet de générer un fichier CSS puis de watcher les modifications des fichiers SCSS pour re-générer au besoin le fichier CSS.
Par défaut, cette tâche est rattachée à la tâche de watch:client
.
Si l'application est démarée via la commande hb w
, la tâche watch:sass
sera donc exécutée et n'importe quelle modification de fichier .scss
entrainera une génération des nouveaux .css
et un redémarrage du nodemon.
Les tâches liées à SASS reposent sur la librairie gulp-sass-image
laquelle génère par défaut un fichier ./static/css/_sass-image.scss
. Ce dernier contient des méthods utiles afin de manipuler les images (cf. ). Ce fichier généré repose sur un template
mustache
qui'il est possible de surcharger.
Il est également possible de générer des fichiers CSS à partir de fichiers SCSS en important ces derniers directement dans les composants React.
import * as React from "react";
import { Utils } from "hornet-js-utils";
if(!Utils.isServer) {
require("path/vers/Scss/File.scss");
}
export class MyComponent extends HornetComponent<MyComponentProps, MyComponentState> {
...
}
La déclaration d'un simple require
dans un composant .tsx
en le protégeant d'un !Utils.isServer
permettra à sass-loader
de générer le fichier CSS associé
hornet-js-builder
est sous licence cecill 2.1.
FAQs
Builder/loader des Applications Hornet, Wrapper NPM permettant de fixer les versions des dépendances
The npm package hornet-js-builder receives a total of 0 weekly downloads. As such, hornet-js-builder popularity was classified as not popular.
We found that hornet-js-builder demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 3 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
The Socket Research Team has discovered six new malicious npm packages linked to North Korea’s Lazarus Group, designed to steal credentials and deploy backdoors.
Security News
Socket CEO Feross Aboukhadijeh discusses the open web, open source security, and how Socket tackles software supply chain attacks on The Pair Program podcast.
Security News
Opengrep continues building momentum with the alpha release of its Playground tool, demonstrating the project's rapid evolution just two months after its initial launch.