How to copy a directory with Webpack?

Viewed 16913

I've been playing around with Webpack to try and understand how it works but no matter what I do it never seems to do what I expect it to considering what the documentation and numerous videos seem to say.

As a first step to accomplishing my end goal, I simply want to copy all the files in the ./src directory to the ./dist directory, maintaining the full folder structure. After a bit of digging it seems what I need is something like this in the rules for my webpack.config.js (I currently only have html, css and js files in the source directory for testing purposes):

test: /\.(html|js|css)$/,
use: [
    {
        loader: 'file-loader',
        options: {
            name: '[path][name].[ext]'
        }
    }
]

Now in my entry.js file which is in the root directory I have this:

function requireAll (r) { r.keys().forEach(r); }
requireAll(require.context('./src/', true, /\.(html|js|css)$/));

...because from my understanding I need to import all the files I want to process into my entry file so they can then be placed into the new directory using file-loader.

With this setup, running webpack creates a dist folder like this:

dist/
    chunk.js     <-- (the output filename set in my webpack config)
    entry.js     <-- (an exact duplicate of the entry file)

This is obviously not what I want. I don't know whether I just need to tweak my setup or if I'm doing this completely wrong.

3 Answers

You can use the copy webpack plugin.

npm install --save-dev copy-webpack-plugin

Edit your webpack.config.js file:

    //Add a plugin declaration at the begining of file
    const CopyWebpackPlugin = require('copy-webpack-plugin');
    
    //...
    
    //search (or create) the plugin array. 
    plugins: [
        // ...
        // Add your plugin
        new CopyWebpackPlugin([
                
            // Copy directory contents to {output}/to/directory/
            //{ from: 'from/directory', to: 'to/directory' },
            { from: 'src', to: 'dist' },
        ]
      ],

There is a lot of simple examples in documentation

edit syntax with Webpack5 is:

const CopyPlugin = require('copy-webpack-plugin');

module.exports = {
    ...
    plugins: [
        new CopyPlugin({
            patterns: [
                { from: "./src/dir", to: "to/dir" }
            ],
        })
    ],
    ...
}

You can use the copy-webpack-plugin:

npm install copy-webpack-plugin --save-dev

In Webpack version 5 (current version) you can edit your webpack.config.js file, adding:

const CopyPlugin = require('copy-webpack-plugin');

module.exports = {
    ...
    plugins: [
        new CopyPlugin({
            patterns: [
                { from: "./src/my-directory", to: "my-directory" }
            ],
        })
    ],
    ...
}

copy-webpack-plugin Documentation

The purpose of webpack is that you should never have to copy files yourself like what you are saying. For example if you are trying to copy from './src' to './dist' you have already taken a bad wrong turn. :P Google around for some "web pack starter projects". And let one of those get you a working configuration. Then go from there, and build up. Starting from scratch will be a bit tricky. If you do have a good reason to copy files there is a webpack plugin i can tell you about for that, but i don't think you will need it.

Here's a file that uses plugins (my project):

https://github.com/Clay-Ferguson/meta64/blob/master/src/main/resources/public/webpack.config.js

I'm not using the 'file copy' plugin but i am using the 'webpack-shell-plugin' which is powerful because it can let you run any script you want before and/or after builds.

Related