For our task to copy files from their original location to a destination directory, we need to create that destination directory. And every time we want to re-create the destination folder we’ll need to delete it and its contents. So let’s use Grunt’s built-in tools to create two tasks—one to create the folder and one to delete it.
Grunt provides grunt.config.init, which lets us define the configuration for our Grunt tasks by passing in a JavaScript object with the properties and values for our tasks.
files/simple/deploying/Gruntfile.js | |
| grunt.config.init({ |
| }); |
When you install and configure a Grunt plug-in, you’ll often have to add some properties and values to this configuration object. Typically you’ll add a property for the specific plug-in, and then that property will have its own configuration object.
While we’re not building a plug-in here, let’s follow the same approach. We’ll create a property called copyFiles and place our configuration variables within that object.
A best practice for creating configuration options for a task is to place all options within an options property. This avoids any potential collision with Grunt’s API.
Let’s define our first option. We need a way to specify the destination folder that we’ll copy our files to, so we’ll create an option for the workingDirectory:
files/simple/deploying/Gruntfile.js | |
| copyFiles: { |
| options: { |
| workingDirectory: 'working', |
| } |
| } |
We’re going to leave a trailing comma after the value when we’re writing configuration options. That way we won’t forget to add it when we add a new option to this section later. However, this is not valid according to the specifications for ECMAScript 6. Grunt and Node.js won’t complain, but JavaScript syntax checkers (and seasoned JavaScript developers) might. When you’re done writing your configurations, you’ll definitely want to remove trailing commas.
Grunt’s built-in grunt.util.mkdir method creates folders, and so all we have to do is create a task, read the name of the directory from our configuration object, and create the folder.
files/simple/deploying/Gruntfile.js | |
| grunt.registerTask('createFolder', 'Create the working folder', function(){ |
| grunt.config.requires('copyFiles.options.workingDirectory'); |
| |
| grunt.file.mkdir(grunt.config.get('copyFiles.options.workingDirectory')); |
| }); |
We’re using grunt.config.requires to ensure that the configuration property we want has been set. The task will abort if the field isn’t specified. Notice that we can use a string with dot notation to look up properties in the configuration object. We then use grunt.config.get to fetch the value out of the object and use it to create the folder, using the same dot notation.
At the command line we can run
| $ grunt createFolder |
and we’ll see the new working folder in our directory.
To remove the working folder, we can write a very similar task, but this time we’ll use Grunt’s grunt.file.delete method instead. This deletes a file, or a folder and all of its contents.
files/simple/deploying/Gruntfile.js | |
| grunt.registerTask('clean', |
| 'Deletes the working folder and its contents', function(){ |
| grunt.config.requires('copyFiles.options.workingDirectory'); |
| |
| grunt.file.delete(grunt.config.get('copyFiles.options.workingDirectory')); |
| }); |
One of the biggest advantages of using these Grunt utilities instead of the raw operating-system commands is that they will work on multiple operating systems. The syntax for recursively deleting folders is very different between Linux and Windows.
Now let’s look at how we copy the files over.
Our project may have lots of files that we don’t want to deploy to the web server. For example, there’s no need to send up our Gruntfile.js or the node_modules folder if we’re building a basic website. So we’ll need to tell Grunt what files we want to copy over. Let’s create a new manifest property of our copyFiles configuration object, which will be an array of file paths we want to copy.
files/simple/deploying/Gruntfile.js | |
| copyFiles: { |
| options: { |
| workingDirectory: 'working', |
* | manifest: [ |
* | 'index.html', 'stylesheets/style.css', 'javascripts/app.js' |
* | ] |
Grunt provides grunt.file.copy, which lets us specify a source file and a destination. Unlike the grunt.file.delete method, it doesn’t handle folders. We’ll address that later. For now we’ll just be very explicit and list every file we want in our manifest property.
Our copyFiles task will check for the workingDirectory and manifest properties and then iterate over the files in the manifest, copying each file into the working folder.
files/simple/deploying/Gruntfile.js | |
| grunt.registerTask('copyFiles', function(){ |
| var files, workingDirectory; |
| |
| grunt.config.requires('copyFiles.options.manifest'); |
| grunt.config.requires('copyFiles.options.workingDirectory'); |
| |
| files = grunt.config.get('copyFiles.options.manifest'); |
| workingDirectory = grunt.config.get('copyFiles.options.workingDirectory'); |
| files.forEach(function(file) { |
| var destination = workingDirectory + '/' + file; |
| grunt.log.writeln('Copying ' + file + ' to ' + destination); |
| grunt.file.copy(file, destination); |
| }); |
| }); |
We can run this task with
| $ grunt copyFiles |
| Running "copyFiles" task |
| Copying index.html to working/index.html |
| Copying stylesheets/style.css to working/stylesheets/style.css |
| Copying javascripts/app.js to working/javascripts/app.js |
| |
| Done, without errors. |
and the files are copied into our working folder.
Now, to make this all fit together nicely, let’s create a new task that runs the clean, createFolder, and copyFiles tasks. Let’s call the task deploy, shall we?
files/simple/deploying/Gruntfile.js | |
| grunt.registerTask('deploy', 'Deploys files', |
| ['clean', 'createFolder', 'copyFiles']); |
Run this new task:
| $ grunt deploy |
| Running "clean" task |
| |
| Running "createFolder" task |
| |
| Running "copyFiles" task |
| Copying index.html to working/index.html |
| Copying stylesheets/style.css to working/stylesheets/style.css |
| Copying javascripts/app.js to working/javascripts/app.js |
| |
| Done, without errors. |
You’ll see that all of the tasks ran in the order we specified, and all of the files were copied into the working folder as expected. Technically, we don’t need the createFolder task; Grunt’s grunt.file.copy will create the destination folder if it doesn’t exist. But it’s best to be specific.
So far we’ve demonstrated that we can use Grunt’s built-in file tools to copy individual files, but what we’ve built here works only if we specify the individual files we want to copy. That’s not practical in a lot of cases. We might want to copy a folder and all of its files.
3.138.126.169