问题
我们用Flutter Web开发了一个应用,通过electron进行打包成可执行文件,但是在使用时发现了一个问题,Lottie动画无法显示。
通过console的日志可以看到,提示lottie
是undifine
的,lottie
是sdk提供的一个全局的对象,通过lottie.loadAnimation(options)
可以加载显示Lottie动画,但是我们明明在index.html
中引入了Lottie的js文件,而且在浏览器上也是可以正常使用的,为什么通过Electron打包后执行就失效了?
我们在开发者工具中的Sources下找到Lottie的js文件,然后打断点进调试,通过对比浏览器和Electron发现问题所在。
在Lottie的js文件一开始的代码:
(typeof navigator !== "undefined") && (function(root, factory) { if (typeof define === "function" && define.amd) { define(function() { return factory(root); }); } else if (typeof module === "object" && module.exports) { module.exports = factory(root); } else { root.lottie = factory(root); root.bodymovin = root.lottie; } }((window || {}), function(window) { ... 复制代码
这里会进行判断将factory(root)
的结果赋值到不同的地方,而factory(root)
就是下面的function(window) {..}
函数,这个函数返回的就是lottie
对象。在浏览器中代码会执行到第三个分支,即:
root.lottie = factory(root); root.bodymovin = root.lottie; 复制代码
而在Electron中,代码执行到第二个分支中,这是因为在Electron中存在module
这个全局变量,但是这个变量是Electron对象,所以将lottie
赋值给它是错误的,全局就无法找到lottie
对象了。
解决
简单的解决方法就是将第二条分支注释掉,因为我们在Electron中使用,所以问题不大。如下:
(typeof navigator !== "undefined") && (function(root, factory) { if (typeof define === "function" && define.amd) { define(function() { return factory(root); }); } //在electron中本身有module的存在,所以会执行到这里,但是factory返回的lottie对象赋值到了错误的地方,导致全局lottie对象丢失 // else if (typeof module === "object" && module.exports) { // module.exports = factory(root); // } else { root.lottie = factory(root); root.bodymovin = root.lottie; } }((window || {}), function(window) {