Webpack.config cara menyalin indeks.html ke folder dist

189

Saya mencoba untuk mengotomatisasi aset masuk ke / dist. Saya memiliki config.js berikut:

module.exports = {
  context: __dirname + "/lib",
  entry: {
    main: [
      "./baa.ts"
    ]
  },
  output: {
    path: __dirname + "/dist",
    filename: "foo.js"
  },
  devtool: "source-map",
  module: {
    loaders: [
      {
        test: /\.ts$/,
        loader: 'awesome-typescript-loader'
      },
      { test: /\.css$/, loader: "style-loader!css-loader" }
    ]
  },
  resolve: {
    // you can now require('file') instead of require('file.js')
    extensions: ['', '.js', '.json']
  }
}

Saya juga ingin memasukkan main.html dari direktori yang berada di sebelah / lib, ke folder / dist ketika menjalankan webpack. Bagaimana saya bisa melakukan ini?

UPDATE 1 2017_____________

Cara favorit saya untuk melakukan ini sekarang adalah dengan menggunakan html-webpack-pluginfile templat. Terima kasih atas jawaban yang diterima juga! Keuntungan dari cara ini adalah bahwa file indeks juga akan memiliki tautan js cachbusted yang ditambahkan di luar kotak!

SuperUberDuper
sumber

Jawaban:

162

Pilihan 1

Dalam index.jsfile Anda (mis. Entri webpack) tambahkan keharusan ke plugin index.htmlvia file-loader Anda , misalnya:

require('file-loader?name=[name].[ext]!../index.html');

Setelah Anda membangun proyek Anda dengan webpack, index.htmlakan berada di folder output.

pilihan 2

Gunakan html-webpack-plugin untuk menghindari index.html sama sekali. Cukup minta webpack membuat file untuk Anda.

VitalyB
sumber
2
dapatkah saya memuatnya entah bagaimana menulis sesuatu dalam file konfigurasi itu sendiri?
codeVerine
Mencoba cara pertama, dan itu menyalin file. Tetapi CSS yang saya salin berhenti bekerja dengan benar. (Saya membutuhkannya di luar ke webpack karena Handsontable tidak dapat bekerja dengan webpack.)
Vaccano
@ Vaccano untuk CSS Anda seharusnya tidak menggunakan metode ini. Gunakan style-loader dan css-loader, lihat di sini: stackoverflow.com/questions/34039826/…
VitalyB
4
Di webpack v2 Anda tampaknya tidak bisa menghilangkan -loadersuffix. misalnyarequire('file-loader?name=[name].[ext]!../index.html');
overthink
1
@ codeVerine Ya, menggunakan dengan menambahkan sesuatu seperti { test: /index\.html/, loader: 'file-loader', query: { name: '[name].[ext]' }ke loadersarray Anda di file konfigurasi webpack Anda, hanya saja saya tidak bisa mendapatkan webpack-dev-server untuk melayani itu, yang mengarah ke, cukup lucu, permintaan 404 /(root tidak ada !).
Brian McCutchon
67

Saya akan menambahkan opsi untuk jawaban VitalyB:

Opsi 3

Via npm. Jika Anda menjalankan perintah Anda melalui npm, maka Anda dapat menambahkan pengaturan ini ke package.json Anda (lihat juga webpack.config.js di sana juga). Untuk mengembangkan proses npm start, tidak perlu menyalin index.html dalam hal ini karena server web akan dijalankan dari direktori file sumber, dan bundle.js akan tersedia dari tempat yang sama (bundle.js hanya akan hidup di memori tetapi akan tersedia seolah-olah itu terletak bersama dengan index.html). Untuk menjalankan produksi npm run builddan folder dist akan berisi bundle.js dan index.html Anda disalin dengan cp-command lama yang baik, seperti yang Anda lihat di bawah:

"scripts": {
    "test": "NODE_ENV=test karma start",
    "start": "node node_modules/.bin/webpack-dev-server --content-base app",
    "build": "NODE_ENV=production node node_modules/.bin/webpack && cp app/index.html dist/index.html"
  }

Pembaruan: Opsi 4

Ada copy-webpack-plugin , seperti yang dijelaskan dalam jawaban Stackoverflow ini

Tetapi secara umum, kecuali untuk file "pertama" (seperti index.html) dan aset yang lebih besar (seperti gambar atau video besar), sertakan css, html, gambar, dan sebagainya langsung di aplikasi Anda melalui requiredan webpack akan memasukkannya untuk Anda (yah, setelah Anda mengaturnya dengan benar dengan loader dan mungkin plugins).

EricC
sumber
11
Opsi 3 adalah Opsi 1
Gil Epshtain
2
Saya mencoba opsi 3, tetapi reload panas index.html tidak berhasil. Apakah Anda tidak sering mengedit index.html Anda? Pertanyaan serius.
batu
3
Gunakan ncp alih-alih cp jika Anda ingin mendukung lingkungan dev lintas-OS
Vivek Maharajh
33

Anda bisa menggunakan CopyWebpackPlugin . Ini berfungsi seperti ini:

module.exports = {
  plugins: [
    new CopyWebpackPlugin([{
      from: './*.html'
    }])
  ]
}
hobbeshunter
sumber
Sekarang Webpack telah menggantikan Gulp dan Grunt dengan tidak hanya melakukan bundling, tetapi juga banyak tugas terkait pembangunan lainnya, solusi ini adalah apa yang saya lihat di sebagian besar proyek. Script dalam package.jsonhanya digunakan untuk hal-hal sederhana seperti memulai test runner atau server dev.
Robert Jack Will
15

Saya akan mengatakan jawabannya adalah: Anda tidak bisa. (atau setidaknya: Anda tidak seharusnya). Ini bukan apa yang seharusnya dilakukan Webpack. Webpack adalah bundler, dan tidak boleh digunakan untuk tugas lain (dalam hal ini: menyalin file statis adalah tugas lain). Anda harus menggunakan alat seperti Grunt atau Gulp untuk melakukan tugas seperti itu. Sangat umum untuk mengintegrasikan Webpack sebagai tugas Grunt atau sebagai tugas Gulp . Keduanya memiliki tugas lain yang berguna untuk menyalin file seperti yang Anda gambarkan, misalnya, grunt-contrib-copy atau gulp-copy .

Untuk aset lain (bukan aset index.html), Anda dapat menggabungkannya dengan Webpack (itulah tujuan dari Webpack). Sebagai contoh var image = require('assets/my_image.png');,. Tapi saya berasumsi index.htmlkebutuhan Anda untuk tidak menjadi bagian dari bundel, dan karenanya itu bukan pekerjaan untuk bundler.

Brodie Garnet
sumber
59
Saya tepatnya pergi ke webpack jadi saya tidak perlu menggunakan gerutuan atau tegukan. Apakah ada alternatif lain? Jika saya perlu menggunakan tegukan, mengapa saya harus repot-repot dengan webpack?
SuperUberDuper
4
Pertanyaannya terbalik. Mengapa Anda harus menggunakan webpack jika Anda dapat menggunakan gerutuan atau tegukan? Mereka adalah sistem tugas / pembangunan yang sangat baik. Webpack (atau browserify atau r.js) adalah alat yang dapat Anda gunakan untuk menggabungkan banyak file JS (dan sumber daya lainnya) menjadi satu bundel javascript besar (atau banyak). Anda harus menggunakan alat yang benar untuk pekerjaan itu. Dan sekali lagi, sangat umum untuk menjalankan webpack, browserify atau bundler lain dari gerutuan atau tegukan.
Brodie Garnet
1
Ada banyak cara webpack dapat melakukannya. Anda bisa menggunakan file-loaderyang pada dasarnya hanya salinan file / gambar ke direktori output dan memberikan url ketika Anda membutuhkan itu: var url = require('myFile');. Seperti yang saya katakan, sebuah bundel dapat berupa satu atau beberapa file.
Brodie Garnet
1
Saya mungkin menggunakan brocolli sebagai proses pembuatan induk
SuperUberDuper
1
Ini jawaban yang tepat untuk saya. Dalam proyek besar / kompleks, kinerja pembuatan webpack merupakan pertimbangan penting. Berbagai plugin salin file menambah biaya yang tidak perlu ke webpack, membiarkan fokus webpack pada bundling JS adalah ide yang lebih baik.
Evi Song
14

Anda dapat menambahkan indeks secara langsung ke konfigurasi entri Anda dan menggunakan pemuat file untuk memuatnya

module.exports = {

  entry: [
    __dirname + "/index.html",
    .. other js files here
  ],

  module: {
    rules: [
      {
        test: /\.html/, 
        loader: 'file-loader?name=[name].[ext]', 
      },
      .. other loaders
    ]
  }

}
Jake Coxon
sumber
5

Untuk menyalin index.htmlfile yang sudah ada ke distdirektori Anda cukup menggunakan HtmlWebpackPlugin dengan menentukan sumber index.htmlsebagai templat .

const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  // ...
  plugins: [    
    new HtmlWebpackPlugin({
      template: './path/to/index.html',
    })
  ],
  // ...
};

