web-dev-qa-db-ja.com

Webpackで静的ファイルをビルドディレクトリにコピーするにはどうすればいいですか?

私はGulpからWebpackに移動しようとしています。 Gulpでは、 /static/ フォルダーから /build/ フォルダーにすべてのファイルとフォルダーをコピーするタスクがあります。 Webpackで同じことをするにはどうすればいいですか?私はいくつかのプラグインが必要ですか?

280

周りをコピーする必要はありません、webpackはgulpとは違った働きをします。 Webpackはモジュールバンドルであり、ファイルで参照しているものすべてが含まれます。そのためにはローダーを指定するだけです。

あなたが書いたのであれば:

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

Webpackは最初に参照ファイルをJavaScriptとして解析しようとします(これがデフォルトです)。もちろん、それは失敗するでしょう。そのため、そのファイルタイプにローダーを指定する必要があります。例えば file - または url-loader は参照ファイルを受け取り、それをwebpackの出力フォルダ(あなたの場合はbuild)に置き、そのファイルのハッシュされたURLを返します。

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

通常ローダーはwebpack configを通して適用されます。

// webpack.config.js

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

もちろん、これを機能させるには、最初にファイルローダーをインストールする必要があります。

172
Johannes Ewald

ファイルローダーモジュールを使用してアセットを要求することは、webpackが使用されることを意図している方法です( source )。しかし、もっと大きな柔軟性が必要な場合やもっときれいなインターフェースが欲しい場合は、私のcopy-webpack-pluginnpmGithub )を使って静的ファイルを直接コピーすることもできます。 staticからbuildの例では、

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

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

静的ファイルをコピーしたい場合は、次のようにファイルローダーを使用できます。

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ファイルがある場所に対する相対パスです。

画像でも同じことができます。コンテキストは探索するための強力な方法です。

53

前述の copy-webpack-plugin がもたらすもう1つの利点は、ここで説明していない他のすべての方法でもリソースがバンドルファイルにバンドルされることです(そして "require"または "import"が必要)どこかにそれらを)。イメージやテンプレートパーシャルを移動したいだけであれば、不要な参照を含むJavaScriptバンドルファイルを整理したくない場合は、ファイルを適切な場所に出力したいだけです。私はこれをwebpackで行う他の方法を見つけていません。確かにそれはwebpackが最初に設計されたものではありませんが、それは間違いなく現在の使用例です。 (@BreakDSこれがあなたの質問に答えてくれることを願っています - それがあなたがそれを望んでいるのであればそれは唯一の利点です)

8
steev

上記の提案は良いです。しかし、あなたの質問に直接答えるには、あなたのcpy-cliで定義されているスクリプトの中でpackage.jsonを使うことをお勧めします。

この例はあなたのパスのどこかにnodeを期待しています。開発依存関係としてcpy-cliをインストールしてください:

npm install --save-dev cpy-cli

その後、いくつかのnodejsファイルを作成します。一方はコピーを実行し、もう一方はチェックマークとメッセージを表示します。

copy.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

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

7
RnR

たぶんあなたはkevlened回答で述べられたCopyWebpackPluginを使うべきです。 .html または .json のようなある種のファイルの代わりに、raw-loaderまたはjson-loaderも使用できます。 npm install -D raw-loader経由でインストールしてください。そして、あなたがする必要があるのは、私たちのwebpack.config.jsファイルに別のローダーを追加することです。

好きです:

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

注:設定の変更を有効にするためにwebpack-dev-serverを再起動してください。

相対パスを使用してHTMLファイルを要求できるようになりました。これにより、フォルダを簡単に移動できます。

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

静的なimagesfontsを読み込む方法:

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/'
          },
        }
    ]
}

それを機能させるためにfile-loaderをインストールすることを忘れないでください。

3
RegarBoy

最後の手順でwebpack設定オブジェクトが返される限り、webpack設定ファイル(webpack 2)を使用して、プロミスチェーンをエクスポートすることができます。 promise configuration docsを参照してください 。そこから:

webpackは設定ファイルからPromiseを返すことをサポートします。これはあなたの設定ファイルで非同期処理をすることを可能にします。

あなたはあなたのファイルをコピーする単純な再帰的コピー機能を作成することができます、そしてそれが後に初めてウェブパックを引き起こします。例えば。:

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

私もここで立ち往生していました。 copy-webpack-pluginは私のために働きました。

しかし、 'copy-webpack-plugin'は私の場合は必要ありませんでした(後で学びました)。

webPackはルートパスを無視します
の例

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

したがって、 'copy-webpack-plugin'を使用せずにこれを機能させるには、パスに '〜'を使用します。

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

'〜'はWebpackに 'images'をモジュールと見なすように指示します

注意:imagesディレクトリの親ディレクトリを追加する必要があるかもしれません。

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

https://vuejs-templates.github.io/webpack/static.html にアクセスしてください。

2
techNik

スタティックアセットはすべてルートレベルの「スタティック」フォルダにあり、サブフォルダの構造を維持したままビルドフォルダにコピーしてから、エントリファイルに入れてください。

//index.js or index.jsx

require.context("!!file?name=[path][name].[ext]&context=./static!../static/", true, /^\.\/.*\.*/);
1
abhisekpaul

あなたのpackage.jsonにbashを書くことができます。

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