Hello,
What is the best way to load images and other assets that will work for both client & server?
I could add url-loader
and file-loader
to webpack config but it will not work on the server.
Are there other options?
Thanks,
Ran.
for example and for fonts, you could add the following :
,
{
test: /\.(woff)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
loader: "url?limit=100000&mimetype=application/font-woff"
}
server does not understand image extension, you need use require hook for ssr
https://github.com/bahmutov/node-hook
also you can add in this file server
require('babel-register')
if (development variable) require.extensions['.png'] = function () {};
require('./server')
I've used https://github.com/tcoopman/image-webpack-loader to deal with the images. I think it is based on file-loader, but allows you to optimise images.
closing this
@jaredpalmer hey man, thanks for the awesome kit :) i'm sorry to drudge this back up, but may i ask how you are handling SSR images/statics like fonts in your projects? for example, how are you approaching:
// logo-component.js
import LogoImage from './logo.png' // colocated image in component folder
export default ({ linkUrl }) =>
<a href={linkUrl}>
<img src={LogoImage} alt="Logo" />
</a>
i've been using webpack-isomorphic-tools
to handle above cases, which works but the ergonomics and setup feels very brittle and hacky... i'm about to start another project, it would be really great to hear your thoughts and approach—it feels like assets.json
could be used for statics as well
thanks again jared, any direction, boilerplate or webpack config you could provide would be greatly appreciated, and i'd be happy to submit a PR if it's something you want to add to starter
i suspect i'm probably overlooking a super simple solution.... thanks again!! :)
All you need to do install url-loader
via npm and then add the following to each webpack.config:
....
{
test: /\.(gif|jpe?g|png|ico)$/,
loader: 'url-loader?limit=10000'
},
{
test: /\.(otf|eot|svg|ttf|woff|woff2).*$/,
loader: 'url-loader?limit=10000'
}
...
You can then just require them in exactly as you described above. BTW the limit parameter just tells url-loader
at what threshold it should actually generate an image vs. creating a data-uri.
EDIT:
Also remove new webpack.IgnorePlugin(/\.(css|less|scss|svg|png|jpe?g|png)$/),
from webpack server config.
@jaredpalmer thanks for the response :) that's exactly the issue i was running into... like i said, i was able to resolve using https://www.npmjs.com/package/webpack-isomorphic-tools but it really feels very clunky...
@rowellx68 you mentioned using image-webpack-loader—could you maybe elaborate?
@b2whats would you mind providing some additional context or example for your node-hook
solution? is there a way to integrate with assets plugin, so we can use a single manifest?
@justingreenberg babel-register can't handle the image file types, a workaround is to modify server:
require('babel-register');
if (process.env.NODE_ENV == 'development') {
require.extensions['.png'] = function () {};
require.extensions['.jpg'] = function () {};
require.extensions['.jpeg'] = function () {};
require.extensions['.woff'] = function () {};
require.extensions['.woff2'] = function () {};
require.extensions['.ico'] = function () {};
require.extensions['.svg'] = function () {};
}
require('./server');
@justingreenberg image-webpack-loader
will just optimize your images... you would use it in tandem with file-loader
:
...
{
test: /\.(png|jpg|jpeg|gif)(\?.*)?$/,
loaders: [
'file',
'image-webpack?' + JSON.stringify({
bypassOnDebug:true,
progressive: true,
optimizationLevel: 7,
interlaced: true,
pngquant: {
quality: "65-90",
speed: 4
},
svgo: {
removeUnknownsAndDefaults: false,
cleanupIDs: false
}
})
]
},
I would still use url-loader
for fonts and svg's with this.
@rowellx68 @b2whats should we create a PR for this with url-loader
? What are downsides of the require.extension
in dev ? It's ugly, but cleaner than bundling the server just for dev IMHO. 🤔
@jaredpalmer re: patching require workaround, this is an interesting approach... so manually registering extensions with require just allows the module to hit url-loader
, makes sense!
re: image-webpack, that was my understanding (really an optimization) but i thought maybe there was something i was missing for node usage since @rowellx68 said he was using it for images
thanks again!
@jaredpalmer require.extensions
seems to have been deprecated?
@justingreenberg re: image-webpack-loader
. It is indeed primarily for optimising images. However, the resulting images were not added into assest.json
.
@rowellx68
we need slice dev and prod mode. webpack config may be different. In dev mode we need from the server get normal url of the image. In prod mode we can use any optimizations
I have modified build scripts. There is now a pbulic folder for you robots.txt, favicon etc. It's not the "perfect solution" but it works. Bundles js -> public/assets
(which is not checked into git).
Will explore @justingreenberg 's requireHooks solution as that would allow for inlining and cache busting.
hey all, let me know if this is out of scope, but the static assets discussion seemed somewhat relevant.
I'm someone who is fairly new to the webpack world (read: no clue how to use it yet) and I'm trying to use this project to build a web app using a client's style guide. rather than reapplying CSS styles over and over I'm trying to load a CSS file that contains the client's style guide. is there a quick and relatively painless way to load their stylesheet statically and then use aphrodite to manage layout, etc?
What about bundling the server entry with webpack using target: 'node'
option?
We'd have all the webpack loaders goodness on the server side without needing to hack node's require() or use webpack-isomorphic-tools.
Or is there a major problem or downside on this approach that I am not seeing? besides needing to have two webpack watches when developing
Edit: just saw it is already being done for prod, but why not dev too?
Most helpful comment
@justingreenberg babel-register can't handle the image file types, a workaround is to modify server: