Webpack ile dizin oluşturmak için statik dosyalar nasıl kopyalanır?


330

Ben den hareket etmeye çalışıyorum Gulpiçin Webpack. İçinde Gulptüm dosyaları ve klasörleri / static / klasöründen / build / klasörüne kopyalayan görevim var. Aynı şey nasıl yapılır Webpack? Eklentiye ihtiyacım var mı?


2
Gulp anlamak harika. isterseniz web paketini gulpfile.js'den arayın
Baryon Lee

Laravel Mix kullanıyorsanız, laravel.com/docs/5.8/mix#copying-files-and-directories kullanılabilir.
Ryan

Yanıtlar:


179

Bir şeyleri kopyalamanıza gerek yok, webpack yıpranmadan farklı çalışır. Webpack bir modül paketleyicisidir ve dosyalarınızda referans verdiğiniz her şey dahil edilecektir. Bunun için bir yükleyici belirtmeniz yeterlidir.

Eğer yazarsanız:

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

Webpack önce başvurulan dosyayı JavaScript olarak ayrıştırmaya çalışır (çünkü bu varsayılan değerdir). Tabii ki, bu başarısız olacak. Bu nedenle, bu dosya türü için bir yükleyici belirtmeniz gerekir. Dosya - veya url-yükleyici , örneğin başvurulan dosyayı almak WebPack çıkış klasörüne yerleştirin (olması gereken buildsizin durumunuzda) ve bu dosya için karma url dönün.

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

Genellikle yükleyiciler webpack yapılandırmasıyla uygulanır:

// webpack.config.js

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

Elbette, bu işi yapabilmek için önce dosya yükleyiciyi kurmanız gerekir.


42
" Tabii ki bu işi yapabilmek için önce dosya yükleyiciyi kurmanız gerekiyor. " Burada yukarıda belirtilen "dosya yükleyiciye" bağlantı verin . Ve işte nasıl kurulacağı ve kullanılacağı.
Nate

21
Hala HTML dosyalarında sorun var ve içindeki tüm referanslar yüklenmiyor.
kilianc

126
evet, webpack eklentilerinin cehennemine girmek istiyorsanız, dosya yükleyici, css-yükleyici, stil yükleyici, url yükleyici kullanabilirsiniz ... ve sonra istediğiniz şekilde yapılandırmak için harika zaman geçirebilirsiniz. ve googling ve uyku değil :) veya copy-webpack-eklentisini kullanabilir ve işinizi
halledebilirsiniz

11
@ KamilTomšík Peki öneriniz webpack eklentilerini önlemek için bir webpack eklentisi kullanmamız mı? (Şaka yapıyorum. Anladım.)
Konrad Viltersten

12
Tamam, tüm görüntülerin çoğu css ve html'de. Yani ben istemek ('img.png') kullanarak benim JS dosyaları tüm bu görüntüleri gerekir; bu dosya yükleyiciyle çalışmasını sağlamak için? Bu oldukça çılgınca bir şey.
Rantiev

580

Dosya yükleyici modülünü kullanarak varlıklara gereksinim duymak, web paketinin kullanılması için tasarlanan yoldur ( kaynak ). Ancak, daha fazla esnekliğe ihtiyacınız varsa veya daha temiz bir arayüz istiyorsanız, statik dosyaları doğrudan copy-webpack-plugin( npm , Github ) kullanarak kopyalayabilirsiniz . Senin için statichiç buildÖrneğin:

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

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

11
Bir dizinin tamamını kopyalamak istediğinizde bu çok daha basittir (örn. Statik html ve diğer kaynak plakası resimleri)!
Arjun Mehta

6
Hile yaptı, teşekkür ederim :) çok basit bir komut yapmak için birkaç başarısız denemeden sonra dosya yükleyiciden vazgeçti. eklentiniz ilk kez çalıştı.
arcseldon

3
@Yan Eklenti, dosyaları değiştirirse yeniden kopyalar (dev-server veya webpack --watch). Sizin için kopyalama yapmıyorsa, lütfen sorun bildirin.
kevlened

2
Web paketinde yeniyim, ancak neden onları kopyalamak yerine dosya yükleyici / url yükleyici / img yükleyici kullanmamız gerektiğini anlamakta zorlanıyorum? Bunu dosya yükleyiciyle yapmaktan kazandığımız fayda nedir?
BreakDS

