Когда я пытаюсь импортировать изображение SVG, появляется следующая ошибка. Какой загрузчик я должен использовать для импорта изображений SVG?
./static/Rolling-1s-200px.svg 1:0
Module parse failed: Unexpected token (1:0)
You may need an appropriate loader to handle this file type.
> <svg xmlns = "http://www.w3.org/2000/svg" viewBox = "0 0 2000 2000"><filter id = "b"><feGaussianBlur stdDeviation = "12" /></filter><path fill = "#817c70" d = "M0 0h2000v2000H0z"/><g filter = "url(#b)" transform = "translate(4 4) scale(7.8125)" fill-opacity = ".5"><ellipse fill = "#000210" rx = "1" ry = "1" transform = "matrix(50.41098 -3.7951 11.14787 148.07886 107 194.6)"/><ellipse fill = "#eee3bb" rx = "1" ry = "1" transform = "matrix(-56.38179 17.684 -24.48514 -78.06584 205 110.1)"/><ellipse fill = "#fff4bd" rx = "1" ry = "1" transform = "matrix(35.40604 -5.49219 14.85017 95.73337 16.4 123.6)"/><ellipse fill = "#79c7db" cx = "21" cy = "39" rx = "65" ry = "65"/><ellipse fill = "#0c1320" cx = "117" cy = "38" rx = "34" ry = "47"/><ellipse fill = "#5cb0cd" rx = "1" ry = "1" transform = "matrix(-39.46201 77.24476 -54.56092 -27.87353 219.2 7.9)"/><path fill = "#e57339" d = "M271 159l-123-16 43 128z"/><ellipse fill = "#47332f" cx = "214" cy = "237" rx = "242" ry = "19"/></g></svg>
Чтобы решить эту проблему удобным способом, я использую плагин next-react-svg. Вот как stackoverflow.com/a/61854576/1762849





