Webpack.config làm thế nào để chỉ sao chép index.html vào thư mục dist


189

Tôi đang cố gắng tự động hóa tài sản đi vào / dist. Tôi có các config.js sau:

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

Tôi cũng muốn bao gồm main.html từ thư mục nằm bên cạnh / lib, vào thư mục / dist khi chạy webpack. Tôi có thể làm cái này như thế nào?

CẬP NHẬT 1 2017___________

Cách ưa thích của tôi để làm điều này bây giờ là sử dụng html-webpack-pluginvới một tệp mẫu. Nhờ câu trả lời được chấp nhận quá! Ưu điểm của cách này là tệp chỉ mục cũng sẽ có liên kết js được lưu trong bộ nhớ cache!

Câu trả lời:


162

lựa chọn 1

Trong index.jstệp của bạn (tức là mục nhập gói web), hãy thêm một yêu cầu cho plugin index.htmlthông qua trình tải tệp , ví dụ:

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

Khi bạn xây dựng dự án của mình với webpack, index.htmlsẽ nằm trong thư mục đầu ra.

Lựa chọn 2

Sử dụng html-webpack-plugin để tránh có index.html. Đơn giản chỉ cần có webpack tạo tập tin cho bạn.


2
Tôi có thể bằng cách nào đó tải nó viết một cái gì đó trong tập tin cấu hình chính nó?
codeVerine

Đã thử cách đầu tiên, và nó đã sao chép các tập tin. Nhưng CSS mà tôi đang sao chép đã ngừng hoạt động chính xác. (Tôi cần nó bên ngoài webpack vì Handsontable không thể hoạt động với webpack.)
Vaccano

@Vaccano cho CSS bạn không nên sử dụng phương pháp này. Sử dụng trình tải kiểu và trình tải css, xem tại đây: stackoverflow.com/questions/34039826/iêu
VitalyB

4
Trong webpack v2 bạn dường như không thể bỏ qua -loaderhậu tố. ví dụrequire('file-loader?name=[name].[ext]!../index.html');
overthink

1
@codeVerine Có, bằng cách thêm một cái gì đó { test: /index\.html/, loader: 'file-loader', query: { name: '[name].[ext]' }vào loadersmảng của bạn trong tệp cấu hình webpack của bạn, chỉ tôi không thể có máy chủ webpack-dev để phục vụ nó, dẫn đến, thật thú vị, một yêu cầu 404 /(root không tồn tại !).
Brian McCutchon

67

Tôi sẽ thêm một tùy chọn cho câu trả lời của VitalyB:

Lựa chọn 3

Qua npm. Nếu bạn chạy các lệnh của mình qua npm, thì bạn có thể thêm thiết lập này vào gói.json của mình (cũng xem webpack.config.js ở đó). Để phát triển chạy npm start, không cần sao chép index.html trong trường hợp này vì máy chủ web sẽ được chạy từ thư mục tệp nguồn và bundle.js sẽ có sẵn từ cùng một nơi (bundle.js sẽ chỉ tồn tại trong bộ nhớ nhưng sẽ có sẵn như thể nó được đặt cùng với index.html). Để chạy sản xuất npm run buildvà một thư mục dist sẽ chứa bundle.js và index.html của bạn được sao chép bằng lệnh cp cũ tốt, như bạn có thể thấy dưới đây:

"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"
  }

Cập nhật: Tùy chọn 4

Có một plugin-webpack-plugin , như được mô tả trong câu trả lời Stackoverflow này

Nhưng nói chung, ngoại trừ tệp "đầu tiên" (như index.html) và các tài sản lớn hơn (như hình ảnh hoặc video lớn), bao gồm css, html, hình ảnh, v.v. trực tiếp trong ứng dụng của bạn thông qua requirevà webpack sẽ bao gồm nó cho bạn (tốt, sau khi bạn thiết lập chính xác với các trình tải và có thể là các plugin).


11
Tùy chọn 3 phải là Tùy chọn 1
Gil Epshtain

2
Tôi đã thử tùy chọn 3, nhưng tải lại index.html nóng không hoạt động. Bạn không chỉnh sửa index.html của bạn rất thường xuyên? Câu hỏi nghiêm túc.
đá

3
Sử dụng ncp thay vì cp nếu bạn muốn hỗ trợ các môi trường phát triển hệ điều hành chéo
Vivek Maharajh

32

Bạn có thể sử dụng CopyWebpackPlugin . Nó hoạt động như thế này:

module.exports = {
  plugins: [
    new CopyWebpackPlugin([{
      from: './*.html'
    }])
  ]
}

Giờ đây, Webpack đã thay thế Gulp và Grunt bằng cách không chỉ thực hiện gói, mà còn nhiều tác vụ liên quan đến xây dựng khác, giải pháp này là những gì tôi đã thấy trong hầu hết các dự án. Các tập lệnh trong package.jsonchỉ được sử dụng cho những việc đơn giản như khởi động trình chạy thử hoặc máy chủ dev.
Robert Jack Will

15

