【问题标题】:Add Favicon with React and Webpack使用 React 和 Webpack 添加 Favicon
【发布时间】:2016-09-14 20:35:04
【问题描述】:

我正在尝试将 favicon 添加到我使用 webpack 制作的基于 React 的网站。添加网站图标是一场彻头彻尾的噩梦,我尝试了许多解决方案都无济于事。向我推荐的最新解决方案称为“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..
  • 你的问题是 webpack 没有捆绑你的 ico 文件吗?还是页面没有显示它。您可以使用 file-loader 让 wepack 将文件加载到您的包中,然后在您的 html 页面中调用它。
  • 嘿@Co​​deYogi,如果我的解决方案对你有用,你想把它标记为正确答案吗?

标签: javascript node.js reactjs webpack favicon


【解决方案1】:

对于仍在搜索的任何人...一旦我运行,我就设法在我的 index.html 中导入网站图标
npm install html-loader
并在我的webpack.config.js 中包含以下内容:

// ... Other config options.
{
  test: /\.html$/,
  include: path.resolve(__dirname, 'public'), // Your path may be different.
  use: [
      {
          loader: 'html-loader',
      },
  ],
},

文件路径需要相对于您的源代码,而不是生产代码。 要检查您的构建是否包含 favicon,您可以在 url 中查找生产路径,如下所示:localhost:xxxxx/path/to/favicon.png

【讨论】:

    【解决方案2】:

    正确答案:

    如果你直接使用 webpack:

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

    如果你使用 CRA(create-react-app) 那么你可以修改公共目录中的manifest.json

    【讨论】:

      【解决方案3】:

      Ctrl+f5清除浏览器缓存

      【讨论】:

        【解决方案4】:

        用你的替换公用文件夹中的 favicon.ico,这样你就可以开始了。

        【讨论】:

          【解决方案5】:
          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 中添加 favicon
          【解决方案6】:

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

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

          【讨论】:

          • 迄今为止最好和最简洁的解决方案。请注意,我的 webpack.config.js 位于根目录中,因此我必须使用 ./src/favicon.ico 来定位正确的路径。
          • 注意你需要做: $ npm install copy-webpack-plugin --save-dev 然后在你的 webpack.config.js 的顶部添加: const CopyWebpackPlugin = require('copy-webpack -plugin');
          • API 已更改。现在应该是: new CopyWebpackPlugin({ patterns: [ { from: './static/favicon.ico' }, ]}),
          • 感谢您的通知,我刚刚更新了我的答案⬆️
          【解决方案7】:

          我用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. 
          
          ]
          }
          

          【讨论】:

            【解决方案8】:

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

            【讨论】:

              【解决方案9】:

              就我而言——我正在使用 webpack 2.4.1 在调试模式下运行 Visual Studio(Professional 2017)——有必要将 favicon.ico 放入项目的根目录中,就在文件夹 @987654323 的位置@ 不是在文件夹public 中,尽管根据https://create-react-app.dev/docs/using-the-public-folder 后者应该是官方位置。

              【讨论】:

                【解决方案10】:

                这就是我的做法。

                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,但我不需要任何额外的设置来让网站图标正常工作,也不需要在服务器端。

                【讨论】:

                  【解决方案11】:

                  我将给出添加网站图标的简单步骤:-)

                  • 创建您的徽标并保存为logo.png
                  • logo.png 更改为favicon.ico

                    注意当你保存它是favicon.ico确保它不是favicon.ico.png

                  • 可能需要一些时间来更新

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

                  【讨论】:

                  • 不要修改manifest.json,你应该清除浏览器上的缓存。在 Chrome 上是 cmd + shift + r/ctrl + shift + r
                  【解决方案12】:

                  这里就是你所需要的:

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

                  那肯定是在将“favicon.gif”添加到文件夹“src”之后。

                  这会将图标传输到您的构建文件夹并将其包含在您的标签中,例如&lt;link rel="shortcut icon" href="favicon.gif"&gt;。这比使用copyWebpackPLugin 导入更安全

                  【讨论】:

                  • 这是比其他响应最简单和安全的方式。对你有好处。
                  • 在这个答案中添加一些细节会有所帮助,我应该在哪个文件中添加new HtmlWebpackPlugin 代码?我需要安装哪个插件?使用它需要什么配置?
                  • @Sumit 你需要'html-webpack-plugin'。您可以查看他们的文档以获取更多详细信息。上面的例子不能开箱即用,你至少需要添加templatefilename选项。
                  • 坏蛋解决方案。
                  • 我在桌面网络浏览器上看到了图标,但在我的 Android 网络浏览器上没有显示,这是预期的吗?我需要任何特定的尺寸或其他东西吗?我使用的是 64x64 png
                  【解决方案13】:

                  另一种选择是

                  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 中的变量时,这是一个很好的答案,感谢您的回答。
                  【解决方案14】:

                  这与添加任何其他外部脚本或样式表相同。 您所要做的就是专注于提供正确的路径reltype

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

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

                  它对我有用。希望它也对你有用。

                  【讨论】:

                    【解决方案15】:

                    为此使用 文件加载器

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

                    【讨论】:

                    • 您还应该添加带有HtmlWebpackPlugin 的网站图标才能正常工作,不仅如此。
                    【解决方案16】:

                    浏览器会在 /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]'));
                    });
                    

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

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

                    【讨论】:

                      猜你喜欢
                      • 1970-01-01
                      • 2018-04-10
                      • 1970-01-01
                      • 2019-03-04
                      • 2020-08-23
                      • 2020-02-01
                      • 2017-06-06
                      • 2019-07-18
                      • 2020-07-06
                      相关资源
                      最近更新 更多