如何使用 Webpack 将静态文件复制到构建目录?

IT技术 javascript webpack
2021-02-08 18:17:38

我正在尝试从 移动GulpWebpackGulp我的任务中,将所有文件和文件夹从/static/文件夹复制到/build/文件夹。如何做同样的事情Webpack我需要一些插件吗?

6个回答

使用 file-loader module要求资源是 webpack 的使用方式(source)。但是,如果您需要更大的灵活性或想要更简洁的界面,您也可以直接使用我的copy-webpack-pluginnpmGithub复制静态文件为了您staticbuild例如:

const CopyWebpackPlugin = require('copy-webpack-plugin');
 
module.exports = {
    context: path.join(__dirname, 'your-app'),
    plugins: [
        new CopyWebpackPlugin({
            patterns: [
                { from: 'static' }
            ]
        })
    ]
};

兼容性说明:如果您使用的是旧版本的 webpack,例如webpack@4.x.x,请使用copy-webpack-plugin@6.x.x. 否则使用最新的。

@Yan 如果文件发生变化,插件会重新复制文件(dev-server 或 webpack --watch)。如果它不是为您复制,请提出问题。
2021-03-12 18:17:38
成功了,谢谢:) 在多次尝试让它执行一个非常简单的命令失败后放弃了文件加载器。你的插件第一次工作。
2021-03-16 18:17:38
当您想要复制整个目录(即静态 html 和其他样板图像)时,这要简单得多!
2021-03-18 18:17:38
我是 webpack 的新手,但我很难理解为什么我们需要使用 file-loader/url-loader/img-loader ... 而不是仅仅复制它们?我们通过使用文件加载器来做这件事有什么好处?
2021-04-06 18:17:38
因为你是插件作者。没有比这更好的速度来问这个问题了。使用“copy-webpack-plugin”插件...我可以从源目录中过滤文件,以便它只复制具有特定文件扩展名的文件。只复制“.html”?问候
2021-04-06 18:17:38

你不需要复制东西,webpack 的工作方式与 gulp 不同。Webpack 是一个module捆绑器,您在文件中引用的所有内容都将包含在内。您只需要为此指定一个加载程序。

所以如果你写:

var myImage = require("./static/myImage.jpg");

Webpack 将首先尝试将引用的文件解析为 JavaScript(因为这是默认设置)。当然,那会失败。这就是您需要为该文件类型指定加载器的原因。例如,文件- 或url-loader获取引用的文件,将其放入 webpack 的输出文件夹(build在您的情况下应该是这样)并返回该文件的散列 url。

var myImage = require("./static/myImage.jpg");
console.log(myImage); // '/build/12as7f9asfasgasg.jpg'

通常加载器是通过 webpack 配置应用的:

// webpack.config.js

module.exports = {
    ...
    module: {
        loaders: [
            { test: /\.(jpe?g|gif|png|svg|woff|ttf|wav|mp3)$/, loader: "file" }
        ]
    }
};

当然,您需要先安装文件加载器才能完成这项工作。

好的,所有图像的大部分都在 css 和 html 中。那么我应该使用 require('img.png') 在我的 JS 文件中要求所有这些图像吗?让它与那个文件加载器一起工作?这是很疯狂的事情。
2021-03-15 18:17:38
您仍然存在 HTML 文件及其中所有引用未加载的问题。
2021-03-19 18:17:38
是的,如果你想进入 webpack 插件的地狱,你可以使用 file-loader、css-loader、style-loader、url-loader ……然后你就可以按照你需要的方式配置它了和谷歌搜索和不睡觉:) 或者你可以使用 copy-webpack-plugin 来完成你的工作......
2021-03-31 18:17:38
当然,您需要先安装文件加载器才能完成这项工作。此处链接到上述“文件加载器” 这里是如何安装和使用它。
2021-04-02 18:17:38
@KamilTomšík 所以你的建议是我们应该使用 webpack 插件来避免 webpack 插件?(开个玩笑。我明白你的意思。)
2021-04-05 18:17:38

如果你想复制你的静态文件,你可以这样使用文件加载器:

对于 html 文件:

在 webpack.config.js 中:

module.exports = {
    ...
    module: {
        loaders: [
            { test: /\.(html)$/,
              loader: "file?name=[path][name].[ext]&context=./app/static"
            }
        ]
    }
};

在你的 js 文件中:

  require.context("./static/", true, /^\.\/.*\.html/);

./static/ 是相对于你的 js 文件所在的位置。

你可以对图像或其他任何东西做同样的事情。上下文是一种强大的探索方法!!

当你说“在你的 js 文件中”是什么意思?如果我没有 JS 文件怎么办?
2021-03-12 18:17:38
我更喜欢这种方法而不是 copy-webpack-plugin module。此外,我能够在我的 webpack 配置中不使用“&context=./app/static”的情况下使其工作。我只需要 require.context 行。
2021-03-15 18:17:38
我正在尝试这个,它看起来很棒,但是我遇到了一个小问题,那就是它将我的文件index.html放入它创建的子目录中,称为_(下划线),这是怎么回事?
2021-03-26 18:17:38
绝对地。入口脚本中的这一行,即main.js导入static文件夹中的所有内容require.context("./static/", true, /^.*/);
2021-04-01 18:17:38
这是一个巧妙的技巧,但如果您复制太多文件,则会耗尽内存。
2021-04-10 18:17:38

前面提到的copy-webpack-plugin带来的一个之前没有解释过的优点是这里提到的所有其他方法仍然将资源捆绑到你的捆绑文件中(并要求你在某处“要求”或“导入”它们)。如果我只想移动一些图像或一些模板部分,我不想用对它们的无用引用来弄乱我的 javascript 包文件,我只想要在正确的位置发出文件。我还没有在 webpack 中找到任何其他方法来做到这一点。诚然,这不是 webpack 最初的设计目的,但它绝对是当前的用例。(@BreakDS 我希望这能回答您的问题-如果您愿意,这只是一个好处)

以上建议都不错。但是要尝试直接回答您的问题,我建议cpy-cli在您的package.json.

这个例子期望node在你的路径上的某个地方。安装cpy-cli为开发依赖项:

npm install --save-dev cpy-cli

然后创建几个 nodejs 文件。一个进行复制,另一个显示复选标记和消息。

复制.js

#!/usr/bin/env node

var shelljs = require('shelljs');
var addCheckMark = require('./helpers/checkmark');
var path = require('path');

var cpy = path.join(__dirname, '../node_modules/cpy-cli/cli.js');

shelljs.exec(cpy + ' /static/* /build/', addCheckMark.bind(null, callback));

function callback() {
  process.stdout.write(' Copied /static/* to the /build/ directory\n\n');
}

复选标记.js

var chalk = require('chalk');

/**
 * Adds mark check symbol
 */
function addCheckMark(callback) {
  process.stdout.write(chalk.green(' ✓'));
  callback();
}

module.exports = addCheckMark;

将脚本添加到package.json. 假设脚本在<project-root>/scripts/

...
"scripts": {
  "copy": "node scripts/copy.js",
...

运行脚本:

npm run copy

OP 想要完成在 webpack 中移动的文件,而不是使用 npm 脚本?
2021-03-18 18:17:38
这实际上更有意义。Webpack 很可能没有这个内置函数,因为它不是 gulp/make/etc 的替代品。
2021-03-23 18:17:38
即使 OP 想要在 webpack 中解决这个问题,他也有可能通过 npm 运行 webpack,因此他可以将其添加到运行 webpack 的构建脚本中
2021-04-01 18:17:38