Get error module not found in component file - reactjs

I'm trying to write unit test. I just import my component file inside test.file. When trying run test. It gives error module not found for file import in file component, while in file component the import is working fine.
Component file - example.tsx
import getConfig from '#/component/utils/appConfig'
jest.config.js
module.exports = {moduleDirectories:["node_modules","src"]}
test.spec.js
import example from '../../example.js'
describe('example',() => {
it('render component file',()=> {
const container = render(<example/>);
})})
after 'npm run test'
then, get error
cannot find module '#/component/utils/appConfig' from example.tsx

The way we usually use import is based on relative path.
.and .. are similar to how we use to navigate in terminal like cd .. to go out of directory and mv ~/file . to move a file to current directory.
Your Statement Should be like this...
import getConfig from './component/utils/appConfig'

Related

How to import src module to public folder in react?

As I'm using Firebase Cloud Messaging in my React, it requires me to put the firebase-messaging-sw.js in my public folder.
In there, it is defining the function for the onBackgroundMessage, which I want to have an access to my module, and update some of my components in my src.
import { toast } from "react-toastify"; // or import my other modules
messaging.onBackgroundMessage(function(payload) {
console.log('Received background message ', payload);
//toast or do some updating my modules
toast(`Message received : ${payload}`) // here comes the error
});
But I got an error of
Uncaught SyntaxError: Cannot use import statement outside a module (at
firebase-messaging-sw.js:3:1)
How can I import my src module to the public folder?
How should I properly use the onBackgroundMessage in React?
is it normal to import module from src to the public folder?
Use importScripts to import scripts into the worker's scope like firebase-messaging itself.
importScripts('https://www.gstatic.com/firebasejs/9.2.0/firebase-messaging.js');

Storybook integration with Expo React Native not working

I am trying to get Storybook running on a react native app build by Expo. I generated my project with:
expo init storybook-test
I entered the folder and ran:
npx -p #storybook/cli sb init --type react_native
...which I got from this tutorial and it added multiple files and folders such as:
- Root
- - storybook
- - - stories
- - - addons.js
- - - index.js
- - - rn-addons.js
It then told me to:
add the following to your entrypoint (usually App.js or index.js).
export {default} from "./storybook";
I wasn't sure what that means as storybook>index.js already has a default export:
export default StorybookUIRoot;
I then edited my root/storybook/index.js as there is no main.js in my project to the following:
// if you use expo remove this line
// import { AppRegistry } from 'react-native';
import { getStorybookUI, configure, addDecorator } from '#storybook/react-native';
// import { withKnobs } from '#storybook/addon-knobs';
import './rn-addons';
// enables knobs for all stories
// addDecorator(withKnobs);
// import stories
configure(() => {
require('./stories');
}, module);
// Refer to https://github.com/storybookjs/react-native/tree/master/app/react-native#getstorybookui-options
// To find allowed options for getStorybookUI
const StorybookUIRoot = getStorybookUI({});
// If you are using React Native vanilla and after installation you don't see your app name here, write it manually.
// If you use Expo you should remove this line.
// AppRegistry.registerComponent('%APP_NAME%', () => StorybookUIRoot);
export default StorybookUIRoot;
After all this, I ran yarn storybook and it opened the webpage but the stories never load.
What am I doing wrong?!

How to conditionally import file in Reactjs

I have have a large application that monitors a file called routes.js . I can not change the file name or mess with routes.js at all. I need to load another file based on a useState variable from another component when a condition is met. This following code will need to be put in Apps.js example:
if (!change) {
import routes from "routes";
} else {
import routes from "newroutes"
}
Is this possible?
You can just alias the imports.
import routes_1 from "routes";
import routes_2 from "newroutes"
Then, you can just declare a variable: routes and assign the appropriate value to it.
routes = !change ? routes_1 : routes_2;
It's possible to do using Webpack lazy loading (if you build your app using Webpack):
import(/* webpackChunkName: "routes" */ './routes').then(module => {
const routes = module.default;
});
But probably you will need to adjust your build config. Also this import is returning a promise, so you should write your code in the callback.
Update: but in your case it seems you don't need it. You could do something like this:
import file1 from 'routes'
import file2 from 'newroutes'
let routes = file1
if (change) {
routes = file2
}
So you will have your routes variable unchanged

Is there a way to import an MDX or MD markdown file in React and use it in a data array?

