İfade gerektirmeden web paketi kullanarak bir dizindeki tüm dosyalar nasıl yüklenir


96

Uygulamamda 4 alt dizine bölünmüş çok sayıda javascript dosyam var. Grunt'ta hepsini alıp tek bir dosyada derliyorum. Bu dosyaların module.exports işlevi yoktur.

Web paketini kullanmak ve 4 parçaya bölmek istiyorum. Manuel olarak içeri girmek istemiyorum ve tüm dosyalarıma ihtiyacım var.

Derlemede dizin ağaçlarını gezen, ardından tüm .js dosya adlarını ve yollarını alan, ardından alt dizinlerdeki tüm dosyaları gerektiren ve çıktıya ekleyen bir eklenti oluşturmak istiyorum.

Her dizindeki tüm dosyaların, daha sonra giriş noktası dosyamdan isteyebileceğim bir modülde derlenmesini veya http://webpack.github.io/docs/plugins.html'nin bahsettiği varlıklara dahil edilmesini istiyorum .

Yeni bir dosya eklerken, onu doğru dizine bırakmak ve ekleneceğini bilmek istiyorum.

Bunu webpack veya birinin bunu yapmak için yazdığı bir eklenti ile yapmanın bir yolu var mı?

Yanıtlar:


119

Bunu başarmak için yaptığım şey buydu:

function requireAll(r) { r.keys().forEach(r); }
requireAll(require.context('./modules/', true, /\.js$/));

Hangi yükleyicinin kullanılacağını belirlemenin bir yolu var mı? Benim kullanım durumum image-size-loader, doğru en boy oranlarına sahip yer tutucular oluşturmak için tüm resimler için kullanmak istememdir.
bobbaluba

13
size çalışma örneği webpack.config.js
Rizwan Patel

2
@bobbaluba, yapılandırma dosyasında yükleyici belirtebilirsiniz: loaders: [ { test: /\.json$/, loader: 'json' } ]. { test: /\.json$/, loader: 'json' }yükleyiciyi kurduğunuz sürece .json dosyaları için json yükleyiciyi ekler.
Jake

1
Sizi çağıran bir işlev yazarak burada KURU olmaya çalışırsanız require.context(...)(örneğin, her şeyi birkaç klasörde gerektirmeye çalışıyorsanız), webpack'in bir uyarı vereceğini unutmayın. require.contextDerleme zamanı sabitleri olması gereken argümanlar .
Isaac Lyman

4
@Joel npmjs.com/package/require-context 2017'de oluşturuldu ve cevabım 2015'ten geliyor, bu yüzden doğrudan oradan alındığını söylemek zor. Ayrıca bunun require-contextbir sarmalayıcı olduğunu webpackve örneğinin 2016'da eklenen webpack.js.org/guides/dependency-management/#context-module-apiwebpack adresindeki belgelerinden alındığını unutmayın ( github.com/webpack/ webpack.js.org/commit/… ), ayrıca cevabımı yazdıktan sonra ... Belki webpack'in yazarları cevabımdan etkilenmiştir. Önbelleğe sahip olacak şekilde genişlettiklerini unutmayın.
splintor

38

Uygulama dosyamda gerekli olanı koydum

require.context(
  "./common", // context folder
  true, // include subdirectories
  /.*/ // RegExp
)("./" + expr + "")

bu gönderinin izniyle: https://github.com/webpack/webpack/issues/118

Şimdi tüm dosyalarımı ekliyor. Html ve css için bir yükleyicim var ve harika çalışıyor gibi görünüyor.


27
exprBu örnekte ne var ?
twiz

2
exprbağlam klasörü içindeki tek bir dosyanın yoludur. bu nedenle, bunu yalnızca tüm html dosyalarını gerektirmek için yapmanız gerekmiyorsa, bu yararlıdır. webpack.github.io/docs/context.html#context-module-api
mkoryak

18
Web exprpaketi belgelerine baktıktan sonra bile temel argümanın burada ne yaptığı hala bana açık değil . "bunu sadece tüm html dosyalarını gerektirmek için yapmayın" ne anlama geliyor? teşekkür ederim
mikkelrd

3
Yakalanmamış ReferenceError hatası aldım : ifade tanımlı değil . Bununla ilgili bir ipucu var mı?
CSchulz

2
exprBurada ne anlama geldiğine dair hala cevap yok
wizulus

5

Bir klasördeki tüm dosyaların haritasına ne dersiniz?

