Je n'aime pas les solutions proposées ici (y compris celle que j'ai donnée précédemment) et voici pourquoi :
- Le problème avec la réponse la plus votée est que vous devez synchroniser manuellement la liste des balises script lorsque vous ajoutez/renommez/supprimez un fichier JS.
- Le problème avec la réponse acceptée est que votre liste de fichiers JS ne peut pas avoir de correspondance de motifs. Cela signifie que vous devez la mettre à jour à la main dans le fichier Grunt.
J'ai trouvé comment résoudre ces deux problèmes. J'ai configuré ma tâche grunt de sorte que chaque fois qu'un fichier est ajouté ou supprimé, les balises script sont automatiquement générées pour refléter cela. De cette façon, vous n'avez pas besoin de modifier votre fichier html ou votre fichier grunt lorsque vous ajoutez/supprimez/renommez vos fichiers JS.
Pour résumer comment cela fonctionne, j'ai un modèle html avec une variable pour les balises script. J'utilise https://github.com/alanshaw/grunt-include-replace pour remplir cette variable. En mode dev, cette variable provient d'un modèle de globbing de tous mes fichiers JS. La tâche de veille recalcule cette valeur lorsqu'un fichier JS est ajouté ou supprimé.
Maintenant, pour obtenir des résultats différents en mode dev ou prod, il suffit de remplir cette variable avec une valeur différente. Voici un peu de code :
var jsSrcFileArray = [
'src/main/scripts/app/js/Constants.js',
'src/main/scripts/app/js/Random.js',
'src/main/scripts/app/js/Vector.js',
'src/main/scripts/app/js/scripts.js',
'src/main/scripts/app/js/StatsData.js',
'src/main/scripts/app/js/Dialog.js',
'src/main/scripts/app/**/*.js',
'!src/main/scripts/app/js/AuditingReport.js'
];
var jsScriptTags = function (srcPattern, destPath) {
if (srcPattern === undefined) {
throw new Error("srcPattern undefined");
}
if (destPath === undefined) {
throw new Error("destPath undefined");
}
return grunt.util._.reduce(
grunt.file.expandMapping(srcPattern, destPath, {
filter: 'isFile',
flatten: true,
expand: true,
cwd: '.'
}),
function (sum, file) {
return sum + '\n<script src="' + file.dest + '" type="text/javascript"></script>';
},
''
);
};
...
grunt.initConfig({
includereplace: {
dev: {
options: {
globals: {
scriptsTags: '<%= jsScriptTags(jsSrcFileArray, "../../main/scripts/app/js")%>'
}
},
src: [
'src/**/html-template.html'
],
dest: 'src/main/generated/',
flatten: true,
cwd: '.',
expand: true
},
prod: {
options: {
globals: {
scriptsTags: '<script src="app.min.js" type="text/javascript"></script>'
}
},
src: [
'src/**/html-template.html'
],
dest: 'src/main/generatedprod/',
flatten: true,
cwd: '.',
expand: true
}
...
jsScriptTags: jsScriptTags
jsSrcFileArray
est votre modèle typique de grunt file-globbing. jsScriptTags
prend le jsSrcFileArray
et les concatène avec script
des étiquettes des deux côtés. destPath
est le préfixe que je veux sur chaque fichier.
Et voici à quoi ressemble le HTML :
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
<title>Example</title>
</head>
<body>
@@scriptsTags
</body>
</html>
Maintenant, comme vous pouvez le voir dans la configuration, je génère la valeur de cette variable sous forme d'une valeur codée en dur. script
lorsqu'il est exécuté dans prod
mode. En mode dev, cette variable se développera en une valeur comme celle-ci :
<script src="../../main/scripts/app/js/Constants.js" type="text/javascript"></script>
<script src="../../main/scripts/app/js/Random.js" type="text/javascript"></script>
<script src="../../main/scripts/app/js/Vector.js" type="text/javascript"></script>
<script src="../../main/scripts/app/js/StatsData.js" type="text/javascript"></script>
<script src="../../main/scripts/app/js/Dialog.js" type="text/javascript"></script>
Faites-moi savoir si vous avez des questions.
PS : C'est une quantité folle de code pour quelque chose que je voudrais faire dans chaque application JS côté client. J'espère que quelqu'un pourra transformer cela en un plugin réutilisable. Peut-être que je le ferai un jour.