解决Electron-egg环境下打包后Canvas图片加载失败的问题

326 阅读2分钟

解决Electron-egg环境下打包后Canvas图片加载失败的问题

问题原因

  • 开发所使用的框架时electron-egg,项目中用到了Konvajs。Konvajs在加载图片资源的时候直接使用的url去定位资源,外加vite的打包策略估计对于没有使用 import关键词引入的资源在打包时就会略过,这样是出于减少打包后体积考虑。但是konvajs引入资源并不是 通过 import关键词引入,这就导致如果图片不在public文件夹下就不会进行打包。

  • 第二个原因就是打包后资源路径变了。比如代码中 url为 ./public/device-maintenance/xx.png,实际打包后路径为 **/out/win-unpacked/resources/app.asar/public/dist/public/device-maintenance/xx.png。vite会把public目录的图片移动到 dist 目录下。比如

    public/image ->dist/image 发现没相比与 dist/public/device-maintenance/xx.png 的路径少了public这个目录。

解决方法

  • 打包时将图片移动到 dist/public文件夹下,在vite里实现一个简单的复制插件就行,你也可以从网上找类似插件。代码如下
import path from 'path';
import fse from 'fs-extra';
​
​
function copyPublicFolder() {
    return {
        name: 'copy-public-folder',  // 插件的名称
        closeBundle() {
            const src = path.resolve(__dirname, 'public');  // 源目录
            const dest = path.resolve(__dirname, 'dist', 'public');  // 目标目录
​
            // 确保目标目录存在,如果不存在则创建
            fse.ensureDir(dest)
                .then(() => {
                    // 复制目录
                    return fse.copy(src, dest);
                })
                .then(() => {
                    console.log('Public folder copied successfully!');
                })
                .catch(err => {
                    console.error('Error copying public folder:', err);
                });
        }
    };
}

然后再 vite.config.js中这样配置:

export default defineConfig(({command, mode}) => {
    return {
        // 项目插件
        plugins: [
            copyPublicFolder(), // 在这里配置即可
            vue(),
        ],
        // 基础配置
        base: './',
        // publicDir: 'public',
        resolve: {
            alias: {
                '@': path.resolve(__dirname, 'src'),
            },
        },
        css: {
            preprocessorOptions: {
                less: {
                    modifyVars: {
                        '@border-color-base': '#dce3e8',
                    },
                    javascriptEnabled: true,
                },
            },
        },

        build: {
            outDir: 'dist',
            assetsDir: 'assets',
            assetsInlineLimit: 4096,
            cssCodeSplit: true,
            copyPublicDir:false,
            brotliSize: false,
            sourcemap: false,
            minify: 'terser',
            terserOptions: {
                compress: {
                    // 生产环境去除console及debug
                    drop_console: false,
                    drop_debugger: true,
                },
            },
        },
    }
})
  • 当然你也可以用import 引用图片来解决,我就不尝试了。