Webpack.config comment copier simplement l'index.html dans le dossier dist

192

J'essaie d'automatiser les actifs entrant dans / dist. J'ai le config.js suivant:

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

Je souhaite également inclure main.html du répertoire qui se trouve à côté de / lib, dans le dossier / dist lors de l'exécution de webpack. Comment puis-je faire ceci?

MISE À JOUR 1 2017_____________

Ma façon préférée de le faire maintenant est d'utiliser le html-webpack-pluginavec un fichier modèle. Merci aussi à la réponse acceptée! L'avantage de cette façon est que le fichier d'index aura également le lien js cachbusted ajouté hors de la boîte!

SuperUberDuper
la source

Réponses:

164

Option 1

Dans votre index.jsfichier (c'est-à-dire l'entrée webpack), ajoutez un require à votre plugin index.htmlvia file-loader , par exemple:

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

Une fois que vous avez construit votre projet avec webpack, index.htmlsera dans le dossier de sortie.

Option 2

Utilisez html-webpack-plugin pour éviter d'avoir un index.html du tout. Demandez simplement à Webpack de générer le fichier pour vous.

VitalyB
la source
2
puis-je en quelque sorte le charger en écrivant quelque chose dans le fichier de configuration lui-même?
codeVerine
J'ai essayé la première façon, et il a copié les fichiers. Mais le CSS que je copiais a cessé de fonctionner correctement. (J'en avais besoin externe au webpack car Handsontable ne peut pas fonctionner avec webpack.)
Vaccano
@Vaccano pour CSS, vous ne devriez pas utiliser cette méthode. Utilisez un chargeur de style et un chargeur css, voir ici: stackoverflow.com/questions/34039826/…
VitalyB
4
Dans webpack v2, vous ne pouvez apparemment pas omettre le -loadersuffixe. par exemplerequire('file-loader?name=[name].[ext]!../index.html');
Overhink
1
@codeVerine Oui, en ajoutant quelque chose comme { test: /index\.html/, loader: 'file-loader', query: { name: '[name].[ext]' }à votre loaderstableau dans votre fichier de configuration webpack, seulement je n'ai pas pu obtenir de webpack-dev-server pour le servir, ce qui a conduit, assez curieusement, à un 404 en requête /(la racine n'existe pas !).
Brian McCutchon
68

J'ajouterai une option à la réponse de VitalyB:

Option 3

Via npm. Si vous exécutez vos commandes via npm, vous pouvez ajouter cette configuration à votre package.json (consultez également le webpack.config.js là aussi). Pour le développement de run npm start, pas besoin de copier index.html dans ce cas car le serveur web sera exécuté à partir du répertoire des fichiers source, et le bundle.js sera disponible au même endroit (le bundle.js ne vivra qu'en mémoire mais sera disponible comme s'il était localisé avec index.html). Pour la production npm run build, un dossier dist contiendra votre bundle.js et index.html sera copié avec la bonne vieille commande cp, comme vous pouvez le voir ci-dessous:

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

Mise à jour: option 4

Il existe un plugin copy-webpack , comme décrit dans cette réponse Stackoverflow