File yang dibuat dist/index.htmlpada dasarnya akan sama dengan file sumber Anda dengan perbedaan sumber daya yang dibundel seperti file .js disuntikkan dengan <script>tag oleh webpack. Minifikasi dan opsi lebih lanjut dapat dikonfigurasi dan didokumentasikan di github .

Tobi Obeck
sumber
3

Ini bekerja dengan baik di Windows:

  1. npm install --save-dev copyfiles
  2. Di package.jsonSaya punya tugas salin:"copy": "copyfiles -u 1 ./app/index.html ./deploy"

Ini memindahkan index.html saya dari folder aplikasi ke folder deploy.

Patrick Desjardins
sumber
Saya membuatnya bekerja menggunakan jawaban di sana: stackoverflow.com/questions/38858718/…
IsraGab
3

Untuk memperluas jawaban @ hobbeshunter jika Anda ingin hanya mengambil index.html Anda juga dapat menggunakan CopyPlugin, Motivasi utama untuk menggunakan metode ini dibandingkan menggunakan paket lain adalah karena merupakan mimpi buruk untuk menambahkan banyak paket untuk setiap jenis tunggal dan mengonfigurasinya dll. Cara termudah adalah dengan menggunakan CopyPlugin untuk semuanya:

npm install copy-webpack-plugin --save-dev

Kemudian

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

module.exports = {
  plugins: [
    new CopyPlugin([
      { from: 'static', to: 'static' },
      { from: 'index.html', to: 'index.html', toType: 'file'},
    ]),
  ],
};

Seperti yang Anda lihat, salin seluruh folder statis beserta semua kontennya ke folder dist. Tidak perlu css atau file atau plugin lain apa pun.

Meskipun metode ini tidak cocok untuk semuanya, itu akan menyelesaikan pekerjaan dengan mudah & cepat.

Remy
sumber
-1

Saya juga menemukan mudah dan cukup generik untuk menempatkan saya index.html berkas di dist/ direktori dan menambahkan <script src='main.js'></script>untuk index.htmlmenyertakan file Webpack dibundel saya. main.jstampaknya merupakan nama keluaran default dari bundel kami jika tidak ada yang lain yang ditentukan dalam file conf webpack . Saya kira itu bukan solusi yang baik dan jangka panjang, tapi saya harap ini bisa membantu untuk memahami cara kerja webpack .

Qback
sumber