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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/27639005/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 00:26:59  来源:igfitidea点击:

How to copy static files to build directory with Webpack?

javascriptwebpack

提问by Vitalii Korsakov

I'm trying to move from Gulpto Webpack. In GulpI have task which copies all files and folders from /static/folder to /build/folder. How to do the same with Webpack? Do I need some plugin?

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

采纳答案by Johannes Ewald

You don't need to copy things around, webpack works different than gulp. Webpack is a module bundler and everything you reference in your files will be included. You just need to specify a loader for that.

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

So if you write:

所以如果你写:

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

Webpack will first try to parse the referenced file as JavaScript (because that's the default). Of course, that will fail. That's why you need to specify a loader for that file type. The file- or url-loaderfor instance take the referenced file, put it into webpack's output folder (which should be buildin your case) and return the hashed url for that file.

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

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

Usually loaders are applied via the webpack config:

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

// webpack.config.js

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

Of course you need to install the file-loader first to make this work.

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

回答by kevlened

Requiring assets using the file-loader module is the way webpack is intended to be used (source). However, if you need greater flexibility or want a cleaner interface, you can also copy static files directly using my copy-webpack-plugin(npm, Github). For your staticto buildexample:

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

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

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

回答by Moussa Dembélé

If you want to copy your static files you can use the file-loader in this way :

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

for html files :

对于 html 文件:

in webpack.config.js :

在 webpack.config.js 中:

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

in your js file :

在你的 js 文件中:

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

./static/ is relative to where your js file is.

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

You can do the same with images or whatever. The context is a powerful method to explore !!

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

回答by steev

One advantage that the aforementioned copy-webpack-pluginbrings that hasn't been explained before is that all the other methods mentioned here still bundle the resources into your bundle files (and require you to "require" or "import" them somewhere). If I just want to move some images around or some template partials, I don't want to clutter up my javascript bundle file with useless references to them, I just want the files emitted in the right place. I haven't found any other way to do this in webpack. Admittedly it's not what webpack originally was designed for, but it's definitely a current use case. (@BreakDS I hope this answers your question - it's only a benefit if you want it)

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

回答by RnR

Above suggestions are good. But to try to answer your question directly I'd suggest using cpy-cliin a script defined in your package.json.

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

This example expects nodeto somewhere on your path. Install cpy-clias a development dependency:

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

npm install --save-dev cpy-cli

npm install --save-dev cpy-cli

Then create a couple of nodejs files. One to do the copy and the other to display a checkmark and message.

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

copy.js

复制.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');
}

checkmark.js

复选标记.js

var chalk = require('chalk');

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

module.exports = addCheckMark;

Add the script in package.json. Assuming scripts are in <project-root>/scripts/

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

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

To run the sript:

运行脚本:

npm run copy

npm run copy

回答by Andurit

Most likely you should use CopyWebpackPlugin which was mentioned in kevlened answer. Alternativly for some kind of files like .htmlor .jsonyou can also use raw-loader or json-loader. Install it via npm install -D raw-loaderand then what you only need to do is to add another loader to our webpack.config.jsfile.

您很可能应该使用在 kevlened 答案中提到的 CopyWebpackPlugin。或者,对于像.html.json这样的文件,你也可以使用 raw-loader 或 json-loader。通过安装它npm install -D raw-loader然后你只需要做的是向我们的webpack.config.js文件添加另一个加载程序。

Like:

喜欢:

{
    test: /\.html/,
    loader: 'raw'
}

Note: Restart the webpack-dev-server for any config changes to take effect.

注意:重新启动 webpack-dev-server 以使任何配置更改生效。

And now you can require html files using relative paths, this makes it much easier to move folders around.

现在您可以使用相对路径来要求 html 文件,这使得移动文件夹变得更加容易。

template: require('./nav.html')  

回答by RegarBoy

The way I load static imagesand fonts:

我加载静态images和的方式fonts

module: {
    rules: [
      ....

      {
        test: /\.(jpe?g|png|gif|svg)$/i,
        /* Exclude fonts while working with images, e.g. .svg can be both image or font. */
        exclude: path.resolve(__dirname, '../src/assets/fonts'),
        use: [{
          loader: 'file-loader',
          options: {
            name: '[name].[ext]',
            outputPath: 'images/'
          }
        }]
      },
      {
        test: /\.(woff(2)?|ttf|eot|svg|otf)(\?v=\d+\.\d+\.\d+)?$/,
        /* Exclude images while working with fonts, e.g. .svg can be both image or font. */
        exclude: path.resolve(__dirname, '../src/assets/images'),
        use: [{
          loader: 'file-loader',
          options: {
            name: '[name].[ext]',
            outputPath: 'fonts/'
          },
        }
    ]
}

Don't forget to install file-loaderto have that working.

不要忘记安装file-loader以使其正常工作。

回答by Victor Pudeyev

You can write bash in your package.json:

您可以在 package.json 中编写 bash:

# package.json
{
  "name": ...,
  "version": ...,
  "scripts": {
    "build": "NODE_ENV=production npm run webpack && cp -v <this> <that> && echo ok",
    ...
  }
}

回答by techNik

I was stuck here too. copy-webpack-plugin worked for me.

我也被卡在这里了。copy-webpack-plugin 为我工作。

However, 'copy-webpack-plugin' was not necessary in my case (i learned later).

但是,在我的情况下,'copy-webpack-plugin' 不是必需的(我后来才知道)。

webpack ignores root paths
example

webpack 忽略根路径
示例

<img src="/images/logo.png'>

Hence, to make this work without using 'copy-webpack-plugin' use '~' in paths

因此,要在不使用“copy-webpack-plugin”的情况下完成这项工作,请在路径中使用“~”

<img src="~images/logo.png'>

'~' tells webpack to consider 'images' as a module

'~' 告诉 webpack 将 'images' 视为一个模块

note: you might have to add the parent directory of images directory in

注意:您可能需要将图像目录的父目录添加到

resolve: {
    modules: [
        'parent-directory of images',
        'node_modules'
    ]
}

Visit https://vuejs-templates.github.io/webpack/static.html

访问https://vuejs-templates.github.io/webpack/static.html

回答by Mentor

The webpack config file (in webpack 2) allows you to export a promise chain, so long as the last step returns a webpack config object. See promise configuration docs. From there:

webpack 配置文件(在 webpack 2 中)允许您导出承诺链,只要最后一步返回一个 webpack 配置对象。请参阅承诺配置文档。从那里:

webpack now supports returning a Promise from the configuration file. This allows to do async processing in you configuration file.

webpack 现在支持从配置文件返回一个 Promise。这允许在您的配置文件中进行异步处理。

You could create a simple recursive copy function that copies your file, and only after that triggers webpack. E.g.:

你可以创建一个简单的递归复制函数来复制你的文件,然后才触发 webpack。例如:

module.exports = function(){
    return copyTheFiles( inpath, outpath).then( result => {
        return { entry: "..." } // Etc etc
    } )
}