Mais généralement, à l'exception du tout "premier" fichier (comme index.html) et des éléments plus volumineux (comme de grandes images ou des vidéos), incluez le css, le html, les images et ainsi de suite directement dans votre application via requireet webpack l'inclura pour vous (enfin, après l'avoir configuré correctement avec des chargeurs et éventuellement des plugins).

EricC
la source
11
L'option 3 devrait être l'option 1
Gil Epshtain
2
J'ai essayé l'option 3, mais le rechargement à chaud de index.html n'a pas fonctionné. Ne modifiez-vous pas votre index.html très souvent? Question sérieuse.
pierre
3
Utilisez ncp au lieu de cp si vous souhaitez prendre en charge les environnements de développement multi-OS
Vivek Maharajh
36

Vous pouvez utiliser CopyWebpackPlugin . Cela fonctionne comme ça:

module.exports = {
  plugins: [
    new CopyWebpackPlugin([{
      from: './*.html'
    }])
  ]
}
hobbeshunter
la source
Maintenant que Webpack a remplacé Gulp et Grunt en faisant non seulement du regroupement, mais aussi de nombreuses autres tâches liées à la construction, cette solution est ce que j'ai vu dans la plupart des projets. Les scripts dans package.jsonne sont utilisés que pour des choses simples comme démarrer le testeur ou le serveur de développement.
Robert Jack Will
15

Je dirais que la réponse est: vous ne pouvez pas. (ou du moins: vous ne devriez pas). Ce n'est pas ce que Webpack est censé faire. Webpack est un bundler, et il ne doit pas être utilisé pour d'autres tâches (dans ce cas: la copie de fichiers statiques est une autre tâche). Vous devez utiliser un outil comme Grunt ou Gulp pour effectuer de telles tâches. Il est très courant d'intégrer Webpack en tant que tâche Grunt ou en tant que tâche Gulp . Ils ont tous deux d'autres tâches utiles pour copier des fichiers comme vous l'avez décrit, par exemple, grunt-contrib-copy ou gulp-copy .

Pour les autres actifs (pas le index.html), vous pouvez simplement les regrouper avec Webpack (c'est exactement à quoi sert Webpack). Par exemple var image = require('assets/my_image.png');,. Mais je suppose que vous index.htmlne devez pas faire partie du bundle, et donc ce n'est pas un travail pour le bundler.

Brodie Grenat
la source
60
Je suis précisément allé sur Webpack pour ne pas avoir besoin d'utiliser grunt ou gulp. Il y a t'il d'autres solutions? Si j'ai besoin d'utiliser gulp, pourquoi devrais-je me soucier de webpack?
SuperUberDuper
4
La question est à l'envers. Pourquoi devriez-vous utiliser webpack si vous pouvez utiliser grunt ou gulp? Ce sont de très bons systèmes de tâche / construction. Webpack (ou browserify ou r.js) sont des outils que vous pouvez utiliser pour regrouper de nombreux fichiers JS (et d'autres ressources) en un seul gros (ou plusieurs) bundles javascript. Vous devez utiliser le bon outil pour le travail. Et encore une fois, il est très courant d'exécuter webpack, browserify ou d'autres bundlers à partir de grunt ou gulp.
Brodie Garnet
1
Webpack peut le faire de plusieurs manières. Vous pouvez utiliser file-loaderqui fondamentalement juste copie le fichier / image dans le répertoire de sortie et vous donne l'URL lorsque vous l' exige: var url = require('myFile');. Comme je l'ai dit, un bundle peut être un ou plusieurs fichiers.
Brodie Garnet
1
Je pourrais utiliser brocolli comme processus de construction parent
SuperUberDuper
1
C'est la bonne réponse pour moi. Dans les projets de grande envergure / complexes, les performances de compilation du webpack sont une considération importante. Divers plugins de copie de fichiers ajoutent des coûts inutiles au webpack, laisser le webpack se concentrer sur le regroupement JS est une meilleure idée.
Evi Song
14

Vous pouvez ajouter l'index directement à votre configuration d'entrée et en utilisant un chargeur de fichiers pour le charger

module.exports = {

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

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

}
Jake Coxon
la source
8

Pour copier un index.htmlfichier déjà existant dans le distrépertoire, vous pouvez simplement utiliser le HtmlWebpackPlugin en spécifiant la source index.htmlcomme modèle .

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

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

Le dist/index.htmlfichier créé sera fondamentalement le même que votre fichier source à la différence que les ressources groupées comme les fichiers .js sont injectées avec des <script>balises par webpack. La minification et d'autres options peuvent être configurées et sont documentées sur github .

Tobi Obeck
la source
4

Pour étendre la réponse de @ hobbeshunter si vous ne voulez prendre que index.html, vous pouvez également utiliser CopyPlugin. Le moyen le plus simple est d'utiliser CopyPlugin pour tout:

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

ensuite

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

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

Comme vous pouvez le voir, copiez tout le dossier statique avec tout son contenu dans le dossier dist. Aucun css ou fichier ou tout autre plug-in nécessaire.

Bien que cette méthode ne convienne pas à tout, elle ferait le travail simplement et rapidement.

Remy
la source
3

Cela fonctionne bien sur Windows:

  1. npm install --save-dev copyfiles
  2. Dans package.jsonj'ai une tâche de copie:"copy": "copyfiles -u 1 ./app/index.html ./deploy"

Cela déplace mon index.html du dossier de l'application vers le dossier de déploiement.

Patrick Desjardins
la source
Je l'obtiens fonctionne en utilisant la réponse ici: stackoverflow.com/questions/38858718/…
IsraGab
-1

J'ai aussi trouvé facile et assez générique pour mettre mon index.html fichier dans le dist/ répertoire et ajouter <script src='main.js'></script>à index.htmlinclure mes fichiers webpack empaquetés. main.jssemble être le nom de sortie par défaut de notre bundle si aucun autre n'est spécifié dans le fichier conf de webpack . Je suppose que ce n'est pas une bonne solution à long terme, mais j'espère que cela peut aider à comprendre le fonctionnement du Webpack .

Qback
la source