I want to make a list of blog posts and therefor I thought it would be easy to use MDX because it helps with styling each blog text. But I don't know if it's possible to import a MDX file and put it in blogs.text.
I tried to use the npm package mdx.macro with it's function importMDX, but I get an error which says that the imported file is outside the src/.
mdx.macro documentation: https://www.npmjs.com/package/mdx.macro
import React, { lazy } from 'react';
import { importMDX } from 'mdx.macro';
const blog1 = lazy(() => importMDX('./blog1.md'));
export const blogs = [
{
title: "Hello World",
subtitle: "subtitle",
text: blog1
}
];
export default blogs;
I import this file in my blog and loop through all the items. But the importMDX keeps giving me the following error:
Module not found: You attempted to import
node_modules\.cache\mdx.macro\Content.6cbf05377c.mdx.js
which falls outside of the project src/ directory.
Relative imports outside of src/ are not supported.
Maybe there's an easier option than this?
Thanks in advance!
Adding to #mfakhrusy's answer , I had to change my blogs.js file to
import { mdx } from 'mdx.macro';
import Blog1 from './Blog1.js';
export const blogs = [
{
title: "My experiences as an intern working without getting paid",
subtitle: "And the difficulties that come along with being undervalued by a company",
text: <Blog1 />
}
];
export default blogs;
And my Blog1.js file contains this
import React from 'react';
import { mdx } from 'mdx.macro';
export const Blog1 = mdx`
# Don't Panic
Since we decided a few weeks ago to adopt the leaf as legal tender, we have, of course, all become immensely rich.
`
export default Blog1;
So now I can write blogs in markdown format and loop through them to show them on my website!
According to The create-react-app imports restriction outside of src directory
It's a restriction from CRA developer. You can try to eject your CRA app and try it again. (see eject script on package json), and remove ModuleScopePlugin from webpack config. Be careful though, eject is a one-way trip, you cannot go back.
It happens because from what I've seen from the doc, the package tries to generate a cache file which being imported later by the app, and CRA would prohibit that by throwing that error you encountered.

TypeError: __webpack_require__.i(...) is not a function

I am getting a webpack TypeError when I am trying to simplify an import. The following code works without any issues. Here I am importing a React Higher-Order-Component (HOC) called smartForm from core/components/form/index.js.
core/components/form/index.js (does a named export of smartForm)
export smartForm from './smart-form';
login-form.jsx (imports and uses smartForm)
import { smartForm } from 'core/components/form';
class LoginForm extends React.Component {
...
}
export default smartForm(LoginForm);
However, I want to simplify the import to just import { smartForm } from 'core'. So I re-exported smart-form in core/index.js and imported it from core. See the code below:
core/index.js (does a named export of smartForm)
export { smartForm } from './components/form';
// export smartForm from './components/form'; <--- Also tried this
login-form.jsx (imports and uses smartForm)
import { smartForm } from 'core';
class LoginForm extends React.Component {
...
}
export default smartForm(LoginForm); // <--- Runtime exception here
This code compiles without any issues, but I am getting the following runtime exception at the line export default smartForm(LoginForm);:
login-form.jsx:83 Uncaught TypeError: webpack_require.i(...) is not a function(…)
What am I missing?
P.S. Here are the Bable and plugin versions that I am using:
"babel-core": "^6.18.2",
"babel-preset-es2015-webpack": "^6.4.3",
"babel-preset-react": "^6.16.0",
"babel-preset-stage-1": "^6.16.0",
tl;dr
For the questioner: Add this to your webpack.config.js:
resolve: {
alias: {
core: path.join(__dirname, 'core'),
},
},
For the general audience: Make sure the thing you try to import is indeed exists in that package.
Explanation
Questioner's problem: importing own code like npm modules
You try to import your module's exports in the same fashion how you import something from an npm package from the node_modules folder: import { something } from 'packagename';. The problem with this is that doesn't work out of the box. The Node.js docs give the answer on why:
Without a leading '/', './', or '../' to indicate a file, the module must either be a core module or is loaded from a node_modules folder.
So you either has to do what Waldo Jeffers and Spain Train suggested and write import { smartForm } from './core', or you can configure webpack so it can resolve your import path via its aliases which are created to solve this exact problem.
Debugging the error message in general
This error can arise if you try to import something from an existing npm package (in node_modules) but the imported thing doesn't exist in the exports. In this case, make sure there were no typos and that the given thing you try to import is indeed in that package. Nowadays it is trendy to break libraries into multiple npm packages, you might be trying to import from a wrong package.
So if you get something like this:
TypeError: __webpack_require__.i(...) is not a function
at /home/user/code/test/index.js:165080:81
at Layer.handle [as handle_request] (/home/user/code/test/index.js:49645:5)
To get more information on what import you should check, just open the output file generated by webpack and go to the line marked by the topmost line in the error stack (165080 in this case). You should see something like: __webpack_require__.i(__WEBPACK_IMPORTED_MODULE_9_react_router_dom__["match"]). This tells us that there is no match export (or there is but it isn't a function) in react-router-dom, so we need to check our stuff around that import.
Since core is a folder of your app and not an npm module, Webpack can not understand which file you want to load. You must use a correct path pointing to a file. You have to replace import { smartForm } from 'core'; by import { smartForm } from './core/index.js
This error will occur by many reasons. Once I encountered this error when I add js in file-loader then when I removed it start to work correctly.
{
test: /\.(ttf|eot|svg|gif|jpg|png|js)(\?[\s\S]+)?$/,
use: 'file-loader'
},
When I remove |js it works
{
test: /\.(ttf|eot|svg|gif|jpg|png)(\?[\s\S]+)?$/,
use: 'file-loader'
},
Just remove these 2 line from config
const context = resolve.alias.context('./', true, /\.spec\.ts$/); context.keys().map(context);

Resources