How can I use emotion with react-native-web? - javascript

I develop a cross-platform react-native application inside a monorepo and want to render my app using react-native-web in the browser. To achieve that I followed this guide https://mmazzarolo.com/blog/2021-09-22-running-react-native-everywhere-web/. I'm also using the metro-react-native-babel-preset package for compiling my web-app, as described in the react-native-web guide https://necolas.github.io/react-native-web/docs/multi-platform/. Here is a part of my craco.config.js file (I use create-react-app with craco):
// craco.config.js
const webpack = require("webpack");
const { getWebpackTools } = require("react-native-monorepo-tools");
const monorepoWebpackTools = getWebpackTools();
module.exports = {
babel: {
presets: ["module:metro-react-native-babel-preset", "#babel/preset-react"]
},
webpack: {
configure: (webpackConfig) => {
// Allow importing from external workspaces.
monorepoWebpackTools.enableWorkspacesResolution(webpackConfig);
// Ensure nohoisted libraries are resolved from this workspace.
monorepoWebpackTools.addNohoistAliases(webpackConfig);
return webpackConfig;
},
Now it seems like the metro-react-native-babel-preset preset is not compatible with the stylis library (imported by #emotion/react), because I get this error when launching the app in the browser (it compiles without errors):
Uncaught TypeError: (0 , _stylis.middleware) is not a function
at createCache (emotion-cache.browser.esm.js:288)
at Object.../node_modules/#emotion/react/dist/emotion-element-699e6908.browser.esm.js (emotion-element-699e6908.browser.esm.js:11)
at __webpack_require__ (bootstrap:851)
at fn (bootstrap:150)
at Object.<anonymous> (emotion-react.browser.esm.js:3)
at Object.../node_modules/#emotion/react/dist/emotion-react.browser.esm.js (emotion-react.browser.esm.js:347)
at __webpack_require__ (bootstrap:851)
at fn (bootstrap:150)
at Object.../node_modules...
I guess that the stylis-package cannot be imported correctly due to the metro-react-native-babel-preset preset, since without the preset the error is gone (but the compilation-step throws errors, so removing the preset is not a solution).
What do I have to change in my babel- / webpack-config or code to remove this error?
Minimum, reproducible example
https://github.com/Tracer1337/stackoverflow-mre

I think it is a problem with packages version.
When I try it, I also have this error.
But when updated packages to newer version it was gone (other error occured thought, but related to reactDOM).
I have updated react-scripts to 5.0.0;
See if it helps you as well.
{
"name": "#meme-bros/web",
...
"dependencies": {
"#emotion/react": "^11.7.1",
"#emotion/styled": "^11.6.0",
"#mui/material": "^5.2.3",
"#types/react": "^17.0.0",
"#types/react-dom": "^17.0.0",
"metro-react-native-babel-preset": "^0.66.2",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-native-web": "^0.17.5",
"react-scripts": "5.0.0",
"typescript": "^4.1.2"
},
"devDependencies": {
"#craco/craco": "^6.4.3",
"react-native-monorepo-tools": "^1.1.4"
},
...

Would you mind to follow these guidelines to run React Native app on web. Official Doc
And Add #emotion/react in compileNodeModules list

Related

How can I fix ValidationError of Sass loader?

I was trying to add global scss variables to my Vue project. I found this example Globally load sass. So I created vue.config.js in my root folder of my Vue project then I copy & paste vue.config.js and change the data inport path and then when I am trying to serve my project I am getting this error :
ValidationError: Invalid options object. Sass Loader has been initialised using an options object that does not match the API schema.
- options has an unknown property 'data'. These properties are valid:
object { implementation?, sassOptions?, prependData?, sourceMap?, webpackImporter? }
at validate
I checked my package.json to just be sure that I have installed node-sass and sass-loader and I found those dependencies :
"devDependencies": {
"#vue/cli-plugin-babel": "^4.1.0",
"#vue/cli-plugin-router": "^4.1.2",
"#vue/cli-service": "^4.1.0",
"babel-eslint": "^10.0.3",
"node-sass": "^4.12.0",
"sass-loader": "^8.0.0",
"vue-template-compiler": "^2.6.10"
}
So I am a little bit confused and I do not know what I am doing wrong. I also know that I can import those .scss variables to every vue component in which i am going to use them but i do not like this solution.
vue.config.js
module.exports = {
css: {
loaderOptions: {
sass: {
data: `
#import "#/style/index.scss";
`
}
}
}
};
Directory structure
Change data to prependData ...see the docs

jest + typescript + es6 modules (yet again, 2019) - SyntaxError: Unexpected token export

I'm still facing problems trying to use jest, typescript and es6 modules. My test are written in Typescript, I'm trying to import objects from js-file which uses es6 modules. To do that, I've followed jest documentation and have the following in my babel.config.js, which is located in project root:
module.exports = {
presets: [
[
'#babel/preset-env',
{
targets: {
node: 'current'
}
}
]
]
};
I have the following dependencies installed:
"devDependencies": {
"#babel/core": "^7.2.2",
"#babel/preset-env": "^7.3.1",
"#types/jest": "^23.3.13",
"#types/node": "^10.12.18",
"babel-jest": "^24.1.0",
"jest": "^23.6.0",
"rollup": "^1.1.2",
"rollup-plugin-terser": "^4.0.4",
"rollup-plugin-typescript2": "^0.19.2",
"ts-jest": "^23.10.5",
"ts-node": "^8.0.1",
"typescript": "^3.2.4"
}
In jest.config.js I have the following:
module.exports = {
verbose: true,
transform: {
"^.+\\.jsx?$": "babel-jest",
'^.+\\.ts?$': 'ts-jest'
},
testEnvironment: 'node',
testRegex: '/test/.*\\.(test|spec)?\\.(ts|tsx)$',
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node']
};
And finally, I'm trying to import like this in my tests:
import {Dag, Directions} from "../dist/dag";
And here it says: SyntaxError: Unexpected token export
D:\devel\tomtom_dag\dist\dag.js:72
}();export { e as Directions, t as Action, n as Dag };
Can someone say what am I doing wrong or point to the project with similar config? And yes, I've googled this already for several hours and have tried solutions from here, here and have tried with this plugin - with the same result=(
UPDATE:
I've created a project to reproduce the issue:
https://github.com/AntonPilyak/jest_typescript_es6
Also, I've noticed that I had forgot to mention that I was trying to use jest#23 version due to ts-jest can't work with the latest (gives a warning + I get an empty test suite). Maybe, my problems are coming out from that fact. But still, I'm unable to make a proper config: if I use the latest jest I get a warning + jest says that the test suite is empty and test is passing though it shouldn't.
It works with ts-jest 24 + it appears to be a bug in my IDE: https://youtrack.jetbrains.com/issue/IDEA-207553

Creating a Kotlin React Wrapper around Paypal Downshift

I've been trying without success to create a Kotlin JS wrapper around the PayPal Downshift library. I can get Downshift to work fine outside the Kotlin ecosystem, but am having no luck when trying to integrate it into a Kotlin JS application.
I've stripped all the properties out to the following:-
#file:JsModule("downshift")
package components.downshift
import react.Component
import react.RProps
import react.RState
import react.ReactElement
#JsName("Downshift")
external class DownshiftComponent : Component<RProps, RState> {
override fun render(): ReactElement?
}
Then inside my React app's render method I add the following:-
child<RProps, DownshiftComponent> { }
The equivalent in JSX works inside a custom component (although renders nothing!)
render() {
return (
<Downshift/>
)
}
The error I end up with is as follows:-
TypeError: Cannot read property '$metadata$' of undefined
getOrCreateKClass
node_modules/kotlin/kotlin.js:27368
27365 | if (jClass === String) {
27366 | return PrimitiveClasses_getInstance().stringClass;
27367 | }
> 27368 | var metadata = jClass.$metadata$;
| ^ 27369 | if (metadata != null) {
27370 | if (metadata.$kClass$ == null) {
27371 | var kClass = new SimpleKClassImpl(jClass);
To me this is suggesting the class from the "downshift" package can't be found (hence undefined). If that is the case what is the correct way to import Downshift so Kotlin can use it?
I have installed the downshift module using npm
npm install downsift --save
and it is showing in my package.json file:-
{
"name": "pop-up-shop-ui",
"version": "0.1.0",
"private": true,
"dependencies": {
"#material-ui/core": "^3.8.2",
"#material-ui/icons": "^3.0.2",
"#material-ui/lab": "^3.0.0-alpha.28",
"d3-shape": "^1.2.2",
"downshift": "^3.2.0",
"prop-types": "latest",
"react": "^16.7.0",
"react-autosuggest": "^9.4.3",
"react-currency-format": "^1.0.0",
"react-dom": "^16.7.0",
"react-google-charts": "^3.0.10",
"react-router": "^4.3.1",
"react-router-dom": "^4.3.1",
"react-scripts": "2.1.3"
},
"devDependencies": {
"react-scripts-kotlin": "3.0.3"
},
"scripts": {
"start": "react-scripts-kotlin start",
"build": "react-scripts-kotlin build",
"eject": "react-scripts-kotlin eject",
"gen-idea-libs": "react-scripts-kotlin gen-idea-libs",
"get-types": "react-scripts-kotlin get-types --dest=src/types",
"postinstall": "npm run gen-idea-libs"
}
}
Here is the standard import when using a react/jsx component
import Downshift from "downshift";
Which matches the #file:JsModule("downshift") and #JsName("Downshift") annotations.
Any help getting this working would be appreciated
I've encountered this problem few days ago. The error is very confusing, but after some digging I found that the problem originates in the type (in your case Downshift) being undefined. You can easily catch it by writing something like prinltn(DownshiftComponent::class) before initializing react.
The problem is probably with the build. Don't forget to add the npm dependency in it. Also sometimes incremental build glitches and you need to do a clean build to see changes.

Intermittent "TypeError: "exports" is read-only" error with Webpack and Vue-CLI

I have a Vue-CLI app which was working fine until recently. Now, sometimes this message appears in the console, and the rest of the app fails to load:
TypeError: "exports" is read-only
The direct cause appears to be one of my modules, which uses module.exports to export its default function. I understand that Webpack (which Vue CLI uses) reduced support for module.exports, at least in the case of a module which also contains ES2015 import statements. But that's not the case here. And Webpack sometimes compiles it just fine.
What's particularly weird is it's intermittent. Generally I can make the problem go away temporarily by rm -rf node_modules; npm install. (Yarn install doesn't seem as reliable). But then it comes back.
What could be the cause? Perhaps two competing dependencies? My package.json looks like this:
"dependencies": {
"#turf/turf": "^5.1.6",
"bluebird": "^3.5.3",
"color": "^3.1.0",
"mapbox-gl": "^0.50.0",
"mapbox-gl-utils": "^0.4.0",
"thenify": "^3.3.0",
"vue": "^2.5.17",
"vue-carousel": "^0.16.0-rc2"
},
"devDependencies": {
"#vue/cli-plugin-babel": "^3.0.5",
"#vue/cli-plugin-eslint": "^3.2.1",
"#vue/cli-service": "^3.0.5",
"babel-eslint": "^10.0.1",
"babel-loader": "^8.0.4",
"copy-webpack-plugin": "^4.6.0",
"eslint": "^5.9.0",
"eslint-plugin-vue": "^5.0.0",
"less": "^3.9.0",
"less-loader": "^4.1.0",
"pug": "^2.0.3",
"pug-plain-loader": "^1.0.0",
"vue-template-compiler": "^2.5.17"
},
"postcss": {
"plugins": {
"autoprefixer": {}
}
},
"browserslist": [
"> 1%",
"last 2 versions",
"not ie <= 8"
]
}
and my vue.config.js is (simplified):
const CopyWebpackPlugin = require('copy-webpack-plugin')
const path = require('path');
module.exports = {
chainWebpack: config => {
config.module
.rule('eslint')
.use('eslint-loader')
.tap(options => {
options.configFile = path.resolve(__dirname, ".eslintrc.js");
return options;
})
},
configureWebpack: {
plugins: [
new CopyWebpackPlugin([
{ ... }
]
}
}
I suspect, without being certain, that the problem is triggered when I make updates in my module, which is linked using npm link.
Using Vue CLI version 2.1.1.
As a workaround, if I use an ES2015 export statement instead, yes, the app works, but then I can't run my test suite with NodeJS.
I would love any suggestions for how to make my environment more stable so this intermittent problem doesn't recur.
According to https://github.com/vuejs/vue-cli/issues/3227 this is due to some configurable behaviour. Add this in your vue.config.js:
module.exports = {
chainWebpack: (config) => {
config.resolve.symlinks(false)
}
}
It's working in my case.
I've run into this problem even after adding
chainWebpack: (config) => {
config.resolve.symlinks(false)
}
to my vue.config.js
To resolve, I deleted my node_modules folder and ran a fresh npm install

Unexpected token import error in while running jest tests

I know this has been asked countless times, but I am not able to fix the problem inspite of following all the SO solutions and suggestions.
I came to know about jest a few days ago and tried to have my hands on it. There is a good tutorial mentioned on DZone about using jest to test react components. However, when I try testing one of the components from the starter directory, I am having this issue,
SyntaxError: Unexpected token import
at ScriptTransformer._transformAndBuildScript (../../../../../../usr/local/lib/node_modules/jest/node_modules/jest-runtime/build/ScriptTransformer.js:289:17)
at emitTwo (events.js:106:13)
As per suggested in this SO post, I have already installed babel-preset-react and added it to my webpack.config.js file.
Here is my webpack.config.js file, my package.json file , the .babelrc file
Please note that I have already gone through the solutions posted in these SO posts -
Link 1
Link 2
Link 3
which might be apparent from the changes in my .babelrc and webpack files
But I'm not able to fix the issue that I'm having. Please let me know if I am missing something here, since I have spent a good 3-4 hrs searching SO and other forums for any answer and I can't seem to find it.
Update 1: Here is my test file - Clock.test.jsx
import React from 'react';
import ReactDOM from 'react-dom';
import Clock from 'Clock';
describe('Clock',()=>{
it("renders without crashing",()=>{
const div = document.createElement('div');
ReactDOM.render(<Clock/>,div);
});
});
I was trying to follow up that tutorial but could not even install it without errors. As I see it, the tutorial is old, webpack 1 is deprecated, and other packages also undergone changes. You could try my steps, but it may not work for you.
In the starter/CountdownTimer folder run npm install. If it throws
this errors: “Cannot read property 'find' of undefined”, then run npm cache verify and npm install.
Then run npm install –save-dev jest#18.0.0 to install jest.
In the app folder create __tests__ folder in there create app.test.jsx
and Clock.test.jsx.
Add “jest” to the package.json test script.
Change your .babelrc.
Here is how the files look like:
// app.test.jsx
describe('App', () => {
it('should be able to run tests', () => {
expect(1 + 2).toEqual(3);
});
});
// Clock.test.jsx
import React from 'react';
import ReactDOM from 'react-dom';
// Note the path.
import Clock from '../components/Clock';
describe('Clock',()=>{
it("renders without crashing",()=>{
const div = document.createElement('div');
ReactDOM.render(<Clock/>,div);
});
});
// package.json
{
"name": "countdown-timer",
"version": "0.0.1",
"description": "",
"main": "server.js",
"scripts": {
"start": "node server.js",
"test": "jest"
},
"author": "Joyce Echessa",
"license": "MIT",
"dependencies": {
"express": "^4.14.0",
"react": "^15.4.0",
"react-dom": "^15.4.0"
},
"devDependencies": {
"babel-core": "^6.18.2",
"babel-loader": "^6.2.8",
"babel-preset-es2015": "^6.18.0",
"babel-preset-react": "^6.16.0",
"css-loader": "^0.26.0",
"foundation-sites": "^6.2.4",
"jest": "^18.0.0",
"jquery": "^3.1.1",
"node-sass": "^3.13.0",
"sass-loader": "^4.0.2",
"script-loader": "^0.7.0",
"style-loader": "^0.13.1",
"webpack": "^1.13.3"
}
}
// .babelrc
{
"presets": [["es2015"], ["react"]]
}
Run npm test. This worked for me to get tests passing, hope it will help you too.

Categories