Cannot resolve module while trying to organize modules in React Native - javascript

I'm new to React Native and am trying to organize my React Native classes into modules to get rid of the "import from '../../../" mess. Here's my very simple folder structure:
Following the tutorial at here, I've structured my package.json as this for each folder:
{
"name": "#foldername"
}
Now, I'm trying to import Page (which is just a component superclass at this time, exported as default in the file):
import Page from '#app/components/core';
But it cannot be resolved. I've also tried:
import Page from '#app/#components/#core';
import { Page } from '#app/#components/#core';
import { Page } from '#app/components/core';
import { Page } from 'app/components/core';
None of them seem to be working. I've also tried them all without the # sign (removing it from both the package files and import statement), but no avail.
How can I organize my components to work that way (and it would be great if I knew what that # sign in front does, as I've also seen some tutorials without it)?
Here is my package.json in my root folder if it helps (haven't touched it, it's the way created by react-native init):
{
"name": "redacted",
"version": "0.0.1",
"private": true,
"scripts": {
"start": "node node_modules/react-native/local-cli/cli.js start",
"test": "jest"
},
"dependencies": {
"react": "16.8.3",
"react-native": "0.59.3"
},
"devDependencies": {
"#babel/core": "^7.4.0",
"#babel/runtime": "^7.4.2",
"babel-jest": "^24.5.0",
"jest": "^24.5.0",
"metro-react-native-babel-preset": "^0.53.1",
"react-test-renderer": "16.8.3"
},
"jest": {
"preset": "react-native"
}
}

add babel-plugin-module-resolver to devDependencies.
If you have .babelrc just delete it and add babel.config.js. And add aliases there. It should look like this
function babelConfig(api) {
if (api) {
api.cache(false);
}
const presets = ['module:metro-react-native-babel-preset'];
const plugins = [
[
'module-resolver',
{
alias: {
appColors: './src/Colors',
appConstants: './src/Constants',
components: './src/Components',
screens: './src/Screens',
utils: './src/utils'
},
cwd: 'babelrc'
}
]
];
return {
presets,
plugins
};
}
module.exports = babelConfig;
Then you can use import like this
import { YourComonent } from 'components';
make sure you have exported as default.
Also, don't try to set the alias names with capital letters
This works with the latest react-native (0.59.3).
Here is my devDependencies
devDependencies": {
"#babel/core": "7.4.0",
"#babel/runtime": "7.4.2",
"#react-native-community/eslint-config": "0.0.3",
"babel-eslint": "8.2.2",
"babel-jest": "24.5.0",
"babel-plugin-module-resolver": "^3.2.0",
"enzyme": "^3.9.0",
"enzyme-adapter-react-16": "^1.10.0",
"enzyme-to-json": "^3.3.5",
"eslint": "5.15.3",
"eslint-config-airbnb": "16.1.0",
"eslint-plugin-import": "2.12.0",
"eslint-plugin-jsx-a11y": "6.0.3",
"eslint-plugin-react": "7.9.1",
"eslint-plugin-react-native": "3.2.1",
"jest": "24.5.0",
"metro-react-native-babel-preset": "0.53.1",
"react-test-renderer": "16.8.3"
},

If you're using VSCode, Intellisense of the IDE does not recognise just the package.json; include a tsconfig/jsconfig JSON file (TypeScript [ftw]/ JavaScript)
In compilerOptions add :
"paths" : {
"#alias1*" : ["./alias1/*"],
.....
}
For all your aliases. Then the editor should pick up your files.
https://code.visualstudio.com/docs/languages/jsconfig
If you choose not to use VSCode, use Babel:
If your project doesn’t use Webpack - for example if you’re working with React Native, you can use your .babelrc file and a babel plugin to get aliasing set up.
Firstly, you’ll want to install babel-plugin-module-resolver with yarn or npm.
Once you’ve done that, open up your project’s .babelrc file, and under the plugins key, add this:
[
'module-resolver',
{
root: ['./src'],
alias: {
myAlias: './src',
},
},
];
Or use the package.json in root

It was my bad.
Instead of using it like:
import MyComponent from 'package/path/MyComponent'
I was using:
import MyComponent from 'package/path' (without my class file at the end).
I've imported it correctly (also removed the app package and the # prefixes and directly referenced components as a package in its package.json file) (including the component name):
import Page from 'components/core/Page';
It worked perfectly.

In tsconfig.json, add the following :
"compilerOptions": {
"baseUrl": "app"
...
}

Related

Can't import external NPM package to make angular library

