Cara membuat beberapa jalur output di konfigurasi Webpack


165

Adakah yang tahu cara membuat beberapa jalur output di file webpack.config.js? Saya menggunakan bootstrap-sass yang datang dengan beberapa file font yang berbeda, dll. Untuk webpack untuk memproses ini saya telah menyertakan file-loader yang berfungsi dengan benar, namun file yang outputnya disimpan ke jalur output yang saya tentukan untuk sisa file saya:

    output: {
      path: __dirname + "/js",
      filename: "scripts.min.js"
    }

Saya ingin mencapai sesuatu di mana saya mungkin dapat melihat jenis ekstensi untuk apa pun keluaran webpack dan untuk hal-hal yang berakhir dengan .woff .eot, dll, minta mereka dialihkan ke jalur output yang berbeda. Apakah ini mungkin?

Saya melakukan sedikit googling dan menemukan masalah * ini di github di mana beberapa solusi ditawarkan, sunting:

tetapi sepertinya Anda perlu mengetahui titik masuk untuk dapat menentukan output menggunakan metode hash misalnya:

var entryPointsPathPrefix = './src/javascripts/pages';
var WebpackConfig = {
  entry : {
    a: entryPointsPathPrefix + '/a.jsx',
    b: entryPointsPathPrefix + '/b.jsx',
    c: entryPointsPathPrefix + '/c.jsx',
    d: entryPointsPathPrefix + '/d.jsx'
  },

  // send to distribution
  output: {
    path: './dist/js',
    filename: '[name].js'
  }
}

* https://github.com/webpack/webpack/issues/1189

Namun dalam kasus saya, sejauh menyangkut file font, proses input agak abstrak dan semua yang saya tahu adalah output. dalam kasus file saya yang lain yang mengalami transformasi, ada titik yang diketahui di mana saya memerlukannya untuk kemudian ditangani oleh loader saya. jika ada cara untuk mencari tahu di mana langkah ini terjadi, saya kemudian bisa menggunakan metode hash untuk menyesuaikan jalur output, tetapi saya tidak tahu di mana file-file ini diperlukan.

Jawaban:


220

Saya tidak yakin apakah kami memiliki masalah yang sama karena webpack hanya mendukung satu output per konfigurasi pada Juni 2016. Saya kira Anda sudah melihat masalah pada Github .

Tapi saya memisahkan jalur output dengan menggunakan multi-compiler . (Yaitu memisahkan objek konfigurasi webpack.config.js).

var config = {
    // TODO: Add common Configuration
    module: {},
};

var fooConfig = Object.assign({}, config, {
    name: "a",
    entry: "./a/app",
    output: {
       path: "./a",
       filename: "bundle.js"
    },
});
var barConfig = Object.assign({}, config,{
    name: "b",
    entry: "./b/app",
    output: {
       path: "./b",
       filename: "bundle.js"
    },
});

// Return Array of Configurations
module.exports = [
    fooConfig, barConfig,       
];

Jika Anda memiliki konfigurasi yang sama di antara mereka, Anda bisa menggunakan perluasan perpustakaan atau Object.assignES6 atau {...}operator penyebaran di ES7.


Saya tidak menjalankan cuplikan, beberapa kesalahan atau kesalahan ketik mungkin terjadi
Yeo

Saya menjalankan cuplikan Anda, bekerja seperti pesona ... Terkejut tidak ada yang melihat ini, eh pengembang frontend, tidak sabar, selalu terburu-buru ;-). Saya mengekspor konfigurasi dengan cara yang sama, tetapi deklarasi saya berbeda / standar: var config = {entri: SOURCE_DIR + '/index.jsx', ....} Tidak menggunakan multi kompiler juga: - \
Aubergine

Atau Anda bisa melakukan webpack && cp dll dalam npm?
SuperUberDuper

1
Itu sangat berguna bagi saya untuk menggunakan paket npm baik di folder asli (ada tes otomatis) tetapi juga di folder aplikasi yang mengimplementasikan paket. Dengan cara ini saya dapat melewati langkah unduh npm dan tinggal menguji kode paket saya yang diperbarui sampai versi baru stabil dan siap untuk diterbitkan pada npm.
Adrian Moisa

