24

I have an app in which I'm using Webpack. In this app, I need to copy some static .html files from various directories in my source directory to the same hierarchy in the public directory. In an attempt to do this, I'm using the CopyWebpackPlugin. At this time, my webpack.config.js file looks like this:

webpack.config.js

const path = require('path');
const projectRoot = path.resolve(__dirname, '../');

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

module.exports = {
  entry: {
    app: './source/index.html.js',
  },
  output: {
    path: path.resolve(__dirname, 'public'),
    filename: '[name].package.js'
  },
  module: {
    rules: [
      {
        test: /\.css$/,
        loaders: ['style-loader','css-loader']        
      },
    ]
  },
  plugins: [
    new CopyWebpackPlugin(
      [ { from: './source/**/*.html', to: './public', force:true } ],
      { copyUnmodified: true }
    )
  ]
};

When I run webpack from the command line, everything works as I want. The HTML files are successfully copied, including their directories, into the public directory. However, when copied, the source directory name is included. For example, if my directory structure is like this:

/source
  /dir-1
    /child-a
      index.html
      page.html
    /child-b
      index.html
      contact.html
  /dir-2
    index.html

I'm expecting the result of CopyWebpackPlugin to output to the following:

expected:

/public
  /dir-1
    /child-a
      index.html
      page.html
    /child-b
      index.html
      contact.html
  /dir-2
    index.html

However, what I'm actually getting is:

actual:

/public
  /source
    /dir-1
      /child-a
        index.html
        page.html
      /child-b
        index.html
        contact.html
    /dir-2
      index.html

Notice how the source directory is included in the copy target. I don't understand why this is being included. More importantly, I need to remove it. How do I remove the source directory from the path in the target?

user687554
  • 10,663
  • 25
  • 77
  • 138

3 Answers3

33

You can use context param.

new CopyWebpackPlugin(
    [{
        context: './source/',
        from: '**/*.html',
        to: './public',
        force: true
    }], {
        copyUnmodified: true
    }
)
Stanislav Mayorov
  • 4,298
  • 5
  • 21
  • 44
  • This didn't work for me, looking at the documentatioin, the "context" option should be in the options object (where copyUnmodified is) and applies to all paterns https://www.npmjs.com/package/copy-webpack-plugin – Tonio Mar 21 '18 at 14:49
  • @Tonio It can be used in both cases. Like array element too. From the docs: `A path that determines how to interpret the from path` and `A path that determines how to interpret the from path, shared for all patterns` https://webpack.js.org/plugins/copy-webpack-plugin/#context – Stanislav Mayorov Mar 24 '18 at 15:42
  • 4
    Great, that's the solution. Am I stupid or is the CopyWebpackPlugin documentation not so clear? – migli Jul 27 '19 at 05:04
  • @migli documentation isn't very good. I think they would glad to merge docs improvement PR. – Stanislav Mayorov Jul 29 '19 at 12:23
  • I found the [webpack documentation for the CopyWebpackPlugin](https://webpack.js.org/plugins/copy-webpack-plugin/#context) quite clear. It states ao: `If from is a glob, then regardless of the context option, the result will be the structure specified in the from option`. Combined with `To determine the structure from which the found resources will be copied to the destination folder, the context option is used.` this pointed me to the same answer as @StanislavMayorov. – Reinier Jan 05 '21 at 11:14
  • I found [How to copy files using the Copy Webpack Plugin (Without copying the entire folder structure)](https://ilikekillnerds.com/2021/09/how-to-copy-files-using-the-copy-webpack-plugin-without-copying-the-entire-folder-structure/) article very good at explaining this. – Ritesh Jagga Mar 28 '22 at 06:01
3

I have used name variable.

patterns: [
    { from: "src/*.svg",    to: '[name].svg'},
]
The Fool
  • 16,715
  • 5
  • 52
  • 86
2

I was able to copy the folder src/pages/Content/lib to the folder build/lib and keep the original structure with the following configuration:

    new CopyWebpackPlugin({
      patterns: [
        {
          from: 'src/pages/Content/lib',
          to({ context, absoluteFilename }) {
            return path.join(__dirname, 'build', 'lib', path.relative(context, absoluteFilename));
          },
        },
      ],
    }),

I am using webpack 5.23 and copy-webpack-plugin 7

The following example page helped me understand how to configure the plugin: https://webpack.js.org/plugins/copy-webpack-plugin/#copy-in-new-directory

note that next to from and to, you could add the properties force: true and info: { minimized: true } to override the previous files and don't execute minimization on these

fredericrous
  • 2,833
  • 1
  • 25
  • 26
  • Thanks a lot @fredericrous , your answer also helped to solve a issue where webpack compilation step was stuch at 92% progress because the minification process was taking a lot of time https://stackoverflow.com/a/71450698/9871509 – Ankit Tiwari Mar 12 '22 at 15:08