package.json firstly I did this,
{
"name": "crypto-local-storage",
"version": "0.0.1",
"peerDependencies": {
"#angular/common": "^12.2.0",
"#angular/core": "^12.2.0",
"crypto-js": "^3.1.8",
"secure-web-storage": "^1.0.2"
},
"dependencies": {
"tslib": "^2.3.0"
},
"devDependencies": {
"#types/crypto-js": "^4.0.2"
}
}
Secondly, I did this
{
"name": "crypto-local-storage",
"version": "0.0.1",
"peerDependencies": {
"#angular/common": "^12.2.0",
"#angular/core": "^12.2.0"
},
"dependencies": {
"tslib": "^2.3.0",
"crypto-js": "^3.1.8",
"secure-web-storage": "^1.0.2"
},
"devDependencies": {
"#types/crypto-js": "^4.0.2"
}
}
But in my service file when I import secure-web-storage Like this
import * as SecureStorage from 'secure-web-storage';
I got this kinda message,
TS7016: Could not find a declaration file for module 'secure-web-storage'.
'D:/AMS/crypto-local-storage/projects/crypto-local-storage/node_modules/secure-web-storage/secure-storage.js'
implicitly has an 'any' type.  
Try `npm i --save-dev #types/secure-web-storage` if it exists or add a new declaration (.d.ts) file containing
`declare module 'secure-web-storage';`
secure-web-storage does not contain any #types/secure-web-storage file. So How could I get rid from this error ? I did not get any clear answer after googling so much.
My folder structure might be help you,
My Folder Structure Image
If running npm install -D #types/secure-web-storage didn't solve the problem use require instead of import.
const secureWebStorage= require('secure-web-storage');
You can also try to create a typings.d.ts file inside the src folder and manually add typings for it.
declare module 'secure-web-storage' {
export function someFunction(): void;
}
And then in your ts file, you can use something like -
import { someFunction } from 'secure-web-storage';
By using this method you can save a lot on bundle size instead of using -
const secureWebStorage= require('secure-web-storage');
which takes a lot of bundle size and makes the application slower. You can read more about this here - https://web.dev/commonjs-larger-bundles/

Error TS2305: Module #types/angular has no exported member 'cookies'

I am having an issue with cookies not being defined in angular scope.
npm run start builds and starts the app just fine,
but when trying to run npm test that executes jest command, I am getting this error:
`Test suite failed to run app/components/Component1/Component1.ts:1:10
error TS2305: Module '"../../../../../node_modules/#types/angular"' has no exported member 'cookies'.`
in Component1.ts there is this import: import { cookies } from 'angular';
Build and run - ok.
Testing - not ok.
If you know where the issue can be hidden, please help :) Thank you.
my package.json:
{
"dependencies": {
...,
"angular": "^1.8.0",
"angular-cookies": "1.8.0",
"babel-polyfill": "^6.2.0",
...
},
"devDependencies": {
"#types/angular": "^1.8.0",
"#types/angular-cookies": "^1.8.0",
"#types/jest": "^26.0.19",
"angular-mock": "^1.0.0",
"angular-mocks": "^1.8.2",
"angularjs-jest": "^0.1.4",
"babel-core": "^6.24.1",
"babel-loader": "^7.0.0",
"jest": "^26.6.3",
"ts-jest": "^26.4.4",
...
}
}
solution for my issue was adding angular-cookies to tsconfig.test.json file.
I still do not understand why angular-cookies since source code and production build is taking types and definitions from angular package (and through IDE I can link to angular module rather than angular-cookies).
But that's life is all about - mysteries.
{
"extends": "./tsconfig.json",
"compilerOptions": {
"types": [
"node",
"jest",
"angular-cookies" --> THIS VERY LINE SOLVED MY ISSUE
]
},
"include": [
"index.d.ts",
"**/*.test.ts"
]
}

difference between the import paths in vue

I am starting to get into vue and I dont exactly understand the syntax between the different imports.
For example it is possible to import something like this
import Vue from 'vue';
import axios from 'axios';
Where do you get the vue/axios from it confuses me a little because normally you would get it from a path. I'm sorry if this is answered elsewhere I couldn't find something.
Thank you in advance :-)
If you look in package.json you have a list of dependencies:
{
"name": "resources",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build"
},
"dependencies": {
"axios": "^0.20.0",
"core-js": "^3.6.5",
"vue": "^2.6.12",
},
"devDependencies": {
"#vue/cli-plugin-babel": "~4.5.6",
"#vue/cli-service": "~4.5.6",
"sass": "^1.26.11",
"sass-loader": "^10.0.2",
"vue-template-compiler": "^2.6.12"
},
"browserslist": [
"> 1%",
"last 2 versions",
"not dead"
]
}
These are npm packages installed using npm i <package>, they're present in your node_modules folder. You don't need relative paths for them, you just import them how you have in your snippet and node knows where to look.
How paths are resolved is defined and configured by the loader, in the case of Vue this is often Webpack.
You may find detailed information here: https://webpack.js.org/concepts/module-resolution/

