Fügen Sie Favicon mit React und Webpack hinzu

74

Ich versuche, einer React-basierten Website, die ich mit Webpack erstellt habe, ein Favicon hinzuzufügen. Es war ein totaler 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 Ihre Unterstützung sehr dankbar.

Ich erhalte die folgende Fehlermeldung, wenn ich 'npm run start' ausführe.

Geben Sie hier die Bildbeschreibung ein

Das ist meine Verzeichnisstruktur:

Geben Sie hier die Bildbeschreibung ein

Dies ist meine Datei 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
        }
      })
    ]
  });
}

Dies ist meine Datei 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()}`));
CodeYogi
quelle
Stellen Sie einfach sicher, dass es mindestens 16x16 ist ... und die Favoriten variieren von Browser zu Browser - einige werden nur angezeigt, wenn es genau 16x16 ist, einige 32x32, oh, und verwenden Sie png not jpg ..
Rachel Gallen
Ist Ihr Problem, dass Webpack Ihre ICO-Datei nicht bündelt? oder wird es auf der Seite nicht angezeigt? Sie können file-loaderWepack verwenden, um die Datei in Ihr Bundle zu laden und sie dann einfach auf Ihrer HTML-Seite aufzurufen.
Brad B
1
Hey @CodeYogi, wenn meine Lösung für Sie funktioniert, möchten Sie sie als die richtige Antwort markieren?
Luke Knepper

Antworten:

110

Hier ist alles was Sie brauchen:

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

Das ist definitiv nach dem Hinzufügen von "favicon.gif" zum Ordner "src".

Dadurch wird das Symbol in Ihren Build-Ordner übertragen und wie folgt in Ihr Tag aufgenommen <link rel="shortcut icon" href="favicon.gif">. Dies ist sicherer als nur das Importieren mitcopyWebpackPLugin

Akintunde
quelle
7
Dies ist der einfachste und sicherste Weg als andere Antworten. Guter Punkt für Sie.
Tutturuuu
5
Das Hinzufügen einiger Details zu dieser Antwort wäre hilfreich. In welcher Datei füge ich den new HtmlWebpackPluginCode hinzu? Welches Plugin muss ich installieren? Welche Konfiguration wird benötigt, um dies zu verwenden?
Sumit
2
@ Sumit Du wirst brauchen 'html-webpack-plugin'. Weitere Informationen finden Sie in der Dokumentation. Das obige Beispiel funktioniert nicht sofort, Sie müssen mindestens templateund filenameOptionen hinzufügen .
iamfrank
24

Für zukünftige Googler: Sie können auch das Copy-Webpack-Plugin verwenden und dieses zur Produktionskonfiguration von Webpack hinzufügen:

plugins: [
  new CopyWebpackPlugin({ 
    patterns: [ 
     // relative path is from src
     { from: './static/favicon.ico' }, // <- your path to favicon
    ]
 })
]
Matúš Šťastný
quelle
1
Zweifellos die bisher beste und konsequenteste Lösung. Beachten Sie, dass sich meine webpack.config.js im Stammverzeichnis befindet, sodass ich ./src/favicon.icoden richtigen Pfad als Ziel festlegen musste .
Seidenfeuer
1
Beachten Sie, dass Sie Folgendes tun müssen: $ npm install copy-webpack-plugin --save-dev Fügen Sie dann oben in Ihrer webpack.config.js Folgendes hinzu: const CopyWebpackPlugin = require ('copy-webpack-plugin');
JohnFlux
1
API geändert. Jetzt sollte sein: neues CopyWebpackPlugin ({pattern: [{from: './static/favicon.ico'},]}),
Djee
Vielen Dank für den Hinweis, ich habe gerade meine Antwort aktualisiert Mat
Matúš Šťastný
21

Das Hinzufügen Ihres Favicons einfach zum publicOrdner sollte reichen. Stellen Sie sicher, dass das Favicon den Namen hat favicon.ico.

Haswin
quelle
12

Hier ist, wie ich es gemacht habe.

public / index.html

Ich habe die generierten Favicon-Links hinzugefügt.

...
<link rel="icon" type="image/png" sizes="32x32" href="%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',
})

Hinweis

Ich verwende historyApiFallbackim Dev-Modus, aber ich brauchte kein zusätzliches Setup, um das Favicon zum Laufen zu bringen, noch auf der Serverseite.

Jiah827
quelle
8

Browser suchen nach Ihrem Favicon /favicon.ico, also muss es dort sein. Sie können überprüfen, ob Sie es an der richtigen Stelle positioniert haben, indem Sie zu [address:port]/favicon.icoIhrem Symbol navigieren und prüfen, ob es angezeigt wird.

Im Entwicklungsmodus verwenden Sie historyApiFallback. Daher müssen Sie das Webpack so konfigurieren, dass Ihr Symbol für diese Route explizit zurückgegeben wird:

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

server.jsVersuchen Sie in Ihrer Datei, die URL explizit neu zu schreiben:

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

(oder Ihr Setup zieht es jedoch vor, URLs neu zu schreiben)

Ich schlage vor, eine echte .icoDatei zu generieren, anstatt eine zu verwenden .png, da ich festgestellt habe, dass dies für alle Browser zuverlässiger ist.

Luke Knepper
quelle
8

Eine andere Alternative ist

npm install react-favicon

Und in Ihrer Bewerbung würden Sie einfach 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'));
mel3kings
quelle
Dies ist eine großartige Antwort, wenn ein Favicon aus Variablen im DOM abgeleitet wird. Vielen Dank für Ihre Antwort.
Mitchken
4

Dies entspricht dem Hinzufügen eines anderen externen Skripts oder Stylesheets. Alles, was Sie tun müssen, ist sich darauf zu konzentrieren, den richtigen Pfad und rel und Typ anzugeben .

Hinweis: Wenn sich mein Favicon-Image im Assets-Ordner befand , wurde das Favicon nicht angezeigt . Also habe ich das Bild in den gleichen Ordner wie meine index.html kopiert und es hat perfekt funktioniert, wie es sollte.

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

Es hat bei mir funktioniert. Hoffe es funktioniert auch bei dir.

Prakhar Mittal
quelle
2

Verwenden Sie dazu den File-Loader :

{
    test: /\.(svg|png|gif|jpg|ico)$/,
    include: path.resolve(__dirname, path),
    use: {
        loader: 'file-loader',
        options: {
            context: 'src/assets',
            name: 'root[path][name].[ext]'
        }
    }
}
shmidtdan
quelle
Sie sollten auch das Favicon mit HtmlWebpackPluginfür die korrekte Arbeit hinzufügen , nicht nur das.
Tutturuuu
2

Ich werde einfache Schritte geben, um Favicon hinzuzufügen :-)

  • Erstellen Sie Ihr Logo und speichern Sie unter logo.png
  • Wechseln Sie logo.pngzufavicon.ico

    Hinweis : Wenn Sie es speichern, favicon.icostellen Sie sicher, dass dies nicht der Fall istfavicon.ico.png

  • Das Update kann einige Zeit dauern

    Ändern Sie die Symbolgröße in manifest.json, wenn Sie nicht warten können

CK
quelle
3
Anstatt zu ändern manifest.json, sollten Sie den Cache im Browser leeren. Auf Chrome ist es cmd + shift + r/ ctrl + shift + r.
Tutturuuu
1

In meinem Fall - ich bin mit Visual Studio (Professional 2017) im Debug - Modus mit webpack 2.4.1 - war es notwendig , die setzen favicon.icoin das Stammverzeichnis des Projektes, genau dort , wo der Ordner srcist , anstatt in einem Ordner public, auch Laut https://create-react-app.dev/docs/using-the-public-folder sollte letzterer der offizielle Speicherort sein.

B - rian
quelle
1

Ich benutze das Favicons-Webpack-Plugin

const FaviconsWebpackPlugin = require("favicons-webpack-plugin");

module.exports={
plugins:[
    new FaviconsWebpackPlugin("./public/favicon.ico"),
//public is in the root folder in this app. 

]
}
Yilmaz
quelle
0

Die richtige Antwort in der Gegenwart, wenn Sie die Create React App nicht verwenden, ist die nächste:

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

Wenn Sie CRA verwenden, können Sie die Datei manifest.json im öffentlichen Verzeichnis ändern

Marco Mesen
quelle
0
This worked for me:

Add this in index.html (inside src folder along with favicon.ico)

**<link rel="icon" href="/src/favicon.ico" type="image/x-icon" />**

webpack.config.js is like:

 plugins: [new HtmlWebpackPlugin({`enter code here`
        template: './src/index.html'
    })],
Piyali
quelle
Diese Implementierung ist falsch. Sollte Favicon in HtmlWebpackPlugin
atom217