minhtranite / react-lazysizes

LazySizes component for ReactJS base on lazysizes
37 stars 12 forks source link

require or import do not work #4

Closed kikoanis closed 8 years ago

kikoanis commented 8 years ago

Not sure if this ever worked or it might be a change in the original lazysizes library

var LazySizes = require('react-lazysizes');

throws an exception of

Error: Cannot find module 'lazysizes' at Function.Module._resolveFilename (module.js:336:15) at Function.Module._load (module.js:286:25) at Module.require (module.js:365:17) at require (module.js:384:17) at Object.<anonymous> (/home/path/to/example/node_modules/react-lazysizes/lib/LazySizes.js:19:1)

I can see that lazysizes does not export any module and as "Self-Executing Anonymous Function" it only will be exposed on the window object.

Is it a change in the original lazysizes that was exporting a module

Even your example does not use require or import

I am using node 4.2.1 (npm v2.14.7)

Or am I missing something?

minhtranite commented 8 years ago

Please re-install react-lazysizes and make sure that lazysizes exists in /home/path/to/example/node_modules/react-lazysizes/node_modules/.

Run:

npm uninstall --save react-lazysizes
npm install --save react-lazysizes
kikoanis commented 8 years ago

@vn38minhtran thanks. The issue was a different one.

I guess the error only appears in isomorphic applications. So when trying to render on server side. It cannot find lazysizes as it is not a module. I fixed this issue by

let LazySizes
if (process.env.BROWSER) {
  LazySizes = require('react-lazysizes')
}

and when I render it

                    <div className="fill">
                      { LazySizes &&
                        <LazySizes dataSrc={src} />
                      }
                    </div>

this is all ok except we have two new issues:

  1. This is not an SEO friendly any more as it is not rendered until it hits the browser which defeats one of the main points for the lazysizes library.
  2. It creates the issue of different markups for client and server sides which react throws a warning at it (development mode)

Now, if we do

    if (process.env.BROWSER) {
         require('lazysizes');
    }

instead of

     import 'lazysizes';

in your react library, I think this will result in fixing both of these issues as the server will render the <img> element and the server will no longer be different from the client. As you know the lazysizes library is all about styling and javascript processing and hence we are still be able to render the <img> HTML element on server side.

Obviously, this would involve changes to webpack config files.

minhtranite commented 8 years ago

Please update new version. Now we use:

if (canUseDOM) {
  require('lazysizes');
}

I think it better than use process.env.BROWSER from webpack config.

Note: I used new version with https://github.com/kriasoft/react-starter-kit it work.

kikoanis commented 8 years ago

That should do it as well. You got the idea. Whenever there is an external library that does not expose a module, we will have to do this trick which is unfortunate I guess.

Thank you for putting this together.