Webpack.config cómo copiar el index.html a la carpeta dist

189

Estoy tratando de automatizar los activos que entran / dist. Tengo el siguiente 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']
  }
}

También quiero incluir main.html del directorio que se encuentra al lado de / lib, en la carpeta / dist cuando ejecute webpack. ¿Cómo puedo hacer esto?

ACTUALIZACIÓN 1 2017_____________

Mi forma favorita de hacer esto ahora es usar el html-webpack-pluginarchivo de plantilla. Gracias a la respuesta aceptada también! ¡La ventaja de esta manera es que el archivo de índice también tendrá el enlace js cachbusted agregado de fábrica!

SuperUberDuper
fuente

Respuestas:

162

Opción 1

En el index.jsarchivo (es decir, la entrada webpack) añadir un requieren a su index.htmltravés archivo-loader plug-in, por ejemplo:

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

Una vez que construya su proyecto con webpack, index.htmlestará en la carpeta de salida.

opcion 2

Use html-webpack-plugin para evitar tener index.html. Simplemente haga que webpack genere el archivo por usted.

VitalyB
fuente
2
¿puedo cargarlo de alguna manera escribiendo algo en el archivo de configuración?
codeVerine
Intenté la primera manera, y copió los archivos. Pero el CSS que estaba copiando dejó de funcionar correctamente. (Lo necesitaba externo a webpack porque Handsontable no puede funcionar con webpack.)
Vaccano
@ Vaccano para CSS no deberías usar este método. Utilice un cargador de estilo y un cargador de CSS, consulte aquí: stackoverflow.com/questions/34039826/…
VitalyB
44
En webpack v2 aparentemente no puede omitir el -loadersufijo. por ejemplorequire('file-loader?name=[name].[ext]!../index.html');
pensar demasiado
1
@codeVerine Sí, usando al agregar algo como { test: /index\.html/, loader: 'file-loader', query: { name: '[name].[ext]' }a su loadersmatriz en su archivo de configuración de webpack, solo que no pude conseguir que webpack-dev-server lo sirviera, lo que, curiosamente, solicitó un 404 /(la raíz no existe !).
Brian McCutchon
67

Agregaré una opción a la respuesta de VitalyB:

Opción 3

Vía npm. Si ejecuta sus comandos a través de npm, puede agregar esta configuración a su package.json (consulte también webpack.config.js allí). Para el desarrollo de la ejecución npm start, no es necesario copiar index.html en este caso porque el servidor web se ejecutará desde el directorio de archivos de origen y el bundle.js estará disponible desde el mismo lugar (el bundle.js vivirá solo en la memoria pero estará disponible como si estuviera ubicado junto con index.html). Para la ejecución de producción npm run buildy una carpeta dist contendrá su bundle.js e index.html se copia con el viejo comando cp, como puede ver a continuación:

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

Actualización: Opción 4

Hay una copia-webpack-plugin , como se describe en esta respuesta de Stackoverflow

Pero, en general, a excepción del "primer" archivo (como index.html) y los activos más grandes (como imágenes grandes o videos), incluya css, html, imágenes, etc. directamente en su aplicación a través de requirey el paquete web lo incluirá para usted (bueno, después de configurarlo correctamente con cargadores y posiblemente complementos).

EricC
fuente
11
La opción 3 debería ser la opción 1
Gil Epshtain el
2
Intenté la opción 3, pero la recarga en caliente de index.html no funcionó. ¿No editas tu index.html muy a menudo? Pregunta seria.
piedra
3
Use ncp en lugar de cp si desea admitir entornos de desarrollo entre sistemas operativos
Vivek Maharajh
33

Puede usar CopyWebpackPlugin . Funciona así:

module.exports = {
  plugins: [
    new CopyWebpackPlugin([{
      from: './*.html'
    }])
  ]
}
Hobbeshunter
fuente
Ahora que Webpack ha reemplazado a Gulp y Grunt no solo haciendo paquetes, sino también muchas otras tareas relacionadas con la compilación, esta solución es lo que he visto en la mayoría de los proyectos. Los scripts en package.jsonsolo se usan para cosas simples como iniciar el corredor de prueba o el servidor de desarrollo.
Robert Jack Will
15

Yo diría que la respuesta es: no puedes. (o al menos: no deberías). Esto no es lo que se supone que debe hacer Webpack. Webpack es un paquete y no debe usarse para otras tareas (en este caso: copiar archivos estáticos es otra tarea). Debes usar una herramienta como Grunt o Gulp para hacer tales tareas. Es muy común integrar Webpack como una tarea de Grunt o como una tarea de Gulp . Ambos tienen otras tareas útiles para copiar archivos como usted describió, por ejemplo, grunt-contrib-copy o gulp-copy .

Para otros activos (no el index.html), puede agruparlos con Webpack (para eso es exactamente Webpack). Por ejemplo, var image = require('assets/my_image.png');. Pero supongo que sus index.htmlnecesidades no deben ser parte del paquete y, por lo tanto, no es un trabajo para el paquete.

Brodie Garnet
fuente
59
Precisamente fui a webpack para no tener que usar gruñido o trago. ¿Hay otra alternativa? Si necesito usar gulp, ¿por qué debería molestarme con webpack?
SuperUberDuper
44
La pregunta está al revés. ¿Por qué deberías usar webpack si puedes usar gruñido o trago? Son muy buenos sistemas de tareas / compilación. Webpack (o browserify o r.js) son herramientas que puede usar para agrupar muchos archivos JS (y otros recursos) en uno grande (o múltiples) paquetes de javascript. Debe usar la herramienta correcta para el trabajo. Y de nuevo, es muy común ejecutar webpack, browserify u otros paquetes desde gruñido o trago.
Brodie Garnet
1
Hay muchas formas en que webpack puede hacer eso. Se podría utilizar file-loader, que básicamente sólo copia el archivo / imagen en el directorio de salida y le da la dirección URL cuando lo requiere: var url = require('myFile');. Como dije, un paquete puede ser uno o varios archivos.
Brodie Garnet
1
Podría usar brocolli como proceso de compilación principal
SuperUberDuper
1
Esta es la respuesta correcta para mí. En proyectos grandes / complejos, el rendimiento de la compilación de paquetes web es una consideración importante. Varios complementos de copia de archivos agregan costos innecesarios al paquete web, y permitir que el paquete web se centre en la agrupación JS es una mejor idea.
Evi Song
14

Puede agregar el índice directamente a la configuración de su entrada y usar un cargador de archivos para cargarlo

module.exports = {

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

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

}
Jake Coxon
fuente
5

Para copiar un index.htmlarchivo ya existente en el distdirectorio, simplemente puede usar HtmlWebpackPlugin especificando la fuente index.htmlcomo plantilla .

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

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

El dist/index.htmlarchivo creado será básicamente el mismo que su archivo fuente con la diferencia de que webpack inyecta <script>etiquetas a los recursos agrupados como archivos .js . La minificación y otras opciones se pueden configurar y documentar en github .

Tobi Obeck
fuente
3

Esto funciona bien en Windows:

  1. npm install --save-dev copyfiles
  2. En package.jsontengo una tarea de copia:"copy": "copyfiles -u 1 ./app/index.html ./deploy"

Esto mueve mi index.html de la carpeta de la aplicación a la carpeta de implementación.

Patrick Desjardins
fuente
Entiendo que funciona usando la respuesta allí: stackoverflow.com/questions/38858718/…
IsraGab
3

Para extender la respuesta de @ hobbeshunter si desea tomar solo index.html, también puede usar CopyPlugin. La principal motivación para usar este método sobre el uso de otros paquetes es porque es una pesadilla agregar muchos paquetes para cada tipo y configurarlo, etc. La forma más fácil es usar CopyPlugin para todo:

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

Luego

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

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

Como puede ver, copie toda la carpeta estática junto con todo su contenido en la carpeta dist. No se necesita CSS ni archivos ni ningún otro complemento.

Si bien este método no es adecuado para todo, haría el trabajo de manera simple y rápida.

Remy
fuente
-1

También me pareció fácil y lo suficientemente genérico para poner mi index.html archivo en el dist/ directorio y añadir <script src='main.js'></script>a index.htmlincluir mis archivos WebPack en paquete. main.jsparece ser el nombre de salida predeterminado de nuestro paquete si no se especifica otro en el archivo conf de webpack . Supongo que no es una buena solución a largo plazo, pero espero que pueda ayudar a comprender cómo funciona el paquete web .

Qback
fuente