I'm trying to remove my live reload script from my index.html file dynamically using Grunt's copy plugin.
The part of my Gruntfile with the code in question is here:
copy: {
main: {
files: [
{
expand: true,
src: 'index.html',
dest: 'build/',
options: {
process: function (content, srcpath){
return content.replace(/<script src = "http:\/\/localhost:9090\/livereload.js"><\/script>/g, " ");
}
}
},
I checked a regex tester and it showed that the regular expression I have above should match the script in my html.
Although the regex tester says it is legit, I have had inaccurate results with matches before, so I need help here in determining if there is a problem with my Gruntfile, or with my regular expression. Any suggestions?
your options are in the wrong place, they need to be one level higher:
copy: {
main: {
files: [
{
expand: true,
src: 'index.html',
dest: 'build/'
},
options: {
process: function (content, srcpath){
return content.replace(/<script src = "http:\/\/localhost:9090\/livereload.js"><\/script>/g, " ");
}
}
Related
I've just started using babel with grunt-babel in my application. But I encounter some behavior I want to avoid:
Before babel:
(function() {
'use strict';
angular
.module('app')
.controller('Ctrl', Ctrl);
Ctrl.$inject = ['$stateParams'];
function Ctrl($stateParams) {
}
})();
After babel:
(function () {
'use strict';
angular.module('app.standingOrder').controller('Ctrl', Ctrl);
Ctrl.$inject = ['$stateParams'];
function Ctrl($stateParams) {}
})();
My grunt task looks like this:
babel: {
options: {
sourceMap: false,
blacklist: ['strict']
},
dist: {
files: [
{
src: [ 'src/**/*.js' ],
cwd: '<%= build_dir %>',
dest: '<%= build_dir %>',
expand: true
}
]
}
},
Note that babel removed blank lines, added/removed spaces that breaks previous formatting.
Is there any way to avoid this and keep my formatting?
The retainLines option will attempt to preserve your line numbers. https://babeljs.io/docs/usage/options/
I think source maps are probably the best option, though they require a bit more work to manage.
You can use the repl to see what babel's gonna do https://babeljs.io/repl/
My middleman template has an 'id' variable that I put my html emails job name into.
I know if I change my middleman erb file from index.html.erb to newName.html.erb it will output that as the final files name.
My problem is that most of my grunt tasks require the file name I want them to run on (I've tried using *.html, but it only works for some tasks) and short of editing that in the grunt file prior to starting grunt up they won't execute if I change the erb file name.
Is there a way to pass grunt that 'id' variable to name the file middleman is outputting and also plug that variable into the various tasks so they too accept that as what the filename?
Here is my grunt config:
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
// Build html
middleman: {
options: {
useBundle: true
},
server: {},
build: {
options: {
command: "build"
}
}
},
// Format html file
prettify: {
options: {
// Task-specific options go here.
},
one: {
src: 'build/index.html',
dest: '_output/index.html'
}
},
// Run the text converter
execute: {
simple_target_with_args: {
options: {
// execute node with additional arguments
args: ['_output/index.html']
},
src: ['node_modules/node-text-converter/converter.js']
}
},
'special-html': {
compile: {
files: {
'_output/index.html': '_output/index.html',
}
}
},
'phantomjs_screenshot': {
main: {
options: {
delay: 1000
},
files: [{
expand: true,
cwd: '_output',
src: ['**/*.html'],
dest: '_output/screenshots/',
ext: '.jpg'
}]
}
}
});
You should store your variable in a JSON file and import it both into Middleman and Grunt.
I'm working on a grunt file for work. We work locally with our files being in html and when we implement them into our CMS they need to be converted to aspx.
I'm trying to replace all instances of <script scr=""></script> with <imod:ScriptPlaceHolder id="#nameOfFile" runat="server" type="FileInclude" url="#pathToFile"></imod:ScriptPlaceHolder>
I'm using "grunt-replace": "^0.8.0." This task is registered under default and build. I've tried using a regex to match the name, and I've been looking at the documentation for far too long. Here is what my grunt file with replace looks like:
replace: {
dist: {
options: {
patterns: [
{
match: '/script src="/g',
replacement: function() {
'asp:PlaceHolder runat="server" url="';
}
}
]
},
files: [
{expand: true, flatten: true, src: ['<%= config.dist %>/index.html'], dest: 'dist/'}
]
}
},
you don't mention the result you're currently getting so i assume you're seeing the script tag simply truncated or "undefined" prepended to the remaining bit of script tag.
I find http://www.regexr.com/ useful for testing regexes.
try changing your match to - '/<script\ssrc=".+</script>/g'
also, your replacement function needs to return a value. obviously if you're replacing with a static string then you can use a string for the argument instead.
With some help from Matthew Kime, I was able to get this working. In my regex I had to search for 2 periods because I'm using grunt-rev to version my files. I also used the file name stripped of it's extension to name the files dynamically.
Here is the conclusion I was able to arrive at.
// replace script tags to imod placeholders
replace: {
dist: {
options: {
patterns: [
{
match: /<script src=\"(.*\/)(.+?)\.(.+?)\.js\"><\/script>/g,
replacement: '<imod:ScriptPlaceHolder id="$2$3" type="FileInclude" url="$1$2.$3.js" runat="server"></imod:ScriptPlaceHolder>'
}
]
},
files: [
{expand: true, flatten: true, src: ['<%= config.dist %>/index.html'], dest: 'dist/'}
]
}
},
my task is the following:
htmlmin : {
dist : {
options : {
removeComments : true,
collapseWhitespace : true
},
files : {
'index.html' : 'index-src.html'
}
}
},
this works fine when i have just one html file on my site, so this processes index-src.html into minified index.html.
what if i have 100 other html files to process? i don't want to manually list them in my gruntfile.
how can i abstract the file name and tell grunt to minify my src file to the corresponding production file? in my case they are:
source file is [name]-src.html
production file is [name].html
i'm guessing it's just a matter of syntax, but i don't know what to write.
thanks! :)
See the Globbing Patterns section of the Grunt Documentation.
I believe you'll just have to change your param files object to:
'index.html' : '*-src.html'
Update
Re-reading your question, I realized you needed a 1-1 file conversion for dynamic source and destination file names.
For that see Building the files object dynamically
I have yet to use this in my project but the syntax looks straight forward. You may need to change your src vs production naming convention to a folder based convention.
/source/name.html (source folder)
/build/name.html (destination folder)
Example
files: [
{
expand: true, // Enable dynamic expansion.
cwd: 'source/', // Src matches are relative to this path.
src: ['*-src.html'], // Actual pattern(s) to match.
dest: 'build/', // Destination path prefix.
ext: '.html', // Dest filepaths will have this extension.
extDot: 'first' // Extensions in filenames begin after the first dot
}
]
module.exports = function (grunt) {
// 1. All configuration goes here
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
concat: {
controlCss: {
src: ['UI.controls/assets/css/*.css'],
dest: 'UI.controls/assets/css/min/production.css'
},
controlJs: {
src: ['UI.controls/assets/js/*.js'],
dest: 'UI.controls/assets/js/min/production.js'
},
coreJs: {
src: ['UI.core/assets/js/*.js'],
dest: 'UI.core/assets/js/min/production.js'
},
dist: {
src: ['UI.controls/assets/templates/*.htm'],
dest: 'UI.controls/assets/templates/min/production.min.htm'
}
},
cssmin: {
controlCss: {
src: 'UI.controls/assets/css/min/production.css',
dest: 'UI.controls/assets/css/min/production.min.css'
}
},
uglify: {
controlJs: {
src: 'UI.controls/assets/js/min/production.js',
dest: 'UI.controls/assets/js/min/production.min.js'
},
coreJs: {
src: 'UI.core/assets/js/min/production.js',
dest: 'UI.core/assets/js/min/production.min.js'
}
},
htmlmin: {
dist: {
options: {
removeComments: true,
collapseWhitespace: true
},
expand: true,
cwd: 'build',
src: ['UI.controls/assets/templates/*.htm'],
dest: 'UI.controls/assets/templates/min/production.min.htm'
}
}
});
// 2. Where we tell Grunt we plan to use this plug-in.
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.loadNpmTasks('grunt-contrib-cssmin');
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-contrib-htmlmin');
// 3. Where we tell Grunt what to do when we type "grunt" into the terminal.
grunt.registerTask('default', ['concat', 'cssmin', 'uglify', 'htmlmin']);
};
I have some code in a grunt.js file which is working with 0.3 but breaks on 0.4:
{
dest: '<%= process.env.DEST %>/index.html'
}
In 0.3 process is defined and so I can access variables defined in the environment inside the template when I am e.g. passing file paths to other plugins.
Is there an alternative approach to this which will work in 0.4? Or a way to put a breakpoint in while the template is rendering so that I can see what variables are available?
The default data is the config object. You can add the environment variable to the config object or just use it directly.
grunt.initConfig({
destination: process.env.DEST,
task: {
target: {
dest: '<%= destination %>/index.html'
}
},
});
or
grunt.initConfig({
task: {
target: {
dest: process.env.DEST + '/index.html'
}
},
});
That's a great straight forward answer by Sindre. Alternatively you can do (use the grunt-env plugin: https://npmjs.org/package/grunt-env )-
grunt.initConfig({
env : {
test : {
DEST : 'testDEST'
},
dev : {
DEST : 'devDEST'
},
qa : {
DEST : 'qaDEST'
},
prod : {
DEST : 'prodDEST'
}
}
});
grunt.registerTask('setenvs', 'Set environment variables', function() {
grunt.config('ENVS', process.env);
});
and then use
{
dest: '<%= ENVS.DEST %>/index.html'
}
Your task would be -
grunt.registerTask('default', [
'env:dev',
'setenvs'
'yourTask'
]);
Proposed alternative approach just so that you can use <%= ... %> and you don't have to hardcode it in initConfig. Target for env you can take as input from user and pass it to env.