Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to load images and other static assets? #45

Closed
ranyefet opened this issue Apr 25, 2016 · 17 comments
Closed

How to load images and other static assets? #45

ranyefet opened this issue Apr 25, 2016 · 17 comments

Comments

@ranyefet
Copy link

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.

@benbonnet
Copy link

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"
}

@b2whats
Copy link

b2whats commented Apr 28, 2016

server does not understand image extension, you need use require hook for ssr
https://github.com/bahmutov/node-hook

@b2whats
Copy link

b2whats commented Apr 29, 2016

also you can add in this file server

require('babel-register')
if (development variable) require.extensions['.png'] = function () {};
require('./server')

@rowellx68
Copy link
Contributor

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.

@jaredpalmer
Copy link
Owner

closing this

@justingreenberg
Copy link
Contributor

@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!! :)

@jaredpalmer
Copy link
Owner

jaredpalmer commented Jun 2, 2016

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 jaredpalmer reopened this Jun 2, 2016
@justingreenberg
Copy link
Contributor

@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?

@jaredpalmer
Copy link
Owner

@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');

@jaredpalmer
Copy link
Owner

jaredpalmer commented Jun 2, 2016

@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.

@jaredpalmer
Copy link
Owner

jaredpalmer commented Jun 2, 2016

@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. 🤔

@justingreenberg
Copy link
Contributor

@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!

@rowellx68
Copy link
Contributor

@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.

@b2whats
Copy link

b2whats commented Jun 4, 2016

@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

@jaredpalmer
Copy link
Owner

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.

@aem
Copy link

aem commented Sep 16, 2016

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?

@williamoliveira
Copy link

williamoliveira commented Oct 21, 2016

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?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

8 participants