// { 
//   './image1.png':  'data:image/png;base64,iVBORw0KGgoAAAANS',
//   './image2.png':  'data:image/png;base64,iVBP7aCASUUASf892',
// }

Bunu yap:

const allFiles = (ctx => {
    let keys = ctx.keys();
    let values = keys.map(ctx);
    return keys.reduce((o, k, i) => { o[k] = values[i]; return o; }, {});
})(require.context('./path/to/folder', true, /.*/));

Bu örneği bıraktığınız için teşekkürler. Harita kullandım, dosyalarımın her birinin dışa aktardığı değeri döndürür =).
cacoder

1

Geçerli klasördeki tüm görüntülerin haritasının nasıl alınacağına ilişkin örnek.

const IMAGES_REGEX = /\.(png|gif|ico|jpg|jpeg)$/;

function mapFiles(context) {
  const keys = context.keys();
  const values = keys.map(context);
  return keys.reduce((accumulator, key, index) => ({
    ...accumulator,
    [key]: values[index],
  }), {});
}

const allImages = mapFiles(require.context('./', true, IMAGES_REGEX));

1

@ Splintor için tüm haklar (teşekkürler).

Ama burada benim kendi türetilmiş versiyonum.

Faydaları:

  • Hangi modüllerin dışa aktarıldığı bir {module_name: exports_obj}nesnenin altında toplanır .
    • module_name , dosya adından oluşturulur.
    • ... uzatma olmadan ve eğik çizgileri alt çizgilerle değiştirmeden (alt dizin taraması durumunda).
  • Özelleştirmeyi kolaylaştırmak için yorumlar eklendi.
    • Örneğin, kök seviyeli modüller için manuel olarak gerekli olmaları gerekiyorsa, dosyaları alt dizinlere dahil etmemek isteyebilirsiniz .

DÜZENLEME: Benim gibi, modüllerinizin normal bir javascript nesnesinden (en azından kök düzeyinde) başka bir şey döndürmeyeceğinden eminseniz, bunları orijinal dizin yapılarını çoğaltarak "bağlayabilirsiniz" (bkz. Kod (Derin Sürüm) ) bölümü).

Kod (Orijinal Sürüm):

function requireAll(r) {
    return Object.fromEntries(
        r.keys().map(function(mpath, ...args) {
            const result =  r(mpath, ...args);
            const name = mpath
                .replace(/(?:^[.\/]*\/|\.[^.]+$)/g, '') // Trim
                .replace(/\//g, '_') // Relace '/'s by '_'s
            ;
            return [name, result];
        })
    );
};
const allModules = requireAll(require.context(
    // Any kind of variables cannot be used here
    '@models'  // (Webpack based) path
    , true     // Use subdirectories
    , /\.js$/  // File name pattern
));

Misal:

Nihai için örnek çıktı console.log(allModules);:

{
  main: { title: 'Webpack Express Playground' },
  views_home: {
    greeting: 'Welcome to Something!!',
    title: 'Webpack Express Playground'
  }
}

Dizin ağacı:

models
├── main.js
└── views
    └── home.js

Kod (Derin Sürüm):

function jsonSet(target, path, value) {
    let current = target;
    path = [...path]; // Detach
    const item = path.pop();
    path.forEach(function(key) {
        (current[key] || (current[key] = {}));
        current = current[key];
    });
    current[item] = value;
    return target;
};
function requireAll(r) {
    const gather = {};
    r.keys().forEach(function(mpath, ...args) {
        const result =  r(mpath, ...args);
        const path = mpath
            .replace(/(?:^[.\/]*\/|\.[^.]+$)/g, '') // Trim
            .split('/')
        ;
        jsonSet(gather, path, result);
    });
    return gather;
};
const models = requireAll(require.context(
    // Any kind of variables cannot be used here
    '@models'  // (Webpack based) path
    , true     // Use subdirectories
    , /\.js$/  // File name pattern
));

Misal:

Bu sürümü kullanan önceki örneğin sonucu:

{
  main: { title: 'Webpack Express Playground' },
  views: {
    home: {
      greeting: 'Welcome to Something!!',
      title: 'Webpack Express Playground'
    }
  }
}

0

bu benim için çalışıyor:

function requireAll(r) { r.keys().forEach(r); } 

requireAll(require.context('./js/', true, /\.js$/));

NOT: Bu, ./js/ alt dizinlerinde özyinelemeli .js dosyaları gerektirebilir.

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.