react native skia configuration with react native web
I try to use it with skin in my components project
but I got an error when I came to the web
Error: Cannot read properties of undefined (reading 'Matrix')
at new JsiRenderNode (/vendors-node_modules_shopify_react-native-skia_lib_module_index_js.iframe.bundle.js:1408:29))
at new GroupNode (/vendors-node_modules_shopify_react-native-skia_lib_module_index_js.iframe.bundle.js:881:5))
at JsiSkDOM.Group (/vendors-node_modules_shopify_react-native-skia_lib_module_index_js.iframe.bundle.js:933:120))
at new Container (/vendors-node_modules_shopify_react-native-skia_lib_module_index_js.iframe.bundle.js:5355:26))
at new SkiaRoot (/vendors-node_modules_shopify_react-native-skia_lib_module_index_js.iframe.bundle.js:5776:22))
at /vendors-node_modules_shopify_react-native-skia_lib_module_index_js.iframe.bundle.js:5267:69
at mountMemo (/vendors-node_modules_babel_runtime_helpers_asyncToGenerator_js-node_modules_babel_runtime_hel-6ba1b4.iframe.bundle.js:41175:19))
at Object.useMemo (/vendors-node_modules_babel_runtime_helpers_asyncToGenerator_js-node_modules_babel_runtime_hel-6ba1b4.iframe.bundle.js:41620:16))
at useMemo (/vendors-node_modules_babel_runtime_helpers_asyncToGenerator_js-node_modules_babel_runtime_hel-6ba1b4.ifram
I reproduce this error in the repo
https://github.com/YOEL311/storybookPublic reproduce step
git clone
cd
git switch main
yarn
yarn storybook
I tried all ways from this page but I already get the error https://shopify.github.io/react-native-skia/docs/getting-started/web
I solved that by adding to my .storybook/main.js file the configuration like that
However, I need to use WithSkiaWeb on each component that requires Skia, and this approach is causing various problems with both the props and the native side.
To address this, can I initialize Skia at the entry point of the web application with the above code?
Additionally, could you please clarify when the AppRegistry for the web application is registered?
import { LoadSkiaWeb } from "@shopify/react-native-skia/lib/module/web";
LoadSkiaWeb().then(async () => {
const App = (await import("./src/App")).default;
AppRegistry.registerComponent("Example", () => App);
});
my .storybook/main.js file
const path = require('path');
const fs = require('fs');
const { sources } = require('webpack'); // Ensure webpack is imported to use its native objects and functions.
const NodePolyfillPlugin = require('node-polyfill-webpack-plugin');
/** @type { import('@storybook/react') } */
const config = {
stories: ['../src/components/**/*.stories.?(ts|tsx|js|jsx)'],
addons: [
'storybook-addon-deep-controls',
'@storybook/addon-links',
'@storybook/addon-essentials',
'@storybook/addon-interactions',
{
name: '@storybook/addon-react-native-web',
options: {
modulesToAlias: {
'react-native-linear-gradient': 'react-native-web-linear-gradient',
},
modulesToTranspile: [
'react-native-reanimated',
],
babelPlugins: [
'@babel/plugin-proposal-export-namespace-from',
'react-native-reanimated/plugin',
],
},
},
],
framework: {
name: '@storybook/react-webpack5',
options: {},
},
docs: {
autodocs: true,
},
webpackFinal: async (webpackConfig) => {
webpackConfig.resolve.alias['@react-native-cookies/cookies'] = path.resolve(
__dirname,
'../mocks/cookies.js',
);
webpackConfig.resolve.alias['@react-native-community/blur'] = path.resolve(
__dirname,
'../mocks/blur.js',
);
const fileLoaderRule = webpackConfig.module.rules.find((rule) =>
rule.test.test('.svg'),
);
fileLoaderRule.exclude = /\.svg$/;
webpackConfig.module.rules.push({
test: /\.svg$/,
// exclude: /node_modules/,
use: [{ loader: '@svgr/webpack' }],
});
// CopyPlugin for canvaskit.wasm
webpackConfig.plugins.push(new NodePolyfillPlugin());
// CopyPlugin for canvaskit.wasm
class CopySkiaPlugin {
apply(compiler) {
compiler.hooks.thisCompilation.tap('AddSkiaPlugin', (compilation) => {
compilation.hooks.processAssets.tapPromise(
{
name: 'copy-skia',
stage:
compiler.webpack.Compilation.PROCESS_ASSETS_STAGE_ADDITIONAL,
},
async () => {
const src = require.resolve(
'canvaskit-wasm/bin/full/canvaskit.wasm',
);
if (!compilation.getAsset(src)) {
compilation.emitAsset(
'canvaskit.wasm',
new sources.RawSource(await fs.promises.readFile(src)),
);
}
},
);
});
}
}
webpackConfig.plugins.push(new CopySkiaPlugin());
// Alias updates for react-native-reanimated
webpackConfig.resolve.alias['react-native-reanimated'] = require.resolve(
'react-native-reanimated',
);
webpackConfig.resolve.alias[
'react-native/Libraries/Image/AssetRegistry'
] = false;
return webpackConfig;
},
};
export default config;
AppRegistry.registerComponent does not seem ideal here.
It's probably easier for you to use <WithSkiaWeb> as a decorator when running on the web.
Decoratore cannot help me here because is get the Story as component In this case I need to import or require the component only after the script of Skia is loaded
you can use a custom render function, that might work better
Hi @dannyhw I appreciate your work
This is what I did, but I had some problems with it that I thought could be solved in a better way with LoadSkiaWeb .