Fügen Sie Favicon mit React und Webpack hinzu

Lesezeit: 9 Minuten

Ich versuche, ein Favicon zu einer React-basierten Website hinzuzufügen, die ich mit Webpack erstellt habe. Es war ein absoluter Albtraum, ein Favicon hinzuzufügen, und ich habe viele Lösungen ohne Erfolg ausprobiert. Die neueste Lösung, die mir empfohlen wurde, heißt ‚favicons-webpack-plugin‘ und ist hier zu finden: https://github.com/jantimon/favicons-webpack-plugin.

Wenn mir jemand sagen kann, was ich falsch mache, wäre ich für Ihre Hilfe sehr dankbar.

Ich erhalte die folgende Fehlermeldung, wenn ich „npm run start“ ausführe

Geben Sie hier die Bildbeschreibung ein

Dies ist meine Verzeichnisstruktur:

Geben Sie hier die Bildbeschreibung ein

Dies ist meine webpack.config.js-Datei:

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: "https://stackoverflow.com/",                      // Path for overriding default icons path. `string`
        url: "https://stackoverflow.com/",                       // 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
        }
      })
    ]
  });
}

Dies ist meine server.js-Datei:

/* 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("https://stackoverflow.com/", (req, res) => res.sendFile('index.html'));
var port = process.env.PORT || 3000;
app.listen(port, () => console.log(`Server initialized on // ${new Date()}`));

  • Stellen Sie nur sicher, dass es mindestens 16 x 16 ist … und Favicons variieren je nach Browser – einige werden nicht angezeigt, es sei denn, es ist genau 16 x 16, einige 32 x 32, oh, und verwenden Sie png, nicht jpg.

    – Rahel Gallen

    18. Mai 2016 um 14:37 Uhr

  • Ist Ihr Problem, dass Webpack Ihre ico-Datei nicht bündelt? oder ist es, dass die Seite es nicht anzeigt. Sie können verwenden file-loader um wepack die Datei in Ihr Bundle laden zu lassen und sie dann einfach in Ihrer HTML-Seite aufzurufen.

    – BradByte

    14. September 2016 um 15:30 Uhr

  • Hey @CodeYogi, wenn meine Lösung für dich funktioniert hat, möchtest du sie als die richtige Antwort markieren?

    – Lukas Knepper

    8. November 2017 um 17:51 Uhr

Hier ist alles, was Sie brauchen:

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

Das ist definitiv nach dem Hinzufügen von “https://stackoverflow.com/questions/37298215/favicon.gif” zum Ordner “src”.

Dadurch wird das Symbol in Ihren Erstellungsordner übertragen und wie folgt in Ihr Tag aufgenommen <link rel="shortcut icon" href="https://stackoverflow.com/questions/37298215/favicon.gif">. Das ist sicherer, als nur mit zu importieren copyWebpackPLugin

  • Dies ist der einfachste und sicherste Weg als andere Antworten. Guter Punkt für dich.

    – Tryliom

    26. April 2019 um 14:52 Uhr

  • Es wäre hilfreich, dieser Antwort einige Details hinzuzufügen, in welcher Datei füge ich die hinzu new HtmlWebpackPlugin Code? Welches Plugin muss ich installieren? welche config wird benötigt, um dies zu verwenden?

    – Gipfel

    8. August 2020 um 1:09 Uhr

  • @Sumit Sie werden brauchen 'html-webpack-plugin'. Weitere Informationen finden Sie in der Dokumentation. Das obige Beispiel funktioniert nicht sofort, Sie müssen es zumindest hinzufügen template und filename Optionen.

    – iamfrank

    12. Oktober 2020 um 23:19 Uhr

  • Knallharte Lösung.

    – DoneDeal0

    3. April 2021 um 9:03 Uhr

  • Ich sehe das Favicon in meinem Desktop-Webbrowser, aber es wird nicht in meinem Webbrowser auf Android angezeigt, ist das zu erwarten? Brauche ich eine bestimmte Größe oder so? Ich verwende ein PNG im Format 64×64

    – Javier Guzman

    5. April 2021 um 11:21 Uhr

Benutzer-Avatar
Matúš Šťastný

Für zukünftige Googler: Sie können auch verwenden copy-webpack-plugin und fügen Sie dies der Produktionskonfiguration von Webpack hinzu:

plugins: [
  new CopyWebpackPlugin({ 
    patterns: [ 
     // relative path is from src
     { from: './static/favicon.ico' }, // <- your path to favicon
    ]
 })
]

  • Zweifellos die bisher beste und kompakteste Lösung. Beachten Sie, dass sich meine webpack.config.js im Stammverzeichnis befindet, sodass ich sie verwenden musste ./src/favicon.ico den richtigen Weg zu zielen.

    – Seidenfeuer

    4. August 2018 um 1:10 Uhr

  • Beachten Sie, dass Sie Folgendes tun müssen: $ npm install copy-webpack-plugin –save-dev Fügen Sie dann am Anfang Ihrer webpack.config.js hinzu: const CopyWebpackPlugin = require(‘copy-webpack-plugin’);

    – JohnFlux

    10. April 2020 um 23:50 Uhr


  • API geändert. Jetzt sollte sein: new CopyWebpackPlugin({ Muster: [ { from: ‘./static/favicon.ico’ }, ]}),

    – Djee

    18. August 2020 um 5:57 Uhr


  • Danke für den Hinweis, ich habe gerade meine Antwort aktualisiert ⬆️

    – Matúš Šťastný

    19. August 2020 um 10:47 Uhr

Benutzer-Avatar
Haswin

Fügen Sie Ihr Favicon einfach in die hinzu public Ordner sollte reichen. Stellen Sie sicher, dass das Favicon benannt ist als favicon.ico.

Benutzer-Avatar
Jiah827

So habe ich es gemacht.

öffentlich/index.html

Ich habe die generierten Favicon-Links hinzugefügt.

...
<link rel="icon" type="image/png" sizes="32x32" href="https://stackoverflow.com/questions/37298215/%PUBLIC_URL%/path/to/favicon-32x32.png" />
<link rel="icon" type="image/png" sizes="16x16" href="%PUBLIC_URL%/path/to/favicon-16x16.png" />
<link rel="shortcut icon" href="%PUBLIC_URL%/path/to/favicon.ico" type="image/png/ico" />

webpack.config.js

new HTMLWebpackPlugin({
   template: '/path/to/index.html',
   favicon: '/path/to/favicon.ico',
})

Notiz

ich benutze historyApiFallback im Dev-Modus, aber ich musste keine zusätzliche Einrichtung vornehmen, um das Favicon zum Laufen zu bringen, noch auf der Serverseite.

Browser suchen nach Ihrem Favicon in /favicon.ico, da muss es also sein. Sie können überprüfen, ob Sie es an der richtigen Stelle positioniert haben, indem Sie zu navigieren [address:port]/favicon.ico und sehen, ob Ihr Symbol erscheint.

Im Entwicklermodus verwenden Sie historyApiFallback, daher müssen Sie das Webpack so konfigurieren, dass es Ihr Symbol für diese Route explizit zurückgibt:

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

In deiner server.js versuchen Sie, die URL explizit umzuschreiben:

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

(oder wie auch immer Ihr Setup es vorzieht, URLs umzuschreiben)

Ich schlage vor, ein true zu generieren .ico Datei, anstatt eine .pngda ich festgestellt habe, dass dies in allen Browsern zuverlässiger ist.

Eine andere Alternative ist

npm install react-favicon

Und in Ihrer Bewerbung würden Sie einfach Folgendes tun:

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

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

Die richtigen Antworten:

Wenn Sie webpack direkt verwenden:

new HtmlWebpackPlugin({
   favicon: "./public/fav-icon.ico"
})

Wenn Sie CRA (create-react-app) verwenden, können Sie die manifest.json im öffentlichen Verzeichnis

1228860cookie-checkFügen Sie Favicon mit React und Webpack hinzu

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy