如何将pixi.js导入到Svelte/Sapper应用程序中?

4

我是Svelte的新手,正在尝试将pixi.js引入我的应用程序。我已经尝试根据这篇文章Svelte Mount DOM Element from Javascript将pixi.js引入我的svelte应用程序。

我已经通过以下方式安装了pixi:

yarn add pixi.js --dev

然而,当我尝试导入pixi.js时,出现了"ReferenceError: window is not defined"错误。以下是一个简单的示例:

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

我在 Reddit 上读到,需要使用以下解决方案:

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

但那也没有起作用。当我使用全局脚本标签时一切正常,但我宁愿使用上面的导入方式。我做错了什么?谢谢!

**编辑: 经过一些研究,我已经学到了需要从非SSR的角度来处理这个问题。https://sapper.svelte.dev/docs#Making_a_component_SSR_compatible

以下是我尝试的:

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

现在我得到了:

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

看起来找不到pixi.js?我的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,
  }
};
4个回答

4

显然我需要:

preferBuiltins: false,

在我的客户端解析中。

0
在你的 rollup.config 中搜索 resolve 将这段代码粘贴到那里
resolve({
      preferBuiltins: false,
      browser: true,
      dedupe: ["svelte"],
    })

0

目前我的解决方案是在onMount内使用动态导入。

<script>
  import {onMount} from 'svelte'

  onMount(async () => {
    const PIXI = await import('pixi.js')
    let type = "WebGL"
    if(!PIXI.utils.isWebGLSupported()){
      type = "canvas"
    }

    PIXI.utils.sayHello(type)
  })
</script>

"sapper": "^0.28.0"
"svelte": "^3.17.3"
"pixi.js": "^5.3.3"

"sapper": "^0.28.0"
"svelte": "^3.17.3"
"pixi.js": "^5.3.3"


0

我也遇到了同样的问题,但是提供的答案并没有完全解决我的问题。

我的整个问题:

我的问题有两个方面。问题的核心在于SSR。

首先,我必须设置preferBuiltins: false并调整commonjs资源加载器,类似于上面给出的答案。

其次,我正在运行polka@version:next(polka是Sapper的默认微服务器),显然在某些方面不稳定/兼容。我不知道确切的不兼容性,但这种直观的修复最终解决了我的问题。我只需更改package.json并运行npm install即可。请参见下面的详细信息。

我的整个解决方案:

我必须对rollup.config.jspackage.json进行以下更改以解决问题:

  1. 我必须对rollup.config.js进行2个更改:
export default {
    client: {
        ...,
        plugins: [
            ...,
            resolve({
                ...
                preferBuiltins: false // ADD THIS
            }),
            commonjs({
              ...,
              namedExports: {
                "resource-loader": ["Resource"] // ADD THIS
              }
            })
        ],
        ...,
    },
    ...,
};

  1. package.json 文件中,我需要将 polka: 'next' 改为 polka: '^0.5.2'(最新版本的 polka)。

这是我的最终 package.json 文件:

{
  "name": "TODO",
  "description": "TODO",
  "version": "0.0.1",
  "scripts": {
    ...
  },
  "dependencies": {
    "polka": "^0.5.2", // THIS
    ...,
  },
  "devDependencies": {
    ...
  }
}


这对我没用。我在@pixi\polyfill\lib\polyfill.js处得到了“window未定义”的错误。 - Abraham Anak Agung

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接