Webpack.config, как просто скопировать index.html в папку dist

189

Я пытаюсь автоматизировать активы, входящие в / dist. У меня есть следующий config.js:

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

Я также хочу включить main.html из каталога, который находится рядом с / lib, в папку / dist при запуске webpack. Как я могу это сделать?

ОБНОВЛЕНИЕ 1 2017 _____________

Мой любимый способ сделать это сейчас - использовать html-webpack-pluginфайл шаблона. Спасибо за принятый ответ тоже! Преимущество этого способа заключается в том, что в индексном файле также будет добавлена ​​ссылка cachbusted js из коробки!

SuperUberDuper
источник

Ответы:

162

Опция 1

В вашем index.jsфайле (например, в записи в веб-пакете) добавьте требование к плагину index.htmlчерез загрузчик файлов , например:

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

Как только вы соберете свой проект с помощью веб-пакета, index.htmlон окажется в выходной папке.

Вариант 2

Используйте html-webpack-plugin, чтобы вообще не иметь index.html. Просто создайте файл для вас.

VitalyB
источник
2
Могу ли я как-то загрузить его, написав что-то в самом файле конфигурации?
codeVerine
Попробовал первый способ, и он скопировал файлы. Но CSS, который я копировал, перестал работать правильно. (Мне нужно было это вне веб-пакета, потому что Handsontable не может работать с веб-пакетом.)
Vaccano
@Vaccano для CSS, вы не должны использовать этот метод. Используйте style-loader и css-loader, см. Здесь: stackoverflow.com/questions/34039826/…
VitalyB
4
В webpack v2 вы, очевидно, не можете опустить -loaderсуффикс. напримерrequire('file-loader?name=[name].[ext]!../index.html');
overthink
1
@codeVerine Да, используя, добавив что-то вроде { test: /index\.html/, loader: 'file-loader', query: { name: '[name].[ext]' }вашего loadersмассива в ваш файл конфигурации webpack, только я не смог заставить webpack-dev-server его обслуживать, что, как ни странно, привело к 404 запросам /(корень не существует) !).
Брайан Маккатон
67

Я добавлю опцию к ответу VitalyB:

Вариант 3

Через нпм. Если вы выполняете свои команды через npm, вы можете добавить эту настройку в свой package.json (также посмотрите там webpack.config.js). Для разработки run npm startнет необходимости копировать index.html в этом случае, потому что веб-сервер будет запускаться из каталога исходных файлов, а bundle.js будет доступен из того же места (bundle.js будет жить только в памяти, но будет доступен, как если бы он находился вместе с index.html). Для npm run buildрабочего запуска и папка dist будет содержать ваш bundle.js, а index.html будет скопирован старой доброй командой cp, как вы можете видеть ниже:

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

Обновление: вариант 4

Существует copy-webpack-plugin , как описано в этом ответе Stackoverflow

Но, как правило, за исключением самого «первого» файла (например, index.html) и более крупных ресурсов (таких как большие изображения или видео), включайте CSS, HTML, изображения и т. Д. Непосредственно в свое приложение через requireWebpack, и он будет включать его для вас. (ну, после того, как вы правильно настроили загрузчики и, возможно, плагины).

EricC
источник
11
Вариант 3 должен быть Вариант 1
Джил Эпштейн
2
Я попробовал вариант 3, но горячая перезагрузка index.html не сработала. Разве вы не редактируете свой index.html очень часто? Серьезный вопрос.
камень
3
Используйте ncp вместо cp, если вы хотите поддерживать кросс-операционные среды разработки
Вивек Махарадж
33

Вы можете использовать CopyWebpackPlugin . Это работает так:

module.exports = {
  plugins: [
    new CopyWebpackPlugin([{
      from: './*.html'
    }])
  ]
}
hobbeshunter
источник
Теперь, когда Webpack заменил Gulp и Grunt не только связыванием пакетов, но и многими другими задачами, связанными со сборкой, это решение стало тем, что я видел в большинстве проектов. Скрипты package.jsonиспользуются только для простых вещей, таких как запуск тестового прогона или сервера разработки.
Роберт Джек Уилл
15

