Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I import pixi.js into a Svelte/Sapper app?

I'm new to Svelte and am trying to import pixi.js into my app. I've tried to import pixi.js into my svelte app following this post Svelte Mount DOM Element from Javascript

I've installed pixi via:

yarn add pixi.js --dev

However, when I try to import pixi.js I get a "ReferenceError: window is not defined" error. Here is a quick example:

<script>
    import * as PIXI from 'pixi.js'
    import { onMount } from 'svelte';
    let view;
    let app;
    onMount(() => {
        app = new PIXI.Application({
        view,
        // ...other props
    });
});

</script>
<canvas bind:this={view}/>

I read somewhere on reddit that I need to solve this using:

  onMount(async ()=>{       
       const PIXI = await import('pixi.js');
        app = new PIXI.Application({
        view,
        // ...other props
        });
    });

But that didn't work either. All is well when I use a global script tag, but I would rather use the import above. What am I doing wrong? Thanks!

**Edit: After some research I have learned that I need to approach this from a non-SSR perspective. https://sapper.svelte.dev/docs#Making_a_component_SSR_compatible

Here's what I tried:

<script>
  import { onMount } from "svelte";

  let MyComponent;
  onMount(async () => {
    const module = await import ('../components/pixi/mycomponent.svelte');
    MyComponent = module.default;
   });
</script>

<svelte:component this={MyComponent}/>

mycomponent.svelte:

<script>
   import * as PIXI from "pixi.js";
   import { onMount } from 'svelte';

   let view;
   let app;
     app = new PIXI.Application({
       view,
        width: 256,         // default: 800
         height: 256,        // default: 600
         antialias: true,    // default: false
         transparent: false, // default: false
         resolution: 1,      // default: 1
         backgroundColor: 0x090f15
       // ...other props
     });
</script>

<style>
 canvas {
    width: 100%;
    margin: 0 auto;
  }
</style>

<div class="content" bp="padding">
  <canvas bind:this={view} />
</div>

Now I'm getting:

TypeError: Failed to resolve module specifier "url". Relative references must start with either "/", "./", or "../".

Apparently pixi.js cannot be found? Is there something wrong with my rollup.config.js?

import resolve from 'rollup-plugin-node-resolve';
import replace from 'rollup-plugin-replace';
import commonjs from 'rollup-plugin-commonjs';
import svelte from 'rollup-plugin-svelte';
import postcss from 'rollup-plugin-postcss';
import babel from 'rollup-plugin-babel';
import { terser } from 'rollup-plugin-terser';
import config from 'sapper/config/rollup.js';
import pkg from './package.json';

const mode = process.env.NODE_ENV;
const dev = mode === 'development';
const legacy = !!process.env.SAPPER_LEGACY_BUILD;

const onwarn = (warning, onwarn) => (warning.code === 'CIRCULAR_DEPENDENCY' && /[/\\]@sapper[/\\]/.test(warning.message)) || onwarn(warning);
const dedupe = importee => importee === 'svelte' || importee.startsWith('svelte/');
const postcssOptions = () => ({
  extensions: ['.scss', '.sass'],
  extract: false,
  minimize: true,
  use: [
    ['sass', {
      includePaths: [
        './src/theme',
        './node_modules',
        // This is only needed because we're using a local module. :-/
        // Normally, you would not need this line.
        //path.resolve(__dirname, '..', 'node_modules')
      ]
    }]
  ]
});

export default {
  client: {
    input: config.client.input(),
    output: config.client.output(),
    plugins: [
      replace({
        'process.browser': true,
        'process.env.NODE_ENV': JSON.stringify(mode)
      }),
      svelte({
        dev,
        hydratable: true,
        emitCss: false,
        css: true
      }),
      resolve({
        browser: true,
        dedupe
      }),
      commonjs(),

      postcss(postcssOptions()),

      legacy && babel({
        extensions: ['.js', '.mjs', '.html', '.svelte'],
        runtimeHelpers: true,
        exclude: ['node_modules/@babel/**'],
        presets: [
          ['@babel/preset-env', {
            targets: '> 0.25%, not dead'
          }]
        ],
        plugins: [
          '@babel/plugin-syntax-dynamic-import',
          ['@babel/plugin-transform-runtime', {
            useESModules: true
          }]
        ]
      }),

      !dev && terser({
        module: true
      })
    ],

    onwarn,
  },

  server: {
    input: config.server.input(),
    output: config.server.output(),
    plugins: [
      replace({
        'process.browser': false,
        'process.env.NODE_ENV': JSON.stringify(mode)
      }),
      svelte({
        generate: 'ssr',
        dev
      }),
      resolve({
        dedupe
      }),
      commonjs(),

      postcss(postcssOptions())
    ],
    external: Object.keys(pkg.dependencies).concat(
      require('module').builtinModules || Object.keys(process.binding('natives'))
    ),

    onwarn,
  },

  serviceworker: {
    input: config.serviceworker.input(),
    output: config.serviceworker.output(),
    plugins: [
      resolve(),
      replace({
        'process.browser': true,
        'process.env.NODE_ENV': JSON.stringify(mode)
      }),
      commonjs(),
      !dev && terser()
    ],

    onwarn,
  }
};
like image 857
TheKernel Avatar asked Oct 23 '25 15:10

TheKernel


1 Answers

Apparently I needed to:

preferBuiltins: false,

In my client resolve.

like image 72
TheKernel Avatar answered Oct 25 '25 08:10

TheKernel