使用React和Webpack添加Favicon


75

我试图将图标添加到使用webpack创建的基于React的网站上。添加favicon完全是一场噩梦,而我尝试了许多解决方案都无济于事。向我推荐的最新解决方案称为“ favicons-webpack-plugin”,可在以下位置找到:https : //github.com/jantimon/favicons-webpack-plugin

如果有人能告诉我我做错了什么,将非常感谢您的协助。

当我运行'npm run start'时出现以下错误

在此处输入图片说明

这是我的目录结构:

在此处输入图片说明

这是我的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
        }
      })
    ]
  });
}

这是我的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()}`));

只需确保其至少16x16 ...以及网站图标在浏览器中有所不同-除非它的16x16恰好是32x32,否则不会显示,哦,并使用png而不是jpg。–
Rachel Gallen

您的问题是webpack不捆绑您的ico文件吗?还是页面没有显示它。您可以使用file-loaderwepack将文件加载到文件包中,然后在html页面中调用它。
Brad B

1
嘿@CodeYogi,如果我的解决方案对您有用,您是否要将其标记为正确答案?
卢克·克内珀

Answers:


119

这就是您所需要的:

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

绝对是在将“ favicon.gif”添加到文件夹“ src”之后。

这样会将图标传输到您的构建文件夹,并将其包含在您的标签中,如下所示<link rel="shortcut icon" href="favicon.gif">。这比仅导入copyWebpackPLugin


8
这是比其他响应方式最简单,最安全的方法。给你的好点。
Tutturuuu

7
在此答案中添加一些详细信息将很有帮助,我应在哪个文件中添加new HtmlWebpackPlugin代码?我需要安装哪个插件?使用此需要什么配置?
萨米特

2
@Sumit您将需要'html-webpack-plugin'。您可以查看其文档以获取更多详细信息。上面的示例开箱即用,您需要至少添加templatefilename选项。
iamfrank

24

对于未来的Google员工:您还可以使用copy-webpack-plugin并将其添加到webpack的生产配置中:

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

1
传递迄今为止最好,最简洁的解决方案。请注意,我的webpack.config.js位于根目录中,因此我不得不使用它./src/favicon.ico来定位正确的路径。
Silkfire '18

1
请注意,您需要执行以下操作:$ npm install copy-webpack-plugin --save-dev然后在webpack.config.js的顶部添加:const CopyWebpackPlugin = require('copy-webpack-plugin');
JohnFlux

1
API已更改。现在应该是:new CopyWebpackPlugin({pattern:[{from:'./static/favicon.ico'},]}),
Djee

感谢您的通知,我刚刚更新了答案⬆️
MatúšŠťastný20年

21

只需将您的收藏public夹图标添加到文件夹即可。确保图标被命名为favicon.ico


12

这是我做的。

public / index.html

我已经添加了生成的图标链接。

...
<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',
})

注意

historyApiFallback在开发人员模式下使用,但是我不需要进行任何其他设置即可获得Favicon的工作,也无需在服务器端进行设置。


8

浏览器在中查找您的收藏夹图标/favicon.ico,因此需要它。您可以通过导航到[address:port]/favicon.ico并查看是否出现图标来仔细检查是否已将其放置在正确的位置。

在开发人员模式下,您使用的是historyApiFallback,因此需要配置webpack以显式返回该路线的图标:

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

在您的server.js文件中,尝试显式重写URL:

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

(或者您的设置更喜欢重写网址)

我建议生成一个真实的.ico文件而不是使用.png,因为我发现它在所有浏览器中都更可靠。


8

另一种选择是

npm install react-favicon

在您的应用程序中,您只需执行以下操作:

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

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

当图标从DOM中的变量派生时,这是一个很好的答案,谢谢您的回答。
mitchken '19

5

与添加任何其他外部脚本或样式表相同。您要做的就是专注于给出正确的路径相关性类型

注意:当我的收藏图像位于assets文件夹中时,它没有显示收藏图标。因此,我将图像复制到了与index.html相同的文件夹中,它可以正常工作。

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

它为我工作。希望它也对您有用。


2

为此使用文件加载器

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

您还应该添加faviconHtmlWebpackPlugin才能正常工作,不仅限于此。
Tutturuuu

2

我将给出简单的步骤来添加favicon :-)

  • 创建徽标并另存为 logo.png
  • 更改logo.pngfavicon.ico

    注意保存时请favicon.ico确保没有favicon.ico.png

  • 更新可能需要一些时间

    如果等不及了,请更改manifest.json中的图标大小


3
而不是Modify manifest.json,您应该清除浏览器上的缓存。在Chrome上是cmd + shift + r/ ctrl + shift + r
Tutturuuu


1

我使用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. 

]
}

1

如果您不使用Create React App,那么当前的正确答案是下一个:

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

如果使用CRA,则可以修改公共目录中的manifest.json


1

将公用文件夹中的favicon.ico替换为您的公用文件夹,这应该可以助您一臂之力。


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

这个实现是错误的。应该补充图标内HtmlWebpackPlugin
atom217
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.