Я бы сказал, что ответ: ты не можешь. (или по крайней мере: вы не должны). Это не то, что должен делать Webpack. Webpack - это пакет, и его не следует использовать для других задач (в данном случае: копирование статических файлов - это другая задача). Вы должны использовать такой инструмент, как Grunt или Gulp для выполнения таких задач. Очень часто интегрируют Webpack как задачу Grunt или как задачу Gulp . У них обоих есть другие задачи, полезные для копирования файлов, как вы описали, например, grunt-contrib-copy или gulp-copy .

Для других ресурсов (не для index.html) вы можете просто связать их с Webpack (это именно то, для чего предназначен Webpack). Например, var image = require('assets/my_image.png');. Но я предполагаю, что ваши index.htmlпотребности не должны быть частью пакета, и, следовательно, это не работа для упаковщика.

Броди Гранат
источник
59
Я точно пошел в webpack, поэтому мне не нужно было использовать grunt или gulp. Есть ли другая альтернатива? Если мне нужно использовать gulp, зачем мне беспокоиться о webpack?
SuperUberDuper
4
Вопрос с ног на голову. Зачем вам использовать webpack, если вы можете использовать grunt или gulp? Это очень хорошие системы задач / сборки. Webpack (или browserify или r.js) - это инструменты, которые вы можете использовать для объединения большого количества JS-файлов (и других ресурсов) в один большой (или несколько) наборов JavaScript. Вы должны использовать правильный инструмент для работы. И снова, очень часто можно запускать webpack, browserify или другие упаковщики из grunt или gulp.
Броди Гранат
1
Есть много способов, которыми webpack может сделать это. Вы можете использовать file-loaderкоторые в основном только копирует файл / изображения в выходной каталог и дает URL , когда это требуется: var url = require('myFile');. Как я уже сказал, в комплекте может быть один или несколько файлов.
Броди Гранат
1
Я мог бы использовать brocolli в качестве родительского процесса сборки
SuperUberDuper
1
Это правильный ответ для меня. В больших / сложных проектах важна производительность сборки веб-пакетов. Различные плагины для копирования файлов увеличивают ненужные затраты на веб-пакеты, поэтому лучше уделить внимание веб-пакетам на комплектации JS.
Эви Сонг
14

Вы можете добавить индекс непосредственно в вашу конфигурацию ввода и использовать загрузчик файлов для его загрузки.

module.exports = {

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

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

}
Джейк Коксон
источник
5

Чтобы скопировать уже существующий index.htmlфайл в distкаталог, вы можете просто использовать HtmlWebpackPlugin , указав источник index.htmlв качестве шаблона .

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

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

Созданный dist/index.htmlфайл будет в основном таким же, как ваш исходный файл, с той разницей, что связанные ресурсы, такие как файлы .js<script> , добавляются тегами через веб-пакет. Минификация и другие параметры могут быть настроены и задокументированы на github .

Тоби Обек
источник
3

Это хорошо работает на Windows:

  1. npm install --save-dev copyfiles
  2. У package.jsonменя есть задача копирования:"copy": "copyfiles -u 1 ./app/index.html ./deploy"

Это переместит мой index.html из папки приложения в папку развертывания.

Патрик Дежарден
источник
Я
понял,
3

Чтобы расширить ответ @ hobbeshunter, если вы хотите использовать только index.html, вы также можете использовать CopyPlugin. Основная мотивация использования этого метода по сравнению с другими пакетами состоит в том, что это кошмар, добавлять много пакетов для каждого отдельного типа, настраивать его и т. Д. Самый простой способ - это использовать Самый CopyPlugin для всего:

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

затем

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

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

Как вы можете видеть, скопируйте всю статическую папку вместе со всем ее содержимым в папку dist. Нет CSS или файла или каких-либо других плагинов не требуется.

Хотя этот метод не подходит для всего, он сделает работу просто и быстро.

Remy
источник
-1

Я также обнаружил, что достаточно просто и достаточно обобщенно поместить мой index.html файл в dist/ каталог и добавить <script src='main.js'></script>к index.htmlнему файлы, включенные в пакет. main.jsПо-видимому, это выходное имя по умолчанию для нашего пакета, если в conf-файле webpack не указано иное . Я думаю, что это не очень хорошее и долгосрочное решение, но я надеюсь, что оно поможет понять, как работает веб-пакет .

QBack
источник