<pre> <code> var config = {// TODO: Tambahkan modul Konfigurasi umum: {},}; </code> </pre> module{}Objeknya salah. Itu tidak wajib. Ini akan diperpanjang / digabung pada tingkat yang sama sebagai kata kunci name, entry, output(dari contoh Anda). <pre> <code> {module: {mode: "development", devtool: "source-map"}}, nama: "a", entri: "./a/app", output: {path: "/ a ", filename:" bundle.js "}} </code> </pre>
Rob Waa

249

Webpack mendukung beberapa jalur keluaran.

Tetapkan jalur keluaran sebagai kunci entri. Dan gunakanname template keluaran sebagai.

konfigurasi webpack:

entry: {
    'module/a/index': 'module/a/index.js',
    'module/b/index': 'module/b/index.js',
},
output: {
    path: path.resolve(__dirname, 'dist'),
    filename: '[name].js'
}

dihasilkan:

└── module
    ├── a
    │   └── index.js
    └── b
        └── index.js

4
Dalam kasus saya, saya ingin satu output tidak mengandung chunkhash, apakah ada solusi sederhana untuk itu? Terima kasih.
raRaRa

1
@ Zhengkenghong Saya percaya bahwa jalur output yang dihasilkan perlu distdi dalamnya. Jadi, alih-alih module/a/index.jsmenjadi jalur output, itu harus menjadi module/a/dist/index.jsAtau yang lain, Anda menimpa file entri Anda.
dance2die

1
distFolder @Sung sudah dikonfigurasi di jalur output. Jadi file yang dihasilkan sebenarnya dist/module/a/index.js, yang tidak saya sebutkan.
zhengkenghong

4
Saya pikir ini harus menjadi jawaban yang diterima karena ini adalah jawaban dari webpack 4 docs. -> webpack.js.org/concepts/output/#multiple-entry-points
Will

1
@raRaRa Terlambat ke pesta, tetapi Anda dapat melakukannya dengan menggunakan fungsi output.filenameseperti yang didokumentasikan di sini: webpack.js.org/configuration/output/#outputfilename
Thomas

22

Jika Anda dapat hidup dengan beberapa jalur keluaran yang memiliki tingkat kedalaman dan struktur folder yang sama ada cara untuk melakukan ini di webpack 2 (belum pernah menguji dengan webpack 1.x)

Pada dasarnya Anda tidak mengikuti aturan doc dan Anda memberikan path untuk nama file.

module.exports = {
    entry: {
      foo: 'foo.js',
      bar: 'bar.js'
    },

    output: {
      path: path.join(__dirname, 'components'),
      filename: '[name]/dist/[name].bundle.js', // Hacky way to force webpack   to have multiple output folders vs multiple files per one path
    }
};

Itu akan mengambil struktur folder ini

/-
  foo.js
  bar.js

Dan mengubahnya menjadi

/-
  foo.js
  bar.js
  components/foo/dist/foo.js
  components/bar/dist/bar.js

@ccnixon didokumentasikan di sini webpack.js.org/configuration/output/#outputfilename seach untuk "masih diizinkan".
John Henckel

3

Saya menulis sebuah plugin yang diharapkan dapat melakukan apa yang Anda inginkan, Anda dapat menentukan titik masuk yang diketahui atau tidak dikenal (menggunakan glob ) dan menentukan keluaran yang tepat atau secara dinamis menghasilkan mereka menggunakan jalur dan nama file entri. https://www.npmjs.com/package/webpack-entry-plus


3

Anda pasti dapat mengembalikan berbagai konfigurasi dari file webpack.config Anda. Tapi itu bukan solusi optimal jika Anda hanya ingin salinan artefak berada di folder dokumentasi proyek Anda, karena itu membuat webpack membuat kode Anda dua kali lipat dua kali lipat keseluruhan waktu untuk membangun.

Dalam hal ini saya akan merekomendasikan untuk menggunakan plugin FileManagerWebpackPlugin sebagai gantinya:

const FileManagerPlugin = require('filemanager-webpack-plugin');
// ...
plugins: [
    // ...
    new FileManagerPlugin({
      onEnd: {
        copy: [{
          source: './dist/*.*',
          destination: './public/',
        }],
      },
    }),
],

1

Anda hanya dapat memiliki satu jalur output.

dari docs https://github.com/webpack/docs/wiki/configuration#output

Opsi yang memengaruhi output kompilasi. opsi keluaran memberi tahu Webpack cara menulis file yang dikompilasi ke disk. Perhatikan, bahwa meskipun ada beberapa titik masuk, hanya satu konfigurasi output yang ditentukan.

Jika Anda menggunakan hashing ([hash] atau [chunkhash]) apa pun, pastikan untuk memiliki urutan modul yang konsisten. Gunakan OccurenceOrderPlugin atau recordsPath.


Terima kasih. Aku akan meninggalkan Q untuk berjaga-jaga kalau-kalau ada yang bisa membuat solusi.
spb

apa kasus penggunaan Anda untuk membutuhkan 2 jalur output? Sepertinya Anda ingin 2 aplikasi atau 1 aplikasi dan 1 modul.
ex-zac-tly

Saya pikir saya perlu satu yang didedikasikan untuk output yang dihasilkan oleh file-loader yang semuanya masuk ke root proyek sedangkan saya menginginkannya di folder sendiri. i akhirnya hanya mengarahkan jalur output di loader itu sendiri per jawaban saya di bawah ini.
spb

1
Ini tidak sepenuhnya benar. Secara teknis Anda hanya dapat menentukan satu jalur output tetapi akan berlaku untuk setiap kunci dalam objek entri, yang memungkinkan Anda untuk memiliki beberapa output - webpack.js.org/concepts/entry-points
sanjsanj

0

Saya benar-benar akhirnya hanya masuk ke index.js dalam modul file-loader dan mengubah di mana isinya dipancarkan. Ini mungkin bukan solusi optimal, tetapi sampai ada cara lain, ini baik karena saya tahu persis apa yang sedang ditangani oleh loader ini, yang hanya font.

//index.js
var loaderUtils = require("loader-utils");
module.exports = function(content) {
    this.cacheable && this.cacheable();
    if(!this.emitFile) throw new Error("emitFile is required from module system");
    var query = loaderUtils.parseQuery(this.query);
    var url = loaderUtils.interpolateName(this, query.name || "[hash].[ext]", {
        context: query.context || this.options.context,
        content: content,
        regExp: query.regExp
    });
    this.emitFile("fonts/"+ url, content);//changed path to emit contents to "fonts" folder rather than project root
    return "module.exports = __webpack_public_path__ + " + JSON.stringify( url) + ";";
}
module.exports.raw = true;

1
Tidak tahu apakah ini masih menjadi masalah bagi Anda tetapi lihatlah di npmjs.com/package/webpack-entry-plus
sanjsanj
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.