2
Eklenti yazarı olduğunuz için. Bu soruyu sormak için daha iyi bir hız yok. "Copy-webpack-plugin" eklentisini kullanarak ... dosyaları sadece belirli dosya uzantısı ex ile kopyalayacak şekilde kaynak dizinden filtreleyebilir miyim. yalnızca ".html" kopyalansın mı? Saygılarımızla
DevWL

56

Statik dosyalarınızı kopyalamak istiyorsanız dosya yükleyiciyi şu şekilde kullanabilirsiniz:

html dosyaları için:

webpack.config.js dosyasında:

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

js dosyanızda:

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

./static/, js dosyanızın bulunduğu yere göredir.

Aynı şeyi görüntülerle veya her neyse yapabilirsiniz. Bağlam keşfetmek için güçlü bir yöntemdir !!


3
Bu yöntemi copy-webpack-plugin modülüne tercih ederim. Ayrıca, benim webpack yapılandırma "& context =. / App / statik" kullanmadan çalışmasını başardı. Sadece requir.context satırına ihtiyacım vardı.
Dave Landry

2
Bunu deniyorum, harika görünüyor ama alıyorum küçük bir sorun için, o benim (alt çizgi) index.htmldenilen oluşturduğu bir alt dizine koyarak _, ne oluyor?
kris

2
"Js dosyanızda" derken ne demek istersiniz? Bir JS dosyam yoksa ne olur?
evolutionxbox

kesinlikle. Giriş komut dosyasındaki bu bir satır, yani klasör main.jsiçindeki her şeyi içeri aktarıyor static:require.context("./static/", true, /^.*/);
Mario

2
Bu düzgün bir hack'tir, ancak çok fazla dosya kopyalıyorsanız bellek yetersiz kalır.
Tom

18

Yukarıda belirtilen copy-webpack-plugin'in daha önce açıklanmadığı bir avantajı, burada belirtilen diğer tüm yöntemlerin hala kaynakları paket dosyalarınıza paketlemesidir (ve bunları bir yere "gerektirmenizi" veya "içe aktarmanızı" gerektirir). Sadece bazı görüntüleri veya bazı şablon parçalarını hareket ettirmek istersem, javascript paket dosyamı onlara gereksiz bir referansla karıştırmak istemiyorum, sadece dosyaların doğru yerde yayınlanmasını istiyorum. Bunu web paketinde yapmanın başka bir yolunu bulamadım. Kuşkusuz, webpack başlangıçta bunun için tasarlanmamıştı, ancak kesinlikle güncel bir kullanım durumu. (@BreakDS Umarım bu soruya cevap verir - bu sadece istersen fayda sağlar)


7

Yukarıdaki öneriler iyidir. Ancak sorunuzu doğrudan yanıtlamaya çalışmak için cpy-cli, sizin tanımladığınız bir komut dosyasında kullanmanızı öneririm package.json.

Bu örnek yolunuzda bir yer bekliyor node. cpy-cliGeliştirme bağımlılığı olarak yükleyin :

npm install --save-dev cpy-cli

Sonra birkaç nodejs dosyası oluşturun. Biri kopyayı, diğeri bir onay işareti ve mesajı görüntülemek için.

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;

Komut dosyasını içine ekleyin package.json. Komut dosyalarının var olduğu varsayılarak<project-root>/scripts/

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

Komut dosyasını çalıştırmak için:

npm run copy


3
OP npm komut dosyaları kullanarak değil, web paketinin içinde hareket eden dosyayı gerçekleştirmek istedi?
William S

OP bunu web paketinin içinde çözmek istediğinde bile, web paketini npm aracılığıyla çalıştırması mümkündür, bu yüzden web paketinin çalıştığı derleme komut dosyasına ekleyebilir
Piro,

5

Büyük olasılıkla kevlened cevabında belirtilen CopyWebpackPlugin'i kullanmalısınız. Alternatif olarak .html veya .json gibi bazı dosyalar için ham yükleyici veya json yükleyici de kullanabilirsiniz. Aracılığıyla yükleyin npm install -D raw-loaderve tek yapmanız gereken webpack.config.jsdosyamıza başka bir yükleyici eklemek .

Sevmek:

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

Not: Yapılandırma değişikliklerinin etkili olması için webpack-dev-server'ı yeniden başlatın.

Ve şimdi göreli yolları kullanarak html dosyalarına ihtiyaç duyabilirsiniz, bu klasörlerin taşınmasını çok daha kolay hale getirir.

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

5

Statik yükleme şekli imagesve 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/'
          },
        }
    ]
}

file-loaderÇalışması için yüklemeyi unutmayın .


