My nextjs project (let's call it TheHost) references another npm package (let's call it ThePackage).
SVGs load fine when defined within TheHost, but importing ThePackage fails because next tries to interpret the svg as javascript... so I get the following error when doing a next build
:
SyntaxError: Unexpected token '<'
To re-iterate, SVGs work fine when referencing an svg defined in TheHost itself. The problem seems to be importing npm packages that contain SVGs.
It doesn't matter if I import a component from ThePackage that uses an SVG or not, just the fact that somewhere in the npm package it contains an "import xxx from '../path/to/svg' is enough to break next build
.
For what it's worth, the ThePackage's transpiled javascript reads the svg as follows:
var _mysvg = require("../path/to/the-svg.svg");
The next build stack trace is:
> Using external babel configuration
> Location: "/Users/w/dev/TheHost/.babelrc"
Creating an optimized production build
Compiled successfully.
> Build error occurred
/Users/w/dev/TheHost/node_modules/ThePackage/build/assets/card_background.svg:1
<svg viewBox="0 0 860 382" fill="none" xmlns="http://www.w3.org/2000/svg">
^
SyntaxError: Unexpected token '<'
at Module._compile (internal/modules/cjs/loader.js:895:18)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:995:10)
at Module.load (internal/modules/cjs/loader.js:815:32)
at Function.Module._load (internal/modules/cjs/loader.js:727:14)
at Module.require (internal/modules/cjs/loader.js:852:19)
at require (internal/modules/cjs/helpers.js:74:18)
at Object.<anonymous> (/Users/w/dev/TheHost/node_modules/TheProject/build/card/style.js:14:47)
at Module._compile (internal/modules/cjs/loader.js:959:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:995:10)
at Module.load (internal/modules/cjs/loader.js:815:32) {
type: 'SyntaxError'
}
Automatically optimizing pages .%
The .babelrc file:
{
"presets": [
"next/babel"
],
"plugins": [
"babel-plugin-styled-components",
"inline-react-svg"
]
}
The next.config.js file:
const withSourceMaps = require("@zeit/next-source-maps");
const withImages = require("next-images");
module.exports = withImages(
withSourceMaps({
env: { *** redacted *** },
publicRuntimeConfig: { *** redacted *** },
webpack: (config, options) => {
if (!options.isServer) {
config.resolve.alias["@sentry/node"] = "@sentry/browser";
}
config.module.rules.push({
test: /\.svg$/,
use: ["@svgr/webpack"]
});
return config;
}
})
);
The nextjs svgr package versions are as follows:
"next": "^9.2.1",
"next-images": "^1.3.0",
"@svgr/webpack": "^5.1.0",
"babel-eslint": "^10.0.3",
"babel-plugin-inline-react-svg": "^1.1.1",
ThePackage is built with the following output configuration (webpack):
entry: './src/index.js',
output: {
path: buildFolder,
filename: 'ThePackage.js',
library: 'ThePackage',
libraryTarget: 'umd', /* Note: umd */
umdNamedDefine: true
},
The Node.js Package Manager (npm) is the default and most popular package manager in Node.js ecosystem that is primarily used to install and maintain external modules in Node.js application. Users can basically install the node modules needed for their application using npm. How to export Modules ?
You can add the css file in head of nextjs. and in the render method, inside the return add a head tag similar to ordinary HTML, the head tag should be inside a div. <div> <Head> <title>Test</title> <link href="/static/master.css" rel="stylesheet" key="test"/> </Head> </div> also the css should be in static folder.
Next.js can be deployed to any hosting provider that supports Node.js. For example, AWS EC2 or a DigitalOcean Droplet. First, ensure your package.json has the "build" and "start" scripts: Then, run next build to build your application. Finally, run next start to start the Node.js server.
<svg> is a standard HTML tag that can be directly used in JSX. That means if your SVG is quite short, it can be easiest to include it in place. You can use a regular img tag and reference the SVG by URL. You need to place the image in the /public directory and reference it relative to that. This file would be in the root of the public directory.
NextJS ignores node_modules
by default so you'd need to specifically allow your config to be able to transpile your package. Fortunately, someone has already created a NextJS plugin to allow this: https://github.com/martpie/next-transpile-modules
I'd also suggest using Next Compose Plugins to neaten up the config. In the end, your next.config.js will look something like this:
const withSourceMaps = require("@zeit/next-source-maps");
const withImages = require("next-images");
const withPlugins = require('next-compose-plugins');
const withTM = require('next-transpile-modules')(['ThePackage']);
module.exports = withPlugins([
withTM,
[
withImages,
{
exclude: /\.svg$/
}
],
withSourceMaps
],
{
env: { *** redacted *** },
publicRuntimeConfig: { *** redacted *** },
webpack: (config, options) => {
if (!options.isServer) {
config.resolve.alias["@sentry/node"] = "@sentry/browser";
}
config.module.rules.push({
test: /\.svg$/,
use: ["@svgr/webpack"]
});
return config;
}
});
I've also excluded SVGs from being processed by withImages
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With