Вам нужно предоставить загрузчик веб-пакетов, который будет обрабатывать импорт SVG, один из известных — СВГР.
Чтобы настроить его для работы со следующим, вам нужно добавить в свой файл next.config.js использование загрузчика, например:
// next.config.js
module.exports = {
webpack(config) {
config.module.rules.push({
test: /\.svg$/,
issuer: {
test: /\.(js|ts)x?$/,
// for webpack 5 use
// { and: [/\.(js|ts)x?$/] }
},
use: ['@svgr/webpack'],
});
return config;
},
};
Для получения дополнительной информации о конфигурации проверить документы.
Не забывайте, чтобы сначала установить @svgr/webpack:
$ npm install --save-dev @svgr/webpack
Редактировать
Я добавил раздел issuer, который ограничивает эти svg как компоненты только для svg, импортированных из файлов js / ts.
Это позволяет настроить другое поведение для svg, которые импортируются из других типов файлов (например, .css).
issuer.
Да, это не буэно @felixmosh
для webpack5 используйте issuer: { and: [/\.(js|ts)x?$/] }
Установите следующие изображения.
yarn add -D next-images
Создайте next.config.js в своем проекте.
// next.config.js
const withImages = require('next-images')
module.exports = withImages()
Для тех, кто использует Typescript, не забудьте добавить: /// <reference types = "next-images" /> в ваш файл next-env.d.ts.
Это сработало для меня без какой-либо другой зависимости
// In next.config.js
module.exports = {
webpack (config, options) {
config.module.rules.push({
test: /\.(png|jpg|gif|svg|eot|ttf|woff|woff2)$/,
use: {
loader: 'url-loader',
options: {
limit: 100000
}
}
});
return config;
}
};
Это лучший ответ. Чистая конфигурация Webpack. Нет необходимости ничего устанавливать.
@DayronGallardo «не нужно ничего устанавливать», а? Вы должны установить @zeit/next-sass и @zeit/next-css
@BrandonDuffany нет, вам не нужно их устанавливать. Ответчик скопировал свою собственную конфигурацию, поэтому в блоке кода присутствуют эти служебные оболочки. Вам вообще не нужно их использовать.
Вы можете использовать Babel-плагин-встроенный-реагировать-SVG
import React from 'react';
import CloseSVG from './close.svg';
const MyComponent = () => <CloseSVG />;
npm install --save-dev babel-plugin-inline-react-svg
// .babelrc
{
"plugins": [
"inline-react-svg"
]
}
Или смотрите ссылку для получения дополнительных инструкций.
По какой-то причине это не будет работать в проекте Typescript.
1. Абсолютные пути не поддерживаются. 2. Вы должны установить окно просмотра вручную, потому что этот плагин не импортирует его из файла svg. 3. Не работает с машинописным текстом. Неужели нет простого решения?? Nextjs существует уже много лет, а этот вопрос был задан в 2019 году!
Лично я предпочитаю плагин следующий-реагировать-SVG, который позволяет обрабатывать изображения SVG как компоненты React и автоматически встраивать их, подобно тому, как это делает приложение Create React.
Вот как это использовать:
next-react-svg:npm i next-react-svg
next.config.js:const withReactSvg = require('next-react-svg')
const path = require('path')
module.exports = withReactSvg({
include: path.resolve(__dirname, 'src/assets/svg'),
webpack(config, options) {
return config
}
})
Параметр include является обязательным и указывает на папку с изображениями SVG.
Если у вас уже есть какие-либо подключаемые модули для вашего Next.js, рассмотрите возможность использования следующий компоновщик-плагины для их правильного объединения.
import Logo from 'assets/svg/Logo.svg';
export default () => (
<Logo />
);
Вот и все. Отныне Next.js будет включать изображения SVG, импортированные таким образом, в отображаемую разметку в виде тегов SVG.
Вы знаете, как использовать next-react-svg со сборником рассказов?
Это большое спасибо. Если вы пришли из приложения Create React, как и я, обязательно измените оператор импорта SVG. то есть изменить import { ReactComponent as MySvg } from 'src/assets/mysvg.svg'. в import MySvg from 'src/assets/mysvg.svg'
Вы можете просто импортировать его через тег <img>.
<img src='./next.svg' alt='next' />
Просто убедитесь, что svg находится в общей папке.
Этот ответ вводит в заблуждение, поскольку контекст здесь SVG как SVG, но не как изображение.
используя этот метод, svg не будет отображаться в браузере
Вы можете использовать next-plugin-svgr и next-compose-plugins для очистки плагинов (если они у вас есть):
// next.config.js
const withPlugins = require("next-compose-plugins");
const withSvgr = require("next-svgr");
module.exports = withPlugins([
withSvgr
// your other plugins here
]);
или просто next-plugin-svgr:
// next.config.js
const withSvgr = require('next-plugin-svgr');
module.exports = withSvgr({
webpack(config, options) {
return config;
},
});
<img> или <Image>Не подходит для интерактивных SVG или если вы собираетесь манипулировать SVG с помощью внешнего CSS/JS.
Можно использовать официальный компонент next/image или тег img (как указано в этом отвечать).
Вам просто нужно переместить файл svg в public вместо static и сделать что-то вроде этого:
import Image from 'next/image';
// ...
<Image src = "/Rolling-1s-200px.svg" width = "2000" height = "2000" />
Но при использовании этого метода содержимое файла svg не будет присутствовать непосредственно в ответе; браузер получит тег <img src = "..." ...></img>.
Также нужно указать width и height, но можно посчитать из атрибута viewbox.
В Next.js v11 и выше вы также можете:
import Image from 'next/image';
import Illustration from '../static/Rolling-1s-200px.svg';
// ...
<Image src = {Illustration} />
// one needs to use `Illustration.src` to get the source URL
// <img src = {Illustration.src} ... />
принятый ответ показал, как это сделать с помощью webpack-4, но поскольку webpack-5 теперь используется по умолчанию, я делюсь соответствующей конфигурацией. Вы можете использовать его после установки @svgr/webpack (yarn add -D @svgr/webpack или npm install @svgr/webpack --save-dev):
// next.config.js
// https://github.com/gregberge/svgr/issues/551#issuecomment-839772396
module.exports = {
// other configs...
// future: { webpack5: true }, // -- not needed since Next.js v11.0.0
webpack(config) {
config.module.rules.push({
test: /\.svg$/i,
issuer: { and: [/\.(js|ts|md)x?$/] },
use: [
{
loader: '@svgr/webpack',
options: {
prettier: false,
svgo: true,
svgoConfig: { plugins: [{ removeViewBox: false }] },
titleProp: true,
},
},
],
});
return config;
},
};
Если вы не используете options для загрузчика, вы можете просто написать это:
use: ['@svgr/webpack']
Если вы используете v6 of @svgr/webpack, вам нужно указать конфигурацию SVGO следующим образом:
// ...
plugins: [
{
name: 'preset-default',
params: {
overrides: { removeViewBox: false },
},
},
],
// ...
Если вы используете машинописный текст, вам необходимо определить соответствующие модули (в каталоге, откуда вы импортируете svg, или, возможно, добавить его в корень как <some-name>.d.ts и включить его tsconfig):
// index.d.ts
declare module '*.svg' {
const ReactComponent: React.FC<React.SVGProps<SVGSVGElement>>;
export default ReactComponent;
}
Затем вы можете использовать его как:
import Illustration from '../static/Rolling-1s-200px.svg';
// ...
<Illustration />
Примечание: Next.js v11.0.1+ объявили SVG как модули, экспортирующие any. Ваша пользовательская конфигурация не будет переопределять типы, установленные next-env.d.ts, если вы не исключите последний. См. это.
[УСТАРЕЛО (Фиксированный)] ОБНОВИТЬ :
Если вы используете Next.js v11.0.0, вы можете получать ошибки при импорте SVG. Пожалуйста, обновите до v11.0.1 или выше. Воспользуйтесь обходным решением, упомянутым в этот комментарий.
Могу ли я использовать .svg из каталога public/? в настоящее время я создал assets/ только для использования относительного импорта с использованием TS, такого как @/assets/logo.svg, но хотел бы использовать его только из public/. Является ли это возможным?
@ deadcoder0904 Пожалуйста, обратитесь к первой части ответа. Переместите свои SVG в public и используйте их вот так <Image src = "/svg-name.svg" height = "100" width = "100" />. Вы также можете переместить папку с активами прямо в каталог public; тогда вам нужно будет передать src как /assets/svg-name.svg.
нет, мне нужно импортировать его. я не хочу использовать компонент Image. эта часть отсутствует в вашем ответе, и это именно то, что я хочу сделать.
@ deadcoder0904 Тогда это невозможно. Я имею в виду, что вы можете сохранить SVG в public или любой другой папке, но вам нужно будет указать полный путь, например @/public/logo.svg, при импорте. Вторая часть ответа показывает это. Вам не нужно использовать компонент Image в этом.
Обратите внимание, что: assets — это просто обычное имя папки, это не то, что Next.js понимает сам по себе. Если вы хотите поместить активы в сам каталог public, это тоже нормально; вам просто нужно изменить оператор импорта: import Logo from '@/public/logo.svg'; Но имейте в виду, что общая папка доступна всем, кто посещает ваш сайт, поэтому не помещайте туда ничего конфиденциального.
о, да! next.js понимает только pages/ и api/, я думаю. Я использую папку src/ и папку public/ в одном каталоге, используя псевдонимы, и я использовал только псевдонимы внутри src/, поэтому я не устанавливал псевдонимы для public/ и думал, что смогу import Logo from '/logo.svg' импортировать из public/, но это не сработало. благодаря вашим обоим комментариям теперь это имеет смысл.
@ deadcoder0904 Вы можете использовать такой путь: "@/*": ["src/*", "public/*"] тогда import Logo from '@/Logo.svg'; будет работать.
По-прежнему появляется сообщение «Возможно, вам понадобится соответствующий загрузчик для обработки этого типа файла, в настоящее время загрузчики не настроены для обработки этого файла», а затем «Ошибка: не удается найти модуль«.../pages-manifest.json’», потому что веб-пакет может « t read config :( Возможно, это связано с sentry или next-transpile-modules, но когда я не использую их в конфигурации, абсолютные пути перестают работать. Думаю, мне придется использовать префикс в импорте.
@VityaSchel Можете ли вы опубликовать другой вопрос, показывающий, что пошло не так и как это воспроизвести? Обсуждение вашего запроса здесь, в разделе комментариев, не принесет пользы сообществу. И, насколько мне известно, вторая ошибка возникает в основном из-за сбоя в сборке веб-пакета (первая ошибка). Можете ли вы попробовать, если решения, упомянутые в этой теме, работают: github.com/vercel/next.js/issues/6287
<Image src = {Illustration} /> сработало!
Как импортировать SVG в компонент Next.js?
Другое решение без установки какой-либо библиотеки
import React from "react";
export default function GoogleLogo() {
return (
<svg className = "svgIcon-use" width = "25" height = "37" viewBox = "0 0 25 25">
<g fill = "none" fillRule = "evenodd">
<path
d = "M20.66 12.693c0-.603-.054-1.182-.155-1.738H12.5v3.287h4.575a3.91 3.91 0 0 1-1.697 2.566v2.133h2.747c1.608-1.48 2.535-3.65 2.535-6.24z"
fill = "#4285F4"
/>
<path
d = "M12.5 21c2.295 0 4.22-.76 5.625-2.06l-2.747-2.132c-.76.51-1.734.81-2.878.81-2.214 0-4.088-1.494-4.756-3.503h-2.84v2.202A8.498 8.498 0 0 0 12.5 21z"
fill = "#34A853"
/>
<path
d = "M7.744 14.115c-.17-.51-.267-1.055-.267-1.615s.097-1.105.267-1.615V8.683h-2.84A8.488 8.488 0 0 0 4 12.5c0 1.372.328 2.67.904 3.817l2.84-2.202z"
fill = "#FBBC05"
/>
<path
d = "M12.5 7.38c1.248 0 2.368.43 3.25 1.272l2.437-2.438C16.715 4.842 14.79 4 12.5 4a8.497 8.497 0 0 0-7.596 4.683l2.84 2.202c.668-2.01 2.542-3.504 4.756-3.504z"
fill = "#EA4335"
/>
</g>
</svg>
);
}
и используйте:
import GoogleLogo from "./GoogleLogo";
class Login extends React.Component {
render() {
return (
<LoginLayout title = "Login Page">
<div>
<Link href = "/auth/google">
<a className = "button">
<div>
<span className = "svgIcon t-popup-svg">
<GoogleLogo />
</span>
</div>
</a>
</Link>
</div>
</LoginLayout>
);
}
}
Я попробовал первый ответ, но получил ошибку, так что это работает:
module.exports = {
webpack(config) {
config.module.rules.push({
test: /\.svg$/,
use: ["@svgr/webpack"]
});
return config;
}};
С Next.js 12.0.9 и Webpack 5 это работает для меня:
yarn add --dev url-loader @svgr/webpack
// next.config.js
module.exports = {
webpack(config, options) {
config.module.rules.push({
test: /\.svg$/,
use: ['@svgr/webpack', 'url-loader'],
});
return config;
},
};
вам даже не нужно url-loader
@ deadcoder0904 для меня без «url-loader» nextjs не может загрузить SVG и выдает ошибку. Мне тоже интересно, почему, но это необходимо.
Если вы хотите использовать файлы SVG в своем коде БЕЗ КОНФИГУРАЦИИ ИЛИ УСТАНОВКИ ЗАВИСИМОСТИ и иметь полный контроль в атрибутах тега, лучшим решением будет преобразование файла SVG в компоненты JSX или TSX.
JSX-решение:
export const YourSVg = ({color, width, height}) => (
<svg fill = {color} height = {height} width = {width}>
..rest of the svg tags...
</svg>
)
TSX-решение:
export const YourSVg:React.FC<{color:string, width:string, height:string}> =
({color, width, height}) => (
<svg color = {color} height = {height} width = {width}>
..rest of the svg tags...
</svg>
)
Как это использовать?
может импортировать его как обычный компонент и использовать так же, как и раньше
например:
import YourSVg from '../from the path/path
<YourSVg color='red' width='10px' height='10px/>