【问题标题】:How do I import pixi.js into a Svelte/Sapper app?如何将 pixi.js 导入 Svelte/Sapper 应用程序?
【发布时间】:2022-01-13 11:45:38
【问题描述】:

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

之后,我尝试将 pixi.js 导入我的苗条应用程序

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

yarn add pixi.js --dev

但是,当我尝试导入 pixi.js 时,我收到“ReferenceError:未定义窗口”错误。这是一个简单的例子:

<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,
  }
};

【问题讨论】:

    标签: svelte pixi.js rollupjs sapper


    【解决方案1】:

    显然我需要:

    preferBuiltins: false,
    

    在我的客户解决。

    【讨论】:

      【解决方案2】:

      我在上面遇到了同样的问题,但提供的答案并没有解决我的问题完全

      整个问题(对我而言):

      我的问题有两个方面。问题的核心确实归结为 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(最新版本的波尔卡)。

      这是我最后的package.json

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

      【讨论】:

      • 这对我不起作用。我在@pixi\polyfill\lib\polyfill.js 得到了window is not defined
      【解决方案3】:

      目前我的解决方案是在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>
      

      “工兵”:“^0.28.0”
      “苗条”:“^3.17.3”
      “pixi.js”:“^5.3.3”

      【讨论】:

        【解决方案4】:

        在你的 rollup.config 中搜索 resolve

        把这个粘贴到那里

        resolve({
              preferBuiltins: false,
              browser: true,
              dedupe: ["svelte"],
            })
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2020-01-07
          • 2021-11-04
          • 1970-01-01
          • 2020-05-09
          • 1970-01-01
          • 2020-04-09
          • 2021-01-02
          • 2020-09-04
          相关资源
          最近更新 更多