Tôi muốn nói câu trả lời là: bạn không thể. (hoặc ít nhất: bạn không nên). Đây không phải là những gì Webpack phải làm. Webpack là một gói, và nó không nên được sử dụng cho các tác vụ khác (trong trường hợp này: sao chép các tệp tĩnh là một tác vụ khác). Bạn nên sử dụng một công cụ như Grunt hoặc Gulp để thực hiện các nhiệm vụ đó. Việc tích hợp Webpack như một nhiệm vụ Grunt hoặc nhiệm vụ Gulp là rất phổ biến . Cả hai đều có các tác vụ khác hữu ích để sao chép các tệp như bạn đã mô tả, ví dụ: grunt-contrib-copy hoặc gulp-copy .

Đối với các tài sản khác (không phải index.html), bạn chỉ có thể gói chúng với Webpack (đó chính xác là những gì Webpack dành cho). Ví dụ , var image = require('assets/my_image.png');. Nhưng tôi cho rằng index.htmlnhu cầu của bạn không phải là một phần của gói, và do đó nó không phải là một công việc cho gói.


59
Tôi chính xác đã đi đến webpack vì vậy tôi sẽ không cần phải sử dụng grunt hoặc gulp. Có sự thay thế nào khác không? Nếu tôi cần sử dụng gulp tại sao tôi phải bận tâm với webpack?
SuperUberDuper

4
Câu hỏi bị đảo lộn. Tại sao bạn nên sử dụng webpack nếu bạn có thể sử dụng grunt hoặc gulp? Họ là hệ thống nhiệm vụ / xây dựng rất tốt. Webpack (hoặc browserify hoặc r.js) là các công cụ bạn có thể sử dụng để gói nhiều tệp JS (và các tài nguyên khác) thành một gói javascript lớn (hoặc nhiều). Bạn nên sử dụng các công cụ chính xác cho công việc. Và một lần nữa, rất phổ biến để chạy webpack, browserify hoặc các gói khác từ grunt hoặc gulp.
Brodie Garnet

1
Có nhiều cách webpack có thể làm điều đó. file-loaderVề cơ bản, bạn có thể sử dụng tệp sao chép tệp / hình ảnh vào thư mục đầu ra và cung cấp cho bạn url khi bạn yêu cầu : var url = require('myFile');. Như tôi đã nói, một gói có thể là một hoặc nhiều tệp.
Brodie Garnet

1
Tôi có thể sử dụng brocolli làm quy trình xây dựng cha mẹ
SuperUberDuper

1
Đây là câu trả lời đúng cho tôi. Trong các dự án lớn / phức tạp, hiệu suất xây dựng webpack là một cân nhắc quan trọng. Các plugin sao chép tệp khác nhau làm tăng thêm chi phí không cần thiết cho gói webpack, cho phép gói webpack tập trung vào gói JS là một ý tưởng tốt hơn.
Bài hát Evi

14

Bạn có thể thêm chỉ mục trực tiếp vào cấu hình mục nhập của mình và sử dụng trình tải tệp để tải nó

module.exports = {

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

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

}

5

Để sao chép một index.htmltập tin đã có vào distthư mục, bạn chỉ cần sử dụng HtmlWebpackPlugin bằng cách chỉ định nguồn index.htmldưới dạng mẫu .

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

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

Tệp đã tạo dist/index.htmlvề cơ bản sẽ giống như tệp nguồn của bạn với sự khác biệt mà các tài nguyên được đóng gói như các tệp .js được chèn bằng <script>thẻ bởi webpack. Giảm thiểu và các tùy chọn khác có thể được cấu hình và được ghi lại trên github .


3

Điều này hoạt động tốt trên Windows:

  1. npm install --save-dev copyfiles
  2. Trong package.jsontôi có một nhiệm vụ sao chép:"copy": "copyfiles -u 1 ./app/index.html ./deploy"

Điều này di chuyển index.html của tôi từ thư mục ứng dụng vào thư mục triển khai.


Tôi nhận được nó hoạt động bằng cách sử dụng câu trả lời ở đó: stackoverflow.com/questions/38858718/ trên
IsraGab 16/07/18

3

Để mở rộng câu trả lời của @ hobbeshunter nếu bạn chỉ muốn dùng index.html, bạn cũng có thể sử dụng CopyPlugin, Động lực chính để sử dụng phương pháp này khi sử dụng các gói khác là vì đó là một cơn ác mộng khi thêm nhiều gói cho mỗi loại và cấu hình nó, v.v. Cách dễ nhất là sử dụng CopyPlugin cho mọi thứ:

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

Sau đó

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

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

Như bạn có thể thấy nó sao chép toàn bộ thư mục tĩnh cùng với tất cả nội dung của nó vào thư mục dist. Không có css hoặc tập tin hoặc bất kỳ bổ trợ nào khác cần thiết.

Mặc dù phương pháp này không phù hợp với mọi thứ, nhưng nó sẽ hoàn thành công việc một cách đơn giản và nhanh chóng.


-1

Tôi cũng thấy đủ dễ dàng và chung chung để đặt index.html tệp của mình vào dist/ thư mục và thêm <script src='main.js'></script>vào index.htmlđể bao gồm các tệp webpack được gói. main.jsdường như là tên đầu ra mặc định của gói của chúng tôi nếu không có chỉ định nào khác trong tệp conf của webpack . Tôi đoán đó không phải là giải pháp tốt và lâu dài, nhưng tôi hy vọng nó có thể giúp hiểu cách thức hoạt động của webpack .

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.