[Solved] NPM copy files to dist folder
Need a quick way to use NPM to copy files to the dist folder after build? Follow some suggestions in this post!
Jan 13, 2023 | Read time 10 minutes🔔 Table of contents
Introduction
A common task with front-end development is after we have built our front end code (CSS, SASS, JavaScript, etc) we copy the minified artifacts to a dist
folder.
Then the dist (short for distribution) folder is the one that will be deployed and served!
Using NPM copy files to dist folders can be done in the following steps:
- Open up the terminal and go to your root project directory
- Make sure you have NPM installed and run
npm init
- In the
package.json
file, create a command"build": "cp -r ./src ./dist"
- Then, make sure you are in the root directory of the project and run
npm run build
Note about folders
Most projects use a folder named
dist
. I have seen different implementations where people call itpublic
orbuild
Package.json to use for copying files to dist
We can setup a front end project by using the following NPM command.
npm init
After that there will be a bunch of prompts that asks us how we want to setup our project. This data will then be in a package.json
file in project root directory!
name: (project-name) project-name
version: (0.0.0) 0.0.1
description: The Project Description
entry point: //leave empty
test command: //leave empty
git repository: //the repositories url
keywords: //leave empty
author: // your name
license: N/A
The resulting package.json
will look something similar to this
{
"name": "project-name",
"version": "0.0.1",
"description": "Project Description",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "the repositories url"
},
"author": "your name",
"license": "N/A"
}
Now to copy our source code files (CSS, JS) to the dist
folder, we can update the package.json
file to the following:
(Assuming that we already have the code in src folder)
{
"name": "project-name",
"version": "0.0.1",
"description": "Project Description",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "cp -r ./src ./dist"
},
"repository": {
"type": "git",
"url": "the repositories url"
},
"author": "your name",
"license": "N/A"
}
We can then use the command npm run build
to start our build process. Keep in mind the cp
command works for Linux distributions. The -r
flag is there to indicate that we want to recursively go through all the folders.
Keep in mind that the above cp
command is for Linux - if you want to use Windows, we can install Git Bash where cp should be available.
An alternative command if you are on Windows is the copy
windows command (https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/copy).
So for windows, our package.json becomes the following:
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "copy src dist"
}
We then do the same thing as before and use the command npm run build
to start our build process.
A more advanced version of copy
on Windows is xcopy
.
XCOPY is similar to the COPY command except that it has additional switches to specify both the source and destination in detail.
The below, we use xcopy to copy the files in src folder to the dist folder:
"copyfiles": "xcopy c:\project\src c:\project\dist /e"
The format of xcopy is:
xcopy <source> <destination> /e
Cross OS support for copying files
Now if we want our build pipeline to be able to support multiple operating systems, we can use the NPM package “copyfiles” (https://github.com/calvinmetcalf/copyfiles)
The
copyfiles
NPM package is more robust and contains more features than the systemcp
orcopy
commands. It can filter out files, flatten output, slice paths, etc.
Using NPM copyfiles package
To get started using the NPM copyfiles package we can follow the below steps:
npm install --save-dev copyfiles
to install copyfiles package as your development dependency- In your package.json “cpdir”: “npx copyfiles soruceDir destinationDir” - using npx you can execute your npm package binaries.
- Finally you run the copy script:
npm run cpdir
Example 1: NPM copyfiles
for only Javascript files
In the below example, we can use the command to filter out only JavaScript files .js
(assuming that our source is in src/assets)
"copyjavascript": "copyfiles --flat src/assets/*.js destination"
Note: The --flat
flag just tells copyfiles to flatten the output - taking just the files and not keeping any folders.
Example 2: NPM copyfiles
for complex copying to folders
NPM copyfiles package lets you to do more complex copying of files to folders. Consider the following:
copyfiles foo foobar foo/scripts/*.js out
The above command, we have a destination folder called out
. The command will copy all files from foo
and foobar
. Now notice that in our foo
folder, we have a directory called scripts
. With this command, we only copy the .js
files in the scripts
folder!
So as you can see, we can do fairly complex tasks with this NPM package that could not be done with cp
(Linux) or copy
(Windows)
Tip: Use a task runner or bundler (such as gulp or webpack)
Using
cp
orcopy
commands or even the NPM copyfiles is good for simple copy tasks, but if your project is going to be more complex in the future - its beneficial to setup your project with task runners such as gulp (https://gulpjs.com/) or bundlers such WebPack.For example, your project in the future might require to use SASS for CSS, using post processing tasks such as minify CSS, JS or even optimizing images, etc.
These types of actions are pretty much built in with those libraries!
Copy files to folder with Gulp example
Just for example, we can do the copy files to a dist folder with Gulp in the steps:
Step 1: Install Gulp CLI
Firstly we need to install the Gulp CLI like so:
npm install --global gulp-cli
Note: If you’ve previously installed gulp globally, run npm rm --global gulp
before following these instructions.
Step 2: Create project folder
Next we create our project folder using my-project
as the folder name.
npx mkdirp my-project
cd my-project
Step 3: Initialize the project with NPM
We then initialize our NPM project.
npm init
This will give a bunch of prompts to setup the project and the result will create a package.json
file similar to the following:
{
"name": "my-project",
"version": "0.0.1",
"description": "Project Description",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "the repositories url"
},
"author": "your name",
"license": "N/A"
}
Step 4: Create project folder
We then need to install Gulp and its plugins as a dev dependency:
npm install --save-dev gulp
Step 5: Create the gulp file
In the root project folder and create a file named gulpfile.js
.
const { src, dest } = require("gulp");
function copy(cb) {
src('src/*.js')
.pipe(dest('dist'));
cb();
}
exports.copy = copy;
Gulp’s design is very plugin driven, so you would need to know which plugin to perform the task you are after. In the above code, we are using the src
and dest
plugins from gulp to copy our files.
src
reads JavaScript files from src/ and passes its contents into the pipeline,pipe
will take output of the previous command as pipe it as an input for the next,dest
writes the output of previous commands to the copies/ directory.
Step 6: Run the build
We can then run the copy task with the following command in the terminal:
gulp copy
Summary
In this post I went over a few ways we can copy files from the src
folder to the dist
folder. This is a common action in front-end build pipelines where we copy files such as images, CSS, JavaScript dist
folder to deploy.
When we are on Linux, we can use the cp
command and for Windows, the copy
or the xcopy
commands will work!
If we want to have more finer control, there is a NPM package called copyfiles
that can do this and contains more features such as filtering, flatting out the files, etc.
It is recommended to use task runners such as Gulp or Webpack if your project becomes more complex and will require more control/features other than just copying files.