I am using standard minify/uglify for css/js files and combine multiple files to main.min.css or app.min.js... However my .html file needs to be modified to point to these new file names too in <link>
or <script>
Is there a way to automate this? Or how to modify .html files automatically to rename the file names in there using gruntjs
?
You can do this with grunt-string-replace. Here's an example on how you could use it.
In my index.html you find the following import tags:
<!--start PROD imports
<script src="assets/dist/traffic.min.js"></script>
end PROD imports-->
<!--start DEV imports-->
<script src="assets/js/app.js"></script>
<script src="assets/js/services.js"></script>
<script src="assets/js/directives.js"></script>
<script src="assets/js/filters.js"></script>
<script src="assets/js/resources.js"></script>
<script src="assets/js/controller/homeControllers.js"></script>
<script src="assets/js/controller/adminControllers.js"></script>
<script src="assets/js/controller/reportsControllers.js"></script>
<!--end DEV imports-->
Notice the 'start imports' and 'end imports' comments. By default (in DEV) we comment out the PROD import.
In my grunt file I then add the following task:
'string-replace': {
inline: {
files: {
'index.html': 'index.html'
},
options: {
replacements: [
{
pattern: '<!--start PROD imports',
replacement: '<!--start PROD imports-->'
},
{
pattern: 'end PROD imports-->',
replacement: '<!--end PROD imports-->'
},
{
pattern: '<!--start DEV imports-->',
replacement: '<!--start DEV imports'
},
{
pattern: '<!--end DEV imports-->',
replacement: 'end DEV imports-->'
}
]
}
}
}
Running the task (grunt string-replace) gives me:
<!--start PROD imports-->
<script src="assets/dist/traffic.min.js"></script>
<!--end PROD imports-->
<!--start DEV imports
<script src="assets/js/app.js"></script>
<script src="assets/js/services.js"></script>
<script src="assets/js/directives.js"></script>
<script src="assets/js/filters.js"></script>
<script src="assets/js/resources.js"></script>
<script src="assets/js/controller/homeControllers.js"></script>
<script src="assets/js/controller/adminControllers.js"></script>
<script src="assets/js/controller/reportsControllers.js"></script>
end DEV imports-->
Now the DEV imports have been commented out, while the PROD import is no longer commented out.
This is easily automated with grunt-processhtml. Here's an example from the docs:
<!-- build:js app.min.js -->
<script src="my/lib/path/lib.js"></script>
<script src="my/deep/development/path/script.js"></script>
<!-- /build -->
<!-- changed to -->
<script src="app.min.js"></script>
Read more at https://www.npmjs.org/package/grunt-processhtml
A very suitable grunt task for this is grunt-html-build
It can substitute some some parts of the HTML from dev to a production version. See examples there, it is easy to setup.
Now, using the standard configuration presented for grunt-html-build, if minified files are dynamically named during build process like:
some-file.js
-> another-name.min.js
One can configure grunt-html-build with:
[...]
scripts: {
bundle: [
'<%= fixturesPath %>/scripts/*.min.js'
]
},
[...]
A HTML section like:
<!-- build:script bundle -->
<script type="text/javascript" src="/path/to/js/libs/jquery.js"></script>
<script type="text/javascript" src="/path/to/js/libs/knockout.js"></script>
<script type="text/javascript" src="/path/to/js/libs/underscore.js"></script>
<script type="text/javascript" src="/path/to/js/app/module1.js"></script>
<script type="text/javascript" src="/path/to/js/app/module2.js"></script>
<!-- /build -->
Would yield to something like:
<script type="text/javascript" src="scripts/other-name.min.js"></script>
<script type="text/javascript" src="scripts/another-other-name.min.js"></script>
That is what @hyprstack is asking for in comments.
You could use grunt preprocess to do this: https://github.com/jsoverson/grunt-preprocess
Basically, you need to set up a template and have preprocess replace the relevant parts.
The Gruntfile part will look something like this:
preprocess: {
dev: {
options: {
context: {
DEBUG: true,
HOST: '<%= env.dev.HOST %>'
}
},
files: {
'index.html': 'tpl/index.tpl'
}
},
production: {
options: {
context: {
DEBUG: false,
HOST: '<%= env.production.HOST %>
}
},
files: {
'index.html': 'tpl/index.tpl'
}
}
},
I am using Middleman App do distinguish between dev vs build in my html or haml file:
- if development?
and
- if build?