Jest encountered an unexpected token when testing a Vue single file component

I have a vue application with single file components and i want to add unit tests to test the components. I'm trying to use jest like described here but i keep getting the error "Jest encountered an unexpected token" with the following details:
/some_path/MyRecipe.vue:1
<template>
^
SyntaxError: Unexpected token <
1 | import { shallowMount } from "#vue/test-utils"
> 2 | import MyRecipe from "../src/components/MyRecipe.vue"
| ^
3 |
4 | describe('MyRecipe', () => {
5 | test('is a Vue instance', () => {
at Runtime._execModule (node_modules/jest-runtime/build/index.js:1166:56)
at Object.<anonymous> (__tests__/MyRecipe.test.js:2:1)
After some research (e.g. from here) I gather that this is probably due to jest expecting a .js file, but the .vue single file components have html, javascript and css in them, usually dealt with by webpack and vue-loader. I've tried to follow jest configurations from various tutorials to make jest use vue-jest to transform .vue files, but the error persists. This is my package.json file (unnecessary parts removed):
{
"name": "all-recipes ",
"version": "0.1.0",
"private": true,
"scripts": {
// ...
"test": "jest"
},
"dependencies": {
// ...
"core-js": "^3.4.3",
"vue": "^2.6.10"
// ...
},
"devDependencies": {
"#vue/cli-plugin-babel": "^4.1.0",
"#vue/cli-plugin-eslint": "^4.1.0",
"#vue/cli-service": "^4.1.0",
"#vue/test-utils": "^1.0.3",
"babel-core": "^7.0.0-bridge.0",
"babel-eslint": "^10.0.3",
"babel-jest": "^26.0.1",
// ...
"jest": "^26.0.1",
"jest-serializer-vue": "^2.0.2",
"vue-jest": "^3.0.5",
"vue-template-compiler": "^2.6.10",
"vue-test-utils": "^1.0.0-beta.11"
},
// ...
"jest": {
"moduleFileExtensions": [
"js",
"json",
"vue"
],
"transform": {
".*\\.,(vue)$": "vue-jest",
"^.+\\.js$": "babel-jest"
},
"snapshotSerializers": [
"jest-serializer-vue"
]
}
}
Any idea what might be wrong, or some tips on how to debug this?
EDIT: I have looked into this question and I don't believe the answer there would solve my problem since what I am trying to import is a .vue file and not an .html file.
EDIT 2: I have a feeling that jest is somehow just not picking up the transforms, because removing them from package.json doesn't change anything.
EDIT 3: No, jest is correctly using vue-jest for transforming. If I uninstall vue-jest and try running the test again, jest complains that vue-jest is missing.
The solution to my problem turns out to be a bit anti-climatic.
The problem was that my regexp string to recognize .vue files was wrong and didn't pick up my MyRecipe.vue file. Therefore, vue-jest wasn't used to transform it for jest to interpret, hence the trouble understanding that the file in question started with a very non-js line; <template>. The regexp that works is ^[^.]+.vue$, so the transform section of my package.json file becomes
{
// ...
"jest": {
// ...
"transform": {
"^[^.]+.vue$": "vue-jest",
"^.+\\.js$": "babel-jest"
},
// ...
}
}
Met same issuesome time ago. What i found.
The problem was in the short note of template v-slot
template(v-slot:body)
It works to compile, but Jest throws an error
Jest encountered an unexpected token
This usually means that you are trying to import a file which Jest cannot parse, e.g. it's not plain JavaScript.
By default, if Jest sees a Babel config, it will use that to transform your files, ignoring "node_modules".
Here's what you can do:
• To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.
• If you need a custom transformation specify a "transform" option in your config.
• If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option.
There was two ways i fount to solve this:
Edit my jest.config.js, like this
globals: {
'vue-jest': {
pug: {
doctype: 'html',
},
},
},
Write a full note like this
template(v-slot:body="")
What worked for me was changing the transform of the vue-jest to what is shown in the documentation.
https://github.com/vuejs/vue-jest
so try using "^.+\\.vue$": "vue-jest" instead of "^[^.]+.vue$": "vue-jest"
full config might look like this
{
"jest": {
"moduleFileExtensions": ["js", "json", "vue"],
"transform": {
"^.+\\.js$": "babel-jest",
"^.+\\.vue$": "vue-jest"
}
}
}
I faced same issues tried many solution but none of them work ..below is following workaround in my case
Check package json has following dev dependency entries and jest configurations
"devDependencies": {
"babel-jest": "^23.6.0",
"#vue/cli-plugin-babel": "~4.5.0",
"#vue/cli-plugin-eslint": "~4.5.0",
"#vue/cli-plugin-unit-jest": "~4.5.0",
"#vue/cli-service": "~4.5.0",
"#vue/eslint-config-airbnb": "^5.0.2",
"#vue/test-utils": "^1.0.3",
"babel-eslint": "^10.1.0",
"eslint": "^6.7.2",
"eslint-plugin-import": "^2.20.2",
"eslint-plugin-vue": "^6.2.2",
},
"jest": {
"moduleFileExtensions": [
"js",
"jsx",
"json",
"vue"
],
"transform": {
"^.+\\.vue$": "vue-jest"
},
"moduleNameMapper": {
"^#/(.*)$": "<rootDir>/src/$1"
},
"snapshotSerializers": [
"jest-serializer-vue"
],
"testMatch": [
"**/tests/unit/**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.
(js|jsx|ts|tsx)"
],
"testURL": "http://localhost/"
}
Check babel.config.js
module.exports = {
presets: [
'#vue/cli-plugin-babel/preset',
],
};
check jest.config.js
module.exports = {
preset: '#vue/cli-plugin-unit-jest',
};
You need to install vue-jest (https://github.com/vuejs/vue-jest) with
npm install -D #vue/vue3-jest
Here are the available versions and their corresponding vue and jest versions
Vue version
Jest Version
Package
Vue 2
Jest <= 26
vue-jest#4
Vue 3
Jest <= 26
vue-jest#5
Vue 2
Jest 27
#vue/vue2-jest
Vue 3
Jest 27
#vue/vue3-jest
Then, you'll just have to update your jest configuration (in jest.config.ts for example) and add a transform section
"transform": {
"^.+\\.vue$": "#vue/vue3-jest"
}
Warning: be sure to update the npm install and the jest.config.ts with the vue-jest package that match your need!

Unable to resolve module in React Native IOS, but works in Android

The app is built successfully in X-code, but this error comes up right on start:
Unable to resolve module
`../node_modules/react-native/node_modules/react-apollo/react-apollo.browser.umd.js`
from `/Users/lau/Documents/project/watch/mobile/src/Screen.js`:
could not resolve
`/Users/lau/Documents/project/watch/mobile/node_modules/react-native/node_modules/react-apollo/react-apollo.browser.umd.js'
as a file nor as a folder
I think the problem is due to the extra /node_modules/react-native/ in the path.
There are files in ../node_modules/react-apollo/react-apollo.browser.umd.js but not in ../node_modules/react-native/node_modules/react-apollo/react-apollo.browser.umd.js. I don't understand why the path is prefixed with the unnecessary /node_modules/react-native/ in React Native IOS. Is it caused by the Search Path in the build settings?
Here is how I import react-apollo module in Screen.js:
import * as React from 'react'
import {Navigation} from 'react-native-navigation';
import {ApolloProvider} from "react-apollo";
The build settings:
package.json:
"dependencies": {
"apollo-cache-inmemory": "^1.2.7",
"apollo-cache-persist": "^0.1.1",
"apollo-client": "^2.3.8",
"apollo-client-preset": "^1.0.8",
"apollo-engine": "^1.1.2",
"apollo-link": "^1.2.2",
"apollo-link-batch-http": "^1.2.2",
"apollo-link-context": "^1.0.8",
"apollo-link-persisted-queries": "^0.2.1",
"apollo-link-state": "^0.4.1",
"react": "^16.4.2",
"react-apollo": "^2.1.11",
"react-native": "0.56.0",
"react-native-navigation": "^2.0.2471"
},
I just deleted the ./nodule_modules, run npm install and remove this block from .babelrc
"plugins": [
["module-resolver", {
"alias": {
"react-apollo": "react-apollo/react-apollo.browser.umd.js"
}
}]
]
Things are working fine.
Maybe there are conflicts in the versions of some apollo modules.

Categories

Resources