• Runtimes
  • Path problem while using webpack

I'm trying to run combo Phaser + Spine2D + TypeScript + Webpack and I got issue with loading Spine things in Phaser via webpack. When I try to load things as usual

this.load.spineJson('skeleton-json', require('assets/skeleton.json'));
this.load.spineAtlas('skeleton-atlas', require('assets/skeleton.atlas'));

I got issue with atlas, cause in there, first line refers to skeleton.png, but webpack hashes it so it's something like 12f12idgf1b3bi.png, thus breaking the path to the file and receiving 404. Removing require works fine locally, but after upload to web server it results in 404.

I tried loading atlas as text, then replacing paths, but this.load.spineAtlas uses URL so it doesn't work as well

import atlas from 'assets/skeleton.atlas';
...
const customAtlas = atlas.replace(/skeleton\.png/g, require('assets/skeleton.png'));

None of those work:

this.load.spineAtlas('skeleton-atlas', customAtlas);
// or
this.load.text('skeleton-atlas', customAtlas);

customAtlas is still treated as URL so it looks like localhost:808012f12idgf1b3bi.pngsize:2046,1890...

Do you have maybe any idea how to load it properly? :/

  • Davide ha risposto a questo messaggio
    Related Discussions
    ...

    When using Webpack with Phaser and Spine, the issue you're encountering is due to Webpack's asset hashing, which changes the file names and breaks the paths specified in your atlas file. To resolve this, you can use Webpack's file-loader or url-loader to handle your assets. These loaders can be configured to preserve the original file names or to output a mapping of original to hashed names, which you can then use to dynamically replace the paths in your atlas file.

    Here's a general approach you can take:

    1. Configure Webpack to handle assets: Use file-loader or url-loader in your Webpack configuration to manage your assets. This will allow you to import assets and get their URLs.

    2. Dynamic path replacement: After importing your assets, replace the paths in your atlas file with the URLs provided by Webpack. You can do this by reading the atlas file as a string and using JavaScript's replace method to substitute the paths.

    3. Load the modified atlas: Use Phaser's this.load.text to load the modified atlas as a text file, then parse it manually or use a custom loader to handle the modified paths.

    Here's a simplified example of how you might implement this:

    import atlas from 'assets/skeleton.atlas';
    import skeletonImage from 'assets/skeleton.png';
    
    // Replace the path in the atlas with the Webpack-generated URL
    const customAtlas = atlas.replace(/skeleton\.png/g, skeletonImage);
    
    // Load the modified atlas as text
    this.load.text('skeleton-atlas', customAtlas);
    
    // After loading, parse the atlas and use it with your Spine setup
    this.load.on('complete', () => {
      const atlasText = this.cache.text.get('skeleton-atlas');
      // Use the atlasText with your Spine setup
    });

    This approach allows you to dynamically adjust the paths in your atlas file to match the URLs generated by Webpack, ensuring that your assets are correctly loaded both locally and on a web server.

    Tried code above but it results Uncaught TypeError: text is undefined even locally

    veme

    That strictly depends on your webpack configuration. There are several ways of solving this problem.

    To do my tests, I've used the official Phaser template with Webpack and TypeScript from this repository.

    The simplest way to solve the problem is to just put the assets in the public folder and use the path from that folder. So, rather than:

    this.load.spineJson('skeleton-json', require('assets/skeleton.json'));
    this.load.spineAtlas('skeleton-atlas', require('assets/skeleton.atlas'));

    you just do:

    this.load.spineJson('skeleton-json', 'assets/skeleton.json');
    this.load.spineAtlas('skeleton-atlas', 'assets/skeleton.atlas');

    If you still want to require/import your files and your webpack configuration imports the atlas text file as raw file, you need to act directly on the cache.

    You can see how assets are directly added to the Phaser cache in this example. Please notice that in this case the images are encoded, while in your case you can just load the images using this.load.texture. If you use this, you need to remember that the key of the images has this syntax: atlasKey!pngKey.