Добавить Favicon с React и Webpack
Я пытаюсь добавить значок на веб-сайт, основанный на React, который я сделал с помощью webpack. Это был полный кошмар, чтобы добавить значок, и я попробовал множество решений безрезультатно. Последнее решение, которое мне было рекомендовано, называется "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 name. `string`
appDescription: null, // Your application 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 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 . 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()}`));
Ответы
Ответ 1
Вот все, что вам нужно:
new HtmlWebpackPlugin({
favicon: "./src/favicon.gif"
})
Это определенно после добавления "favicon.gif" в папку "src".
Это перенесет значок в вашу папку сборки и включит его в ваш тег, например, <link rel="shortcut icon" href="favicon.gif">
. Это безопаснее, чем просто импортировать с помощью copyWebpackPLugin
Ответ 2
Для будущих googlers: Вы также можете использовать copy-webpack-plugin и добавить это в производственный конфиг webpack:
plugins: [
new CopyWebpackPlugin([
// relative path is from src
{ from: './static/favicon.ico' }, // <- your path to favicon
])
]
Ответ 3
Добавление вашего favicon просто в папку public
должно подойти. Убедитесь, что значок назван favicon.ico
.
Ответ 4
Браузеры ищут ваш значок в /favicon.ico
, чтобы там, где он должен быть. Вы можете дважды проверить, разместили ли вы его в нужном месте, перейдя к [address:port]/favicon.ico
и посмотрев, появляется ли ваш значок.
В режиме dev вы используете 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
, так как я обнаружил, что он более надежный в браузерах.
Ответ 5
Другая альтернатива
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'));
Ответ 6
Используйте файловый загрузчик для этого:
{
test: /\.(svg|png|gif|jpg|ico)$/,
include: path.resolve(__dirname, path),
use: {
loader: 'file-loader',
options: {
context: 'src/assets',
name: 'root[path][name].[ext]'
}
}
}
Ответ 7
Это так же, как добавление любого другого внешнего скрипта или таблицы стилей. Все, что вам нужно сделать, это сосредоточиться на том, чтобы указать правильный путь, отн и тип.
Примечание. Когда мое изображение избранного находилось в папке ресурсов, оно не отображало значок. Поэтому я скопировал изображение в ту же папку, что и мой index.html, и оно работало отлично, как и должно.
<head>
<link rel="shortcut icon" type="image/png/ico" href="/favicon.png" />
<title>SITE NAME</title>
</head>
Это сработало для меня. Надеюсь, это работает и для вас.
Ответ 8
Вот как я это сделал.
общественности /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
в режиме разработки, но мне не нужно было никаких дополнительных настроек для работы со значком и на стороне сервера.
Ответ 9
Я дам простые шаги, чтобы добавить favicon :-)
Ответ 10
В моем случае - я запускаю Visual Studio (Professional 2017) в режиме отладки с веб-пакетом 2.4.1 - необходимо было поместить favicon.ico
в корневой каталог проекта, там, где папка src
довольно чем в папке public
, хотя согласно https://create-react-app.dev/docs/using-the-public-folder последнее должно быть официальным местоположением.