web-dev-qa-db-fra.com

Ajouter un favicon avec React et Webpack

J'essaie d'ajouter un favicon à un site Web basé sur React que j'ai créé à l'aide de webpack. Ajouter un favicon a été un véritable cauchemar et j'ai essayé de nombreuses solutions en vain. La dernière solution qui m'a été recommandée s'appelle 'favicons-webpack-plugin', que l'on peut trouver ici: https://github.com/jantimon/favicons-webpack-plugin

Si quelqu'un pouvait me dire ce que je faisais mal, votre aide serait grandement appréciée. 

Je reçois le message d'erreur suivant lorsque je lance npm run start

enter image description here

Ceci est ma structure de répertoire:

enter image description here

Ceci est mon fichier webpack.config.js:

const path = require('path');
const merge = require('webpack-merge');
const webpack = require('webpack');
const NpmInstallPlugin = require('npm-install-webpack-plugin');
const TARGET = process.env.npm_lifecycle_event;
const FaviconsWebpackPlugin = require('favicons-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanPlugin = require('clean-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
var favicons = require('favicons'),
    source = 'my-logo.png',           // Source image(s). `string`, `buffer` or array of `{ size: filepath }`
    configuration = {
        appName: null,                  // Your application's name. `string`
        appDescription: null,           // Your application's description. `string`
        developerName: null,            // Your (or your developer's) name. `string`
        developerURL: null,             // Your (or your developer's) URL. `string`
        background: "#fff",             // Background colour for flattened icons. `string`
        path: "/",                      // Path for overriding default icons path. `string`
        url: "/",                       // Absolute URL for OpenGraph image. `string`
        display: "standalone",          // Android display: "browser" or "standalone". `string`
        orientation: "portrait",        // Android orientation: "portrait" or "landscape". `string`
        version: "1.0",                 // Your application's version number. `number`
        logging: false,                 // Print logs to console? `boolean`
        online: false,                  // Use RealFaviconGenerator to create favicons? `boolean`
        icons: {
            Android: true,              // Create Android homescreen icon. `boolean`
            appleIcon: true,            // Create Apple touch icons. `boolean`
            appleStartup: true,         // Create Apple startup images. `boolean`
            coast: true,                // Create Opera Coast icon. `boolean`
            favicons: true,             // Create regular favicons. `boolean`
            firefox: true,              // Create Firefox OS icons. `boolean`
            opengraph: true,            // Create Facebook OpenGraph image. `boolean`
            Twitter: true,              // Create Twitter Summary Card image. `boolean`
            windows: true,              // Create Windows 8 tile icons. `boolean`
            yandex: true                // Create Yandex browser icon. `boolean`
        }
    },
    callback = function (error, response) {
        if (error) {
            console.log(error.status);  // HTTP error code (e.g. `200`) or `null`
            console.log(error.name);    // Error name e.g. "API Error"
            console.log(error.message); // Error description e.g. "An unknown error has occurred"
        }
        console.log(response.images);   // Array of { name: string, contents: <buffer> }
        console.log(response.files);    // Array of { name: string, contents: <string> }
        console.log(response.html);     // Array of strings (html elements)
    };

favicons(source, configuration, callback);
const pkg = require('./package.json');

const PATHS = {
  app: path.join(__dirname, 'app'),
  build: path.join(__dirname, 'build')
};

process.env.BABEL_ENV = TARGET;

const common = {
  entry: {
    app: PATHS.app
  },
  // Add resolve.extensions
  // '' is needed to allow imports without an extension
  // note the .'s before the extension as it will fail to load without them
  resolve: {
    extensions: ['', '.js', '.jsx', '.json']
  },
  output: {
    path: PATHS.build,
    filename: 'bundle.js'
  },
  module: {
    loaders: [
      {
        // Test expects a RegExp! Notethe slashes!
        test: /\.css$/,
        loaders: ['style', 'css'],
        //Include accepts either a path or an array of paths
        include: PATHS.app

      },
      //set up JSX. This accepts js too thanks to RegExp
      {
      test: /\.(js|jsx)$/,
      //enable caching for improved performance during development
      //It uses default OS directory by default. If you need something more custom,
      //pass a path to it. ie: babel?cacheDirectory=<path>
      loaders: [
        'babel?cacheDirectory,presets[]=es2015'
    ],
      //parse only app files Without this it will go thru the entire project.
      //beside being slow this will likely result in an error
      include: PATHS.app
      }
    ]
  }
};

// Default configuration. We will return this if
// Webpack is called outside of npm.
if(TARGET === 'start' || !TARGET){
  module.exports = merge(common, {
    devtool: 'eval-source-map',
    devServer: {
      contentBase: PATHS.build,

      //enable history API fallback so HTML5 HISTORY API based
      // routing works. This is a good default that will come in handy in more
      // complicated setups.
      historyApiFallback: true,
      hot: true,
      inline: true,
      progress: true,

      //display only errors to reduce output amount
      stats: 'errors only',

      //Parse Host and port from env so this is easy to customize
      Host: process.env.Host,
      port: process.env.PORT

},

plugins: [
  new webpack.HotModuleReplacementPlugin(),
  new NpmInstallPlugin({
    save: true //--save
  }),
  new FaviconsWebpackPlugin('my-logo.png')

]
});
}

if(TARGET === 'build' || TARGET === 'stats') {
  module.exports = merge(common, {
    entry: {
      vendor: Object.keys(pkg.dependencies).filter(function(v) {
        return v !== 'alt-utils';
      }),
      style: PATHS.style
    },
    output: {
      path: PATHS.build,
      // Output using entry name
      filename: '[name].[chunkhash].js',
      chunkFilename: '[chunkhash].js'
    },
    module: {
      loaders: [
        // Extract CSS during build
        {
          test: /\.css$/,
          loader: ExtractTextPlugin.extract('style', 'css'),
          include: PATHS.app
        }
      ]
    },
    plugins: [
      // Output extracted CSS to a file
      new ExtractTextPlugin('[name].[chunkhash].css'),
      // Extract vendor and manifest files
      new webpack.optimize.CommonsChunkPlugin({
        names: ['vendor', 'manifest']
      }),
      // Setting DefinePlugin affects React library size!
      new webpack.DefinePlugin({
        'process.env.NODE_ENV': '"production"'
      }),
      new webpack.optimize.UglifyJsPlugin({
        compress: {
          warnings: false
        }
      })
    ]
  });
}

Ceci est mon fichier server.js:

/* Global Requires */

const express    = require('express');
const logger     = require('morgan');
const bodyParser = require('body-parser');
const path       = require('path');
const app        = express();
const ReactDOM = require('react-dom')
var favicon = require('serve-favicon');


if(process.env.NODE_ENV === 'development') {
  console.log('in development.');
  require('dotenv').config();
} else {
  console.log('in production.');
}

/* App Config */
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.use(express.static(path.join(__dirname, 'build')));
app.use(favicon(__dirname + '/public/favicon.ico'));

app.use(logger('dev'));

/* Server Initialization */
app.get('/', (req, res) => res.sendFile('index.html'));
var port = process.env.PORT || 3000;
app.listen(port, () => console.log(`Server initialized on // ${new Date()}`));
27
CodeYogi

Pour les futurs utilisateurs: Vous pouvez également utiliser copy-webpack-plugin et l'ajouter à la configuration de la production de webpack:

plugins: [
  new CopyWebpackPlugin([
    // relative path is from src
    { from: './static/favicon.ico' }, // <- your path to favicon
  ])
]
15
Matúš Šťastný

Les navigateurs recherchent votre favicon dans /favicon.ico, c'est donc ce qu'il faut. Vous pouvez vérifier si vous l'avez placé au bon endroit en naviguant dans [address:port]/favicon.ico et en vérifiant si votre icône apparaît.

En mode dev, vous utilisez historyApiFallback, vous devrez donc configurer Webpack pour qu'il retourne explicitement votre icône pour cette route:

historyApiFallback: {
    index: '[path/to/index]',
    rewrites: [
        // shows favicon
        { from: /favicon.ico/, to: '[path/to/favicon]' }
    ]
}

Dans votre fichier server.js, essayez de réécrire explicitement l'URL:

app.configure(function() {
    app.use('/favicon.ico', express.static(__dirname + '[route/to/favicon]'));
});

(ou si votre configuration préfère réécrire les URL)

Je suggère de générer un vrai fichier .ico plutôt que d'utiliser un .png, car je trouve que cela est plus fiable pour tous les navigateurs.

7
Luke Knepper

Ajouter votre favicon simplement dans le dossier public devrait faire l'affaire. Assurez-vous que le favicon est nommé "favicon.ico".

6
Haswin Vidanage

Voici tout ce dont vous avez besoin:

new HtmlWebpackPlugin({
    favicon: "./src/favicon.gif"
})

C'est certainement après avoir ajouté "favicon.gif" au dossier "src".

Cela transférera l'icône dans votre dossier de construction et l'inclura dans votre balise comme ceci <link rel="shortcut icon" href="favicon.gif">. C’est plus sûr que de simplement importer avec copyWebpackPLugin

5
Akintunde

Une autre alternative est

npm install react-favicon

Et dans votre application, vous feriez simplement:

   import Favicon from 'react-favicon';
   //other codes

    ReactDOM.render(
        <div>
            <Favicon url="/path/to/favicon.ico"/>
            // do other stuff here
        </div>
        , document.querySelector('.react'));
3
mel3kings

Cela revient à ajouter tout autre script ou feuille de style externe. Tout ce que vous avez à faire est de vous concentrer sur le type chemin correct et rel et type .

Remarque: lorsque mon image de favicon était dans le dossier des actifs, il s’agissait de ne affichant pas le favicon. Donc, je ai copié l'image dans le même dossier que mon index.html et cela a parfaitement fonctionné comme il se doit.

<head>
    <link rel="shortcut icon" type="image/png/ico" href="/favicon.png" />
    <title>SITE NAME</title>
</head>

Cela a fonctionné pour moi. J'espère que ça marchera pour toi aussi.

2
Prakhar Mittal

Voici comment je l'ai fait.

  1. en public/index.html

    Ajoute des liens de favicon générés

  2. dans src/App.js

    import '/path/to/favicon.ico';

  3. dans webpack.js

    nouveau HTMLWebpackPlugin ({ favicon: '/path/to/favicon.ico' ,}),

Remarque. J'utilise historyApiFallback en mode dev, mais je n'avais besoin d'aucune configuration supplémentaire pour que le favicon fonctionne, ni du côté serveur.

0
Jiah827

Je vais donner des étapes simples pour ajouter un favicon :-) 

  • Créez votre logo et enregistrez-le sous logo.png 
  • Remplacez logo.png par favicon.ico 

    Remarque: lorsque vous sauvegardez, il s'agit de favicon.ico, assurez-vous que ce n'est pas favicon.ico.png 

  • Il faudra peut-être un peu de temps pour mettre à jour 

    changez la taille de l'icône dans manifest.json si vous ne pouvez pas attendre

0
Chawki

Utilisez le file-loader pour cela: 

{
    test: /\.(svg|png|gif|jpg|ico)$/,
    include: path.resolve(__dirname, path),
    use: {
        loader: 'file-loader',
        options: {
            context: 'src/assets',
            name: 'root[path][name].[ext]'
        }
    }
}
0
shmidtdan