Importing images has the wrong route in production builds
See original GitHub issueReporting a bug?
When you import an image (and probably other file assets, as well), ex: import imgSrc from '../img.png';
, the file is placed in a /static
folder. This works perfectly fine in a local dev server.
But when you run react-static build
, the path received from the import is missing the /static
prefix, and your image reference is broken in the built site!
Digging through the react-static
source, I think I’ve traced the problem to this file: https://github.com/react-static/react-static/blob/dbf750c/packages/react-static/src/static/webpack/rules/fileLoader.js
See how it passes different configuration to the loader depending on the “stage”? According to some console logging, this configuration is actually called twice during the build process - once for a stage of “node” and once for “prod”.
I’d love to send a PR with a fix, but unfortunately, this is where I’m stuck. I don’t know why it’s doing this or if it’s supposed to be solving another problem. In fact, I don’t even know what “stages” are - the possible values appear to be “dev”, “node”, and “prod”, which doesn’t really make sense to me - when would Webpack not run in Node? It wouldn’t exactly work in the browser, right?
I did manage to find a workaround, though - create a plugin at node.api.js
:
export default () => ({
webpack: (config, {stage}) => {
if (stage === 'node') {
const fileRule = config.module.rules[0].oneOf.find((x) => x.loader === 'url-loader');
fileRule.options.name = 'static/[name].[hash:8].[ext]';
}
return config;
},
});
This is probably extremely brittle, and I don’t know if it has any other detrimental side effects.
Environment
Run and copy the result of:
npx envinfo --system --npmPackages react* --binaries --npmGlobalPackages react* --browsers
here:
System:
OS: macOS Mojave 10.14.6
CPU: (8) x64 Intel(R) Core(TM) i7-7700HQ CPU @ 2.80GHz
Memory: 106.03 MB / 16.00 GB
Shell: 5.3 - /bin/zsh
Binaries:
Node: 10.15.3 - ~/.nvm/versions/node/v10.15.3/bin/node
npm: 6.9.0 - ~/.nvm/versions/node/v10.15.3/bin/npm
Watchman: 4.9.0 - /usr/local/bin/watchman
Browsers:
Chrome: 77.0.3865.90
Firefox Developer Edition: 70.0
Safari: 13.0.2
npmPackages:
react: ^16.9.0 => 16.10.2
react-dom: ^16.9.0 => 16.10.2
react-static: ^7.2.0 => 7.2.2
react-static-plugin-reach-router: ^7.2.0 => 7.2.2
react-static-plugin-sitemap: ^7.2.0 => 7.2.2
react-static-plugin-source-filesystem: ^7.2.0 => 7.2.2
of course include any other package versions here if relevant.
Steps to Reproduce the problem
Base your steps off of any freshly installed react-static template!
- Start from the “basic” template
- Add an image into the “src” dir, ex.
src/img.png
. - In
pages/about.js
, import that image and render it:
import React from 'react';
import imgSrc from '../img.png';
export default () => {
return (
<div>
<p>React Static is a progressive static site generator for React.</p>
<img src={imgSrc} />
</div>
);
};
- Run
npm run build
and thennpm run serve
to see a built version of the site - Navigate to the “About” page on the site
- The image you included is missing, because the
src
is something like/62faa5fe0f4d6c46784c1eb0e08b0ed6.png
and the image is indist/static/img.62faa5fe.png
- If you navigate to the same page, you’ll see the image appear, with the correct src.
Expected Behavior
The image’s src
should match up to where Webpack actually placed the image.
Reproducible Demo
Here’s a repo with the code-based steps in “Steps to Reproduce the Problem” already done: https://github.com/dallonf/react-static-img-repro
Issue Analytics
- State:
- Created 4 years ago
- Reactions:15
- Comments:5 (1 by maintainers)
For what it is worth, in this file
node_modules/react-static/lib/static/webpack/rules/fileLoader.js
if I change this:to:
The image paths are now correct in the
dist
folder. Perhaps the bug could be lanced by doing what is counter to this comment// Don't generate extra files during node build
?I had the same issue, but after digging through the documentation I decided to go with the following solution
node.api.js