4

im having trouble using webpack file-loader with three.js

I tried two methods, 1:

 import jpg from "./assets/water.jpg";
    const water = new Water(waterGeometry, {
          waterNormals: new THREE.TextureLoader().load(jpg, function(texture) {
            texture.wrapS = texture.wrapT = THREE.RepeatWrapping;
          }),

which produces 404 jpgname not found

second method :

import jpg from "./assets/water.jpg";
    const water = new Water(waterGeometry, {
          waterNormals: jpg

which makes error:

 TypeError: Invalid value used as weak map key
    at WeakMap.set

my webpack config :

rules: [
  {
      {
    test: /\.(png|svg|jpg|gif)$/,
    use: ["file-loader"]
  },

1 Answers1

3

I was able to solve this issue in the following way:

1st) with webPack you must do a require (or an import), for example:

let bg_px = require('../assets/milkyway/dark-s_px.jpg'),
bg_nx = require('../assets/milkyway/dark-s_nx.jpg'),
bg_py = require('../assets/milkyway/dark-s_py.jpg');

2nd) OK! when you do that, webpack will move your file in your "dest" folder, with another name (probably the id, something like this: 'a36b443f1f659f216df3b8f1c82dd167.jpg')

The problem is that, if you need to load an asset (like a texture) to THREE.js using require or import in webpack, it wont work cause THREE is expecting an URL (in dist folder) and not an object (in this case, a module object). Example:

let urls = [ bg_px, bg_nx , bg_py ]; //wrong
let textureCube = new THREE.CubeTextureLoader().load( urls );//wont work because bg_px is an object

3rd) If you do a console.log(bg_px) on you required asset you will see that the real URL is on the "default" field.. so using it like this will work:

let urls = [ bg_px.default, bg_nx.default , bg_py.default ]; //right!!
let textureCube = new THREE.CubeTextureLoader().load( urls );//works!

So, "bundling" this out:

You have to do a const ASSET = require('path/to/ASSET') to your asset (I guess that import also will do), and then you must use your 'ASSET' variable accessing the 'default' field inside the object, like this: 'ASSET.default'

obs: Your webpack config is right!

Hope it helps, for me it did. Keep calm and happy coding!

sugaith
  • 772
  • 7
  • 14