So I've been trying to run my react native code but it keeps coming up with different errors. I've managed to solve them from solutions I found online but I can't seem to find this particular problem.
When I run react-native run-android I get this error
Failed to compile.
C:/Users/Stephen Murya/Desktop/dev/react-native/FaceAttendance/node_modules/react-native/Libraries/Components/UnimplementedViews/UnimplementedView.js
Module not found: Can't resolve 'StyleSheet' in 'C:\Users\Stephen Murya\Desktop\dev\react-native\FaceAttendance\node_modules\react-native\Libraries\Components\UnimplementedViews'
Error from chokidar (C:\): Error: EBUSY: resource busy or locked, lstat 'C:\DumpStack.log.tmp'
Error from chokidar (C:\node_modules): Error: EBUSY: resource busy or locked, lstat 'C:\DumpStack.log.tmp'
This is the content of the js file in UnimplementedViews
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* #flow strict-local
* #format
*/
'use strict';
const React = require('React');
const StyleSheet = require('StyleSheet');
/**
* Common implementation for a simple stubbed view. Simply applies the view's styles to the inner
* View component and renders its children.
*/
class UnimplementedView extends React.Component<$FlowFixMeProps> {
setNativeProps() {
// Do nothing.
// This method is required in order to use this view as a Touchable* child.
// See ensureComponentIsNative.js for more info
}
render() {
// Workaround require cycle from requireNativeComponent
const View = require('View');
return (
<View style={[styles.unimplementedView, this.props.style]}>
{this.props.children}
</View>
);
}
}
const styles = StyleSheet.create({
unimplementedView: __DEV__
? {
alignSelf: 'flex-start',
borderColor: 'red',
borderWidth: 1,
}
: {},
});
module.exports = UnimplementedView;
I don't know what seems to be the problem here
Related
I'm bundling my CLI app using Webpack v4. One of the dependencies is Express, and this causes a warning:
WARNING in ./node_modules/express/lib/view.js 81:13-25
Critical dependency: the request of a dependency is an expression
# ./node_modules/express/lib/application.js
# ./node_modules/express/lib/express.js
# ./node_modules/express/index.js
That comes from this line within Express:
/**
* Initialize a new `View` with the given `name`.
*
* Options:
*
* - `defaultEngine` the default template engine name
* - `engines` template engine require() cache
* - `root` root path for view lookup
*
* #param {string} name
* #param {object} options
* #public
*/
function View(name, options) {
var opts = options || {};
this.defaultEngine = opts.defaultEngine;
this.ext = extname(name);
// ...
if (!opts.engines[this.ext]) {
// load engine
var mod = this.ext.substr(1)
debug('require "%s"', mod)
// default engine export
var fn = require(mod).__express // <-- this require is the problem
There's quite a few questions asking about how to fix this by not bundling express at all, or not bundling anything from node_modules.
For me that would defeat the point (I'm trying to shrink my deployed file footprint), so I want to fix this whilst keeping express inside my bundle. In my case I don't use view engines at all, and this require exists solely to load view engines on demand, so I really just want the warning to go away.
If I'm confident that this require will never be called, how can I tell webpack to ignore it completely?
What you could maybe try is alter you webpack config module rules so that
view unit uses the null-loader
This will of course make View return null but if you never touch views it might be ok.
example.
rules: [
{
test: require.resolve("express/view"),
use: 'null-loader',
},
],
Looking at application
this.set('view', View); hopefully View been null here doesn't cause issues.
The only other place View is then mentioned in application is then in render that you say your not using. So fingers crossed this won't cause any side effects.
I have a Vue component that renders an Xterm.js terminal.
Terminal.vue
<template>
<div id="terminal"></div>
</template>
<script>
import Vue from 'vue';
import { Terminal } from 'xterm/lib/public/Terminal';
import { ITerminalOptions, ITheme } from 'xterm';
export default Vue.extend({
data() {
return {};
},
mounted() {
Terminal.applyAddon(fit);
this.term = new Terminal(opts);
this.term.open(document.getElementById('terminal'));
},
</script>
I would like to test this component.
Terminal.test.js
import Terminal from 'components/Terminal'
import { mount } from '#vue/test-utils';
describe('test', ()=>{
const wrapper = mount(App);
});
When I run jest on this test file, I get this error:
TypeError: Cannot set property 'globalCompositeOperation' of null
45 | this.term = new Terminal(opts);
> 46 | this.term.open(document.getElementById('terminal'));
Digging into the stack trace, I can see it has something to do with Xterm's ColorManager.
at new ColorManager (node_modules/xterm/src/renderer/ColorManager.ts:94:39)
at new Renderer (node_modules/xterm/src/renderer/Renderer.ts:41:25)
If I look at their code, I can see a relatively confusing thing:
xterm.js/ColorManager.ts
constructor(document: Document, public allowTransparency: boolean) {
const canvas = document.createElement('canvas');
canvas.width = 1;
canvas.height = 1;
const ctx = canvas.getContext('2d');
// I would expect to see the "could not get rendering context"
// error, as "ctx" shows up as "null" later, guessing from the
// error that Jest caught
if (!ctx) {
throw new Error('Could not get rendering context');
}
this._ctx = ctx;
// Somehow this._ctx is null here, but passed a boolean check earlier?
this._ctx.globalCompositeOperation = 'copy';
this._litmusColor = this._ctx.createLinearGradient(0, 0, 1, 1);
this.colors = {
foreground: DEFAULT_FOREGROUND,
background: DEFAULT_BACKGROUND,
cursor: DEFAULT_CURSOR,
cursorAccent: DEFAULT_CURSOR_ACCENT,
selection: DEFAULT_SELECTION,
ansi: DEFAULT_ANSI_COLORS.slice()
};
}
I'm not quite clear on how canvas.getContext apparently returned something that passed the boolean check (at if(!ctx)) but then later caused a cannot set globalCompositeOperation of null error on that same variable.
I'm very confused about how I can successfully go about mock-rendering and thus testing this component - in xterm's own testing files, they appear to be creating a fake DOM using jsdom:
xterm.js/ColorManager.test.ts
beforeEach(() => {
dom = new jsdom.JSDOM('');
window = dom.window;
document = window.document;
(<any>window).HTMLCanvasElement.prototype.getContext = () => ({
createLinearGradient(): any {
return null;
},
fillRect(): void { },
getImageData(): any {
return {data: [0, 0, 0, 0xFF]};
}
});
cm = new ColorManager(document, false);
});
But I believe that under the hood, vue-test-utils is also creating a fake DOM using jsdom. Furthermore, the documentation indicates that the mount function both attaches and renders the vue component.
Creates a Wrapper that contains the mounted and rendered Vue component.
https://vue-test-utils.vuejs.org/api/#mount
How can I successfully mock a DOM in such a way that I can test a Vue component that implements Xterm.js, using Jest?
There are multiple reasons for this.
First of all, Jest js uses jsdom under the hood, as I suspected.
Jsdom doesn't support the canvas DOM api out of the box. First of all, you need jest-canvas-mock.
npm install --save-dev jest-canvas-mock
Then, you need to add it to the setupFiles portion of your jest config. Mine was in package.json, so I added it like so:
package.json
{
"jest": {
"setupFiles": ["jest-canvas-mock"]
}
}
Then, I was getting errors about the insertAdjacentElement DOM element method. Specifically, the error was:
[Vue warn]: Error in mounted hook: "TypeError: _this._terminal.element.insertAdjacentElement is not a function"
This is because the version of jsdom used by jest is, as of today, 11.12.0 :
npm ls jsdom
└─┬ jest#24.8.0
└─┬ jest-cli#24.8.0
└─┬ jest-config#24.8.0
└─┬ jest-environment-jsdom#24.8.0
└── jsdom#11.12.0
Through the help of stackoverflow, I discovered that at version 11.12.0, jsdom had not implemented insertAdjacentElement. However, a more recent version of jsdom implemented insertAdjacentElement back in July of 2018.
Efforts to convince the jest team to use a more up to date version of jsdom have failed. They are unwilling to let go of node6 compatibility until the absolute last second (they claimed back in April), or alternatively don't want to implement jsdom at all anymore, and are recommending people fork their own versions of the repo if they want the feature.
Luckily, you can manually set which version of jsdom jest uses.
First, install the jest-environment-jsdom-fourteen package.
npm install --save jest-environment-jsdom-fourteen
Then, you need to modify the testEnvironment property of your jest config. So, now my jest config looks like:
package.json
"jest": {
"testEnvironment": "jest-environment-jsdom-fourteen",
"setupFiles": ["jest-canvas-mock"]
}
Now, I can run tests without errors.
Great answer above which was going to be my solution but since I'm using react-scripts I didn't really want to eject (testEnvironment is not supported config setting). So I had a look around in source code of react-scripts how I can potentially sneak in and override testEnvironment.
https://github.com/facebook/create-react-app/blob/master/packages/react-scripts/scripts/test.js
Line 124 looks quite interesting
resolvedEnv = resolveJestDefaultEnvironment(`jest-environment-${env}`);
So a brilliant idea came to my mind, no pun intended, to stick --env=jsdom-fourteen as command line arg. My CI command looks like this now
cross-env CI=true react-scripts test --coverage --env=jsdom-fourteen --testResultsProcessor=jest-teamcity-reporter
and it miraculously works :).
I also have setupTests.js file in src folder where I import jest-canvas-mock and jest-environment-jsdom-fourteen but before the --env hacky option the tests were spitting out the insertAdjacentElement mentioned above.
Obvs this is very hacky and it will break at some point but it's fine for now, hopefully Jest will start supporting JSDOM 14 soon.
I have created an empty react-native project but using type-script (like react-native init MyApp --template typescript), then installed on that react-navigation-tabs package, and the problem which I am facing is:
TS7016: Could not find a declaration file for module 'react-navigation-tabs'.
'.../node_modules/react-navigation-tabs/src/index.js' implicitly has an 'any' type.
Try `npm install #types/react-navigation-tabs` if it exists
or add a new declaration (.d.ts) file containing `declare module 'react-navigation-tabs';`
I did also try npm install --save-dev #types/react-navigation-tabs, and since no such package did exist,
for now I did workaround it like suggested in another post.
But coming back to the question in the title, it is really painful, I mean the information that the IDE needs to provide auto-completion are there, in the node_modules/react-navigation-tabs/src/index.js file, like:
/* #flow */
/* eslint-disable import/no-commonjs */
module.exports = {
/**
* Navigators
*/
get createBottomTabNavigator() {
return require('./navigators/createBottomTabNavigator').default;
},
get createMaterialTopTabNavigator() {
return require('./navigators/createMaterialTopTabNavigator').default;
},
/**
* Views
*/
get BottomTabBar() {
return require('./views/BottomTabBar').default;
},
get MaterialTopTabBar() {
return require('./views/MaterialTopTabBar').default;
},
/**
* Utils
*/
get createTabNavigator() {
return require('./utils/createTabNavigator').default;
},
};
How can we make the IDE (e.g. VS Code) show auto-completion using the data it can find in the existing node_modules/react-navigation-tabs/src/index.js file ?
Edit: Also, created a request/question on github.
In our app we are using absolute paths for import modules. We have react folder into our resolve root:
Folder structure
We are using webpack for build and develop app and it works ok, with the next options:
resolve: {
modules: [
'node_modules',
path.resolve('src')
]
},
I'm working on integration of storybook and found, that it can't find any module from this react folder.
ERROR in ./stories/index.stories.js
Module not found: Error: Can't resolve 'react/components/Button' in 'project_name/stories'
# ./stories/index.stories.js
for the next line:
import Button from 'react/components/Button';
As mark: I added resolve/modules to .storybook/webpack config and also if I try to import anything other from, for example services/xxx - it works.
Issues
react folder name conflicts with actual React package location: node_modules/react. Webpack tries to resolve to .resolution(default is node_modules) if the file does not exist in the path.
.resolution is not appropriate for this sort of usage. it is mostly used for package resolution because it can't tell source strings.
to change path selectively, use alias instead.
Solution
change your component folder's name so that it does not collide with node_modules/react. a good example is view/components/Button.
add alias to .storybook/main.js setting
// .storybook/main.js
const path = require('path');
module.exports = {
/* ... other settings goes here ... */
/**
* #param {import('webpack').Configuration} config
* */
webpackFinal: async (config, { configType }) => {
if (!config.resolve) config.resolve = {};
// this config allows to resolve `view/...` as `src/view/...`
config.resolve.alias = {
...(config.resolve.alias || {}),
view: path.resolve(__dirname, '../src/view'),
};
return config;
},
};
change storybook code in accordance with (1)
// Button.stories.jsx
import Button from 'view/components/Button';
//...
I'm using React Native and getting this error during build. I'm pretty sure it's because of the mismatch between the SDK and the support library but I couldn't find the correct values. What SDK version and support library should I use. Please help me I'm really in a tough spot.
:app:processDebugResources/Users/hg/Downloads/ecoway/android/app/build/intermediates/res/merged/debug/values-v26/values-v26.xml:15:21-54: AAPT: No resource found that matches the given name: attr 'android:keyboardNavigationCluster'.
/Users/hg/Downloads/ecoway/android/app/build/intermediates/res/merged/debug/values-v26/values-v26.xml:18:21-54: AAPT: No resource found that matches the given name: attr 'android:keyboardNavigationCluster'.
/Users/hg/Downloads/ecoway/android/app/build/intermediates/res/merged/debug/values-v26/values-v26.xml:15: error: Error: No resource found that matches the given name: attr 'android:keyboardNavigationCluster'.
/Users/hg/Downloads/ecoway/android/app/build/intermediates/res/merged/debug/values-v26/values-v26.xml:18: error: Error: No resource found that matches the given name: attr 'android:keyboardNavigationCluster'.
FAILED
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':app:processDebugResources'.
> com.android.ide.common.process.ProcessException: Failed to execute aapt
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.
BUILD FAILED
app/build.gradle
apply plugin: "com.android.application"
import com.android.build.OutputFile
/**
* The react.gradle file registers a task for each build variant (e.g. bundleDebugJsAndAssets
* and bundleReleaseJsAndAssets).
* These basically call `react-native bundle` with the correct arguments during the Android build
* cycle. By default, bundleDebugJsAndAssets is skipped, as in debug/dev mode we prefer to load the
* bundle directly from the development server. Below you can see all the possible configurations
* and their defaults. If you decide to add a configuration block, make sure to add it before the
* `apply from: "../../node_modules/react-native/react.gradle"` line.
*
* project.ext.react = [
* // the name of the generated asset file containing your JS bundle
* bundleAssetName: "index.android.bundle",
*
* // the entry file for bundle generation
* entryFile: "index.android.js",
*
* // whether to bundle JS and assets in debug mode
* bundleInDebug: false,
*
* // whether to bundle JS and assets in release mode
* bundleInRelease: true,
*
* // whether to bundle JS and assets in another build variant (if configured).
* // See http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Build-Variants
* // The configuration property can be in the following formats
* // 'bundleIn${productFlavor}${buildType}'
* // 'bundleIn${buildType}'
* // bundleInFreeDebug: true,
* // bundleInPaidRelease: true,
* // bundleInBeta: true,
*
* // whether to disable dev mode in custom build variants (by default only disabled in release)
* // for example: to disable dev mode in the staging build type (if configured)
* devDisabledInStaging: true,
* // The configuration property can be in the following formats
* // 'devDisabledIn${productFlavor}${buildType}'
* // 'devDisabledIn${buildType}'
*
* // the root of your project, i.e. where "package.json" lives
* root: "../../",
*
* // where to put the JS bundle asset in debug mode
* jsBundleDirDebug: "$buildDir/intermediates/assets/debug",
*
* // where to put the JS bundle asset in release mode
* jsBundleDirRelease: "$buildDir/intermediates/assets/release",
*
* // where to put drawable resources / React Native assets, e.g. the ones you use via
* // require('./image.png')), in debug mode
* resourcesDirDebug: "$buildDir/intermediates/res/merged/debug",
*
* // where to put drawable resources / React Native assets, e.g. the ones you use via
* // require('./image.png')), in release mode
* resourcesDirRelease: "$buildDir/intermediates/res/merged/release",
*
* // by default the gradle tasks are skipped if none of the JS files or assets change; this means
* // that we don't look at files in android/ or ios/ to determine whether the tasks are up to
* // date; if you have any other folders that you want to ignore for performance reasons (gradle
* // indexes the entire tree), add them here. Alternatively, if you have JS files in android/
* // for example, you might want to remove it from here.
* inputExcludes: ["android/**", "ios/**"],
*
* // override which node gets called and with what additional arguments
* nodeExecutableAndArgs: ["node"],
*
* // supply additional arguments to the packager
* extraPackagerArgs: []
* ]
*/
project.ext.react = [
entryFile: "index.js"
]
apply from: "../../node_modules/react-native/react.gradle"
/**
* Set this to true to create two separate APKs instead of one:
* - An APK that only works on ARM devices
* - An APK that only works on x86 devices
* The advantage is the size of the APK is reduced by about 4MB.
* Upload all the APKs to the Play Store and people will download
* the correct one based on the CPU architecture of their device.
*/
def enableSeparateBuildPerCPUArchitecture = false
/**
* Run Proguard to shrink the Java bytecode in release builds.
*/
def enableProguardInReleaseBuilds = false
android {
compileSdkVersion 25
buildToolsVersion "23.0.1"
defaultConfig {
applicationId "com.ecoway"
minSdkVersion 16
targetSdkVersion 25
multiDexEnabled = true
versionCode 1
versionName "1.0"
vectorDrawables.useSupportLibrary = true
ndk {
abiFilters "armeabi-v7a", "x86"
}
}
splits {
abi {
reset()
enable enableSeparateBuildPerCPUArchitecture
universalApk false // If true, also generate a universal APK
include "armeabi-v7a", "x86"
}
}
buildTypes {
release {
minifyEnabled enableProguardInReleaseBuilds
proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
}
}
// applicationVariants are e.g. debug, release
applicationVariants.all { variant ->
variant.outputs.each { output ->
// For each separate APK per architecture, set a unique version code as described here:
// http://tools.android.com/tech-docs/new-build-system/user-guide/apk-splits
def versionCodes = ["armeabi-v7a":1, "x86":2]
def abi = output.getFilter(OutputFile.ABI)
if (abi != null) { // null for the universal-debug, universal-release variants
output.versionCodeOverride =
versionCodes.get(abi) * 1048576 + defaultConfig.versionCode
}
}
}
}
dependencies {
compile project(':tipsi-stripe')
compile project(':react-native-maps')
compile ("com.google.android.gms:play-services-base:10.0.1") {
force = true;
}
compile ("com.google.android.gms:play-services-maps:10.0.1") {
force = true;
}
compile ("com.google.android.gms:play-services-gcm:10.0.1") {
force = true;
}
compile ('com.google.firebase:firebase-core:10.0.1') {
force = true;
}
compile ('com.google.firebase:firebase-messaging:10.0.1') {
force = true;
}
compile project(':react-native-svg')
compile project(':react-native-maps')
compile project(':react-native-image-crop-picker')
compile project(':react-native-fs')
compile project(':react-native-fcm')
compile project(':react-native-audio-toolkit')
compile fileTree(dir: "libs", include: ["*.jar"])
compile "com.android.support:appcompat-v7:25.0.0"
compile "com.facebook.react:react-native:+" // From node_modules
}
// Run this once to be able to run the application with BUCK
// puts all compile dependencies into folder libs for BUCK to use
task copyDownloadableDepsToLibs(type: Copy) {
from configurations.compile
into 'libs'
}
apply plugin: 'com.google.gms.google-services'
android/build.gradle
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.2.3'
classpath 'com.google.gms:google-services:3.0.0'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
mavenLocal()
jcenter()
maven {
// All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
url "$rootDir/../node_modules/react-native/android"
}
maven {
url "https://jitpack.io"
}
maven {
url "https://maven.google.com"
}
}
}
settings.gradle
rootProject.name = 'ecoway'
include ':tipsi-stripe'
project(':tipsi-stripe').projectDir = new File(rootProject.projectDir, '../node_modules/tipsi-stripe/android')
include ':react-native-maps'
project(':react-native-maps').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-maps/lib/android')
include ':react-native-svg'
project(':react-native-svg').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-svg/android')
include ':react-native-maps'
project(':react-native-maps').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-maps/lib/android')
include ':react-native-image-crop-picker'
project(':react-native-image-crop-picker').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-image-crop-picker/android')
include ':react-native-fs'
project(':react-native-fs').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-fs/android')
include ':react-native-fcm'
project(':react-native-fcm').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-fcm/android')
include ':react-native-audio-toolkit'
project(':react-native-audio-toolkit').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-audio-toolkit/android/lib')
include ':app'
I had the same issue, I tried to upgrade from 25 to 26 Android version (https://github.com/facebook/react-native/issues/18095) but I could not do it because it react native does not support 26 yet and then I downgrade to 25 and I found the same issue,
This works for me...
build.gradle file
android {
compileSdkVersion 25
buildToolsVersion '26.0.1'
defaultConfig {
minSdkVersion 18
targetSdkVersion 25
compile 'com.android.support:appcompat-v7:25.0.0'
AndroidManifest.xml
<uses-sdk android:minSdkVersion="18"
android:targetSdkVersion="25" />
React-native version 0.47.2
force Gradle to build all the dependencies with our main project SDK version and tools versions.
Add the following line to your project's android/build.gradle with your Android SDK dependency.
subprojects {
afterEvaluate {project ->
if (project.hasProperty("android")) {
android {
compileSdkVersion 27
buildToolsVersion "27.0.2"
}
}
}
}
refer to this link