Nie podoba mi się tutaj rozwiązania (w tym te, które wcześniej podałem ) i oto dlaczego:
- Problem z najwyższą głosowaną odpowiedzią polega na tym, że musisz ręcznie zsynchronizować listę znaczników skryptu podczas dodawania / zmiany nazwy / usuwania pliku JS.
- Problem z zaakceptowaną odpowiedzią polega na tym, że na liście plików JS nie można dopasować wzorca. Oznacza to, że musisz zaktualizować go ręcznie w Gruntfile.
Zrozumiałem, jak rozwiązać oba te problemy. Skonfigurowałem moje zadanie karczowania, aby za każdym razem, gdy plik był dodawany lub usuwany, tagi skryptów były automatycznie generowane, aby to odzwierciedlić. W ten sposób nie musisz modyfikować pliku html ani chrząkać podczas dodawania / usuwania / zmiany nazw plików JS.
Podsumowując, jak to działa, mam szablon HTML ze zmienną dla znaczników skryptu. Korzystam z https://github.com/alanshaw/grunt-include-replace do wypełnienia tej zmiennej. W trybie deweloperskim ta zmienna pochodzi ze wzoru globowania wszystkich moich plików JS. Zadanie oglądania ponownie oblicza tę wartość, gdy plik JS jest dodawany lub usuwany.
Teraz, aby uzyskać różne wyniki w trybie deweloperskim lub produkcyjnym, wystarczy wypełnić tę zmienną inną wartością. Oto kod:
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
to Twój typowy wzorzec globowania plików. jsScriptTags
pobiera jsSrcFileArray
i łączy je razem z script
tagami po obu stronach. destPath
to prefiks, który chcę w każdym pliku.
A oto jak wygląda HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
<title>Example</title>
</head>
<body>
@@scriptsTags
</body>
</html>
Teraz, jak widać w konfiguracji, generuję wartość tej zmiennej jako script
tag zakodowany na stałe, gdy jest ona uruchomiona w prod
trybie. W trybie deweloperskim zmienna ta rozwija się do wartości takiej jak ta:
<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>
Daj mi znać, jeśli masz jakieś pytania.
PS: To szalona ilość kodu do czegoś, co chciałbym zrobić w każdej aplikacji JS po stronie klienta. Mam nadzieję, że ktoś może to zmienić we wtyczkę wielokrotnego użytku. Może kiedyś to zrobię.