Yinelenen dosya adlarını nasıl ele alırsınız? Ya da daha iyisi, yeni çıkış dizinindeki orijinal yolu korumanın herhangi bir yolunu biliyor musunuz?
Ocak'ta

Projenizde aynı uzantı adına sahip yinelenen dosya adınız olmamalıdır. İçeriği aynı ise kopyaları saklamanın anlamı nedir? Değilse, içeriklerine göre farklı adlandırın. Eşyalarınızı orijinal yolunda tutmak istiyorsanız neden web paketini kullanasınız ki? Sadece JS çevirisi istiyorsanız Babil yeterli olacaktır.
RegarBoy

1
Bileşen tabanlı geliştirme (temel ilkelerinden biri kapsülleme ve daha özel olarak bu durumda bilgi gizleme ) uyguluyorsanız , bahsettiğiniz şeylerden hiçbiri uygun değildir. Birisi programa yeni bir bileşen eklediğinde, adında başka bir görüntü olup olmadığını kontrol logo.pngetmeleri veya küresel çarpışmayı önlemek için geniş ve "umarım" benzersiz bir dosya adı oluşturmaları gerekmemelidir . Aynı sebeple CSS Modülleri kullanıyoruz .
cantuket

1
Görüntülerin neden orijinal yolu ve dosya adını korumasını istediğime gelince; çoğunlukla hata ayıklama, aynı neden sourcemaps kullanmak, aynı zamanda SEO . Ne olursa olsun, sorumun cevabı aslında çok basitti ... [path][name].[ext]ve bunu belirli bir ortam veya kullanım durumu için değiştirmek için bolca esneklik sağlandı ... dosya yükleyici
cantuket

1
Örneğinizin bir varyasyonunu uyguladığımız söyleniyor, bu yüzden sağladığınız için teşekkür ederiz!
cantuket

3

Paketinize bash yazabilirsiniz. Json:

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

1
Windows'da cp yerine xcopy kullanın:"build": "webpack && xcopy images dist\\images\\ /S /Y && xcopy css dist\\css\\ /S /Y"
SebaGra

7
Doğru, çözümünüz her işletim sistemi için farklı bir komut dosyasına sahip olmak mı?
Maciej Gurban

Evet, benim için her işletim sistemi için bir komut dosyası kabul edilebilir (linux ile ilgili bir komut dosyası Darwin veya başka bir POSIX * nix üzerinde çalışacağından gerçekten unix / unix olmayan)
Victor Pudeyev

Ve bu Windows örneği de varsayılan kabuk olarak PowerShell ile çalışmaz.
Julian Knight

CopyWebpackPlugin'in aksine, bu seçenek dosya tarihlerini tutar. İşletim sistemi sorunu açık kaynak için sorunlu olabilir, ancak küçük takımlar için Windows bash ile kolayca yönetilebilir veya cp.bat ile xcopy sarma yapılabilir.
Alien Technology

2

Ben de burada takılıp kaldım. copy-webpack-plugin benim için çalıştı.

Ancak, benim durumumda 'copy-webpack-plugin' gerekli değildi (daha sonra öğrendim).

webpack kök yolları
örneğini yok sayar

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

Bu nedenle, bu işi yollarda 'copy-webpack-plugin' use '~' kullanmadan yapmak için

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

'~' web paketine 'resimleri' modül olarak kabul etmesini söyler

not: resim dizininin üst dizinini

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

Https://vuejs-templates.github.io/webpack/static.html adresini ziyaret edin


2

Webpack yapılandırma dosyası (webpack 2'de), son adım bir webpack config nesnesi döndürdüğü sürece bir söz zincirini dışa aktarmanıza olanak tanır. Vaat yapılandırma belgelerine bakın . Buradan:

webpack artık yapılandırma dosyasından bir Söz döndürmeyi destekliyor. Bu, yapılandırma dosyanızda zaman uyumsuz işlemeye izin verir.

Dosyanızı kopyalayan basit bir özyinelemeli kopyalama işlevi oluşturabilirsiniz ve ancak bundan sonra web paketi tetiklenir. Örneğin:

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

1

diyelim ki tüm statik varlıklarınız kök düzeyinde "statik" bir klasörde ve bunları alt klasörün yapısını koruyan yapı klasörüne, ardından giriş dosyanıza kopyalamak istiyorsunuz)

//index.js or index.jsx

require.context("!!file?name=[path][name].[ext]&context=./static!../static/", true, /^\.\/.*\.*/);
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.