I've been working on a React project and I'm having an issue trying to use ES6 to import several exported React node modules.
This is my code:
I should be able to include the AddFriendInput and FriendList from the hello folder without any issue. But I get this error when webpack/babel compiles:
ERROR in ./src/common/containers/Menu/indexRender.js
Module not found: Error: Cannot resolve 'file' or 'directory' ../../hello in /Users/markpaul/Documents/projects/patient-portal-app/src/common/containers/Menu
# ./src/common/containers/Menu/indexRender.js 122:13-35
The content of my AddFriendInput.js file is like so:
import React, { Component, PropTypes } from 'react';
export default class AddFriendInput extends Component {
constructor(props, context) {
super(props, context);
this.state = {
name: this.props.name || ''
};
}
render() {
return (
<div>
</div>
);
}
}
I use webpack with babel to transpile my files. My Babel config is:
{
"presets": ["react", "es2015", "stage-1"]
}
The only way I can get it to work is to do this:
import AddFriendInput from '../../hello/AddFriendInput/AddFriendInput';
import FriendList from '../../hello/FriendList/FriendList';
But as you can see, this looks horrible.
Can someone please help.
Thanks in advance.
Create home/index.js
import AddFriendInput from './AddFriendInput'
import FriendList from './FriedList'
export { AddFriendInput, FriendList }
OLD ANSWER:
Rename AddFriendInput.js to index.js and after that you can import like this:
import AddFriendInput from '../../hello/AddFriendInput'
ES6 module doesn't automatically load nested directories/files
import by directory name (../../hello) implies that you have hello/index.js
updates
you could just create home/index.js as #Sergey mentioned or there is a module named auto-import that watch your directory and update index.js for you.
I think you are not understand the commonJS.
if the ../../hello is a folder, nodejs will find index.js file. so you must be have a file ../../hello/index.js.
import AddFriendInput from '../../hello/AddFriendInput/AddFriendInput';
import FriendList from '../../hello/FriendList/FriendList';
module.exports = {
AddFriendInput,
FriendList
};
Related
I am writing a component library in/for react and using Rollup to bundle it. As part of the build process I am using Terser to make sure the bundle is as small as possible. As part of the minification process, Terser renames the variables and then renames then back at export. Like so:
export{_ as BtnResponsive,l as Button};
This works fine when importing my library into other ES modules. Like so:
import { BtnResponsive } from '#namespace/component-lib';
But when I create a Storybook story Button.stories.tsx and import my component like so:
import { ComponentStory, ComponentMeta } from '#storybook/react';
import { BtnResponsive } from '#namespace/component-lib';
export default {
title: 'Components/BtnResponsive',
component: BtnResponsive,
} as ComponentMeta<typeof BtnResponsive>;
const Template: ComponentStory<typeof BtnResponsive> = (args) => <BtnResponsive {...args} />;
export const Primary = Template.bind({});
Primary.args = { children: 'Primary', theme: 'primary' };
Storybook then renders the component in my story like
<_ theme="primary">
Primary
</_>
Storybook somehow doesn't respect the renamed export. Does anyone know how to either make storybook respect the component name? or know how I can adjust Terser so Storybook understands the name correctly?
Thanks in advance!
Terser apparently has options that you can use to prevent it from mangling function names. In my rollup.config.js I had to add the following:
terser({
keep_fnames: true,
})
It's a common thing to create a index.js file in an React application with the only purpose to export several modules, in order to avoid having too many import statements on other components. This can be done by:
index.js
export { Credits } from './Credits.js';
export { SocialMedia } from './SocialMedia.js';
any module that might use those exports:
import * as var_name from index.js
And this is very nice. It wraps exports into a single file. However, when I changed my project to React with typescript, I found that .tsx files cannot be exported like that. The image below is the error I got after changing the project to typescript and the extensions became .tsx
Is there a way of 'bundle' export React .tsx files with the structure shown above? If not, what is the simplest way of centralizing .tsx files export?
My webpack.config.js:
module.exports = {
module: {
rules: [{
test: /\.scss$/,
use: ["sass-loader"]
}]
}
};
You can definitely use the same style of having an index file to group up exports for a whole folder. The simplest way around your problem would be to omit the file extension (assuming you only have one "index" file in the folder).
For example, let's say you have a component in 'common/Example.tsx':
import React from 'react'
export const Example = () => (<div>I'm an example component</div>)
You can then export it in an index file 'common/index.tsx':
export { Example } from './Example'
And import it from somewhere else, e.g. 'App.tsx':
import { Example } from './common'
I created an NPM package that uses Webpack and Babel for transpiling/bundling.
In my package.json, I've got main set to "main": "build/index.js". And in my Webpack config, I have entry set to entry: { app: './src/index.js' }. My entry file is shown below.
Everything works fine when the package is installed. However, with this setup, two import paths are exposed for every helper:
This is a problem for editors that support auto imports, since they will sometimes auto import from 'my-package/build/utils/helper1' rather than the preferred path of 'my-package'.
So, two questions:
Is there any way to prevent the longer import path from being exposed?
What is considered best practice when creating NPM packages. Is my setup acceptable, or should I be doing something different?
Entry File:
import helper1 from './utils/helper1';
import helper2 from './utils/helper2';
export {
helper1,
helper2,
};
const myPackage = {
helper1,
helper2,
};
export default myPackage;
you can utilize Webpack resolve
I often use the first way:
export {
helper1,
helper2,
};
Recently, I found that we can use Object.freeze() to export. This is a good article.
I would suggest probably merge your helper1 and helper2 in one file and name it helpers, then you can put them in the class myPackage so that you then export them as a module like this
import myPackage from './utils/helper';
// OR import {helper1, helper2} from './utils/helpers';
export default class myPackage {
helper1,
helper2,
};
OR
import {myPackage} from './utils/helpers';
// OR import {helper1, helper2} from './utils/helpers';
module.exports.myPackage = (helper1, helper2) => {
this.helper1 = helper1;
this.helper2 = helper2;
};
I hope this helps.
I'm building an npm package (ES6 + Babel) for the first time and I'm having trouble connecting it all together so it can be imported by the end user.
My build (output) folder structure is the same as src:
build
- index.js
- BaseClass.js
sublclasses
- SubClassA.js
- SubClassB.js
SubClassA and SubClassB import and extend BaseClass and are both exported using the module.exports. The entry point, index.js, has only two lines:
import SubClassA from './subclasses/SubClassA'
import SubClassB from './subclasses/SubClassB'
package.json has the main field set to ./build/index.js.
When installing the project (or npm linking) into a test project, I write:
import SubClassA, SubClassB from 'my-package'
Import works, but imported classes are undefined. I've tried a couple more ways to do it, but it didn't work.
How should I do it properly?
EDIT: after changing index.js to:
import SubClassA from './subclasses/SubClassA'
import SubClassB from './subclasses/SubClassB'
module.exports = SubClassA
module.exports = SubClassB
it kind of works. 'Kind of' means that if I import both classes in the test project like so:
import SubClassA, SubClassB from 'my-package'
and then do:
let sca = new SubClassA()
it turns out to be SubClassB. If I ommit SubClassB from import, it works normally.
EDIT 2 - SOLUTION:
Per instructions in the comments below, I've changed the index.js file like so:
export { default as SubClassA } from './subclasses/SubClassA'
export { default as SubClassB } from './subclasses/SubClassB'
and I imported it in the test project like so:
import { SubClassA, SubClassB } from 'my-project' and it worked.
The problem is you're not exporting anything from your main file,
using es6 import/export syntax you can directly export it with:
export {default as SubclassA} from './subclasses/SubClassA'
export {default as SubclassB} from './subclasses/SubClassB'
then to you can use the named imports :
{SubClassA, SubClassB} from 'my-package'
I just started with React.js and I am unable to import component.
I have this structure as followed by this tutorial (YouTube link) :
-- src
----| index.html
----| app
------| index.js
------| components
--------| MyCompontent.js
This is my index.js:
import React from 'react';
import { render } from 'react-dom';
import { MyCompontent } from "./components/MyCompontent";
class App extends React.Component {
render() {
return (
<div>
<h1>Foo</h1>
<MyCompontent/>
</div>
);
}
}
render(<App />, window.document.getElementById('app'));
This is MyComponent.js:
import React from "react";
export class MyCompontent extends React.Component {
render(){
return(
<div>MyCompontent</div>
);
}
}
I am using this webpack file (GitHub link).
However, when I run this, my module fails to load.
I get this error in the browser console:
Error: Cannot find module "./components/MyCompontent"
[WDS] Hot Module Replacement enabled. bundle.js:631:11
[WDS] Errors while compiling. bundle.js:631:11
./src/app/index.js
Module not found: Error: Cannot resolve 'file' or 'directory' ./components/MyCompontent in /home/kuno/code/react-hoteli/src/app
resolve file
/home/kuno/code/react-hoteli/src/app/components/MyCompontent doesn't exist
/home/kuno/code/react-hoteli/src/app/components/MyCompontent.webpack.js doesn't exist
/home/kuno/code/react-hoteli/src/app/components/MyCompontent.web.js doesn't exist
/home/kuno/code/react-hoteli/src/app/components/MyCompontent.js doesn't exist
/home/kuno/code/react-hoteli/src/app/components/MyCompontent.json doesn't exist
resolve directory
/home/kuno/code/react-hoteli/src/app/components/MyCompontent/package.json doesn't exist (directory description file)
/home/kuno/code/react-hoteli/src/app/components/MyCompontent doesn't exist (directory default file)
[/home/kuno/code/react-hoteli/src/app/components/MyCompontent]
[/home/kuno/code/react-hoteli/src/app/components/MyCompontent.webpack.js]
[/home/kuno/code/react-hoteli/src/app/components/MyCompontent.web.js]
[/home/kuno/code/react-hoteli/src/app/components/MyCompontent.js]
[/home/kuno/code/react-hoteli/src/app/components/MyCompontent.json]
# ./src/app/index.js 11:20-56 bundle.js:669:5
Can't figure out what went wrong here.
For anyone coming here without a typo, and is using Webpack, be sure to check for a clause like this:
resolve: {
extensions: [".jsx", ".js"]
},
in your webpack.config.js.
This tells your transpiler to resolve statements like:
import Setup from './components/Setup'
to
import Setup from './components/Setup.jsx'
This way you don't need the extension.
You have a typo in your import. You're requesting MyCompontent. Change to:
import MyComponent from "./components/MyComponent";
And all typos as well.
You can try to import MyCompontent from "./components/MyCompontent.js"
like this
import MyCompontent from "./components/MyCompontent.js";
You have written that the filename is MyComponent.js.
Thus, your import should look like
import { MyCompontent } from './components/MyComponent.js'
The problem for me was that import line was not generated correctly. I have this scenario:
--src
----elements
-----myCustomText.tsx
this is myCustomText.tsx file:
export interface Props {
text: string;
}
const MyCustomText = ({ text }: Props) => (
<Text>{text}</Text>
);
export default MyCustomText
And the generated import was this:
import MyCustomText from '../../elements/MyCustomText';
and I changed it to this:
import MyCustomText from '../../elements/myCustomText'
I don't know why the generated import line was generated automatically wrong.
I found myself here without a typo and without a webpack issue.
The solution for me was to restart the typescript server via VS Code.
I just had this issue, no type or webpack config issues.
What fixed it was changing the import from relative to the app root directory to relative to the file:
import MyComponent from "src/components/MyComponent";
to
import MyComponent from "../components/MyComponent";
If you're getting this from Visual Studio Code auto-importing via the shortest route, you can change it so it imports relatively. By going here:
menu File → Preferences → Settings → User Settings,
"typescript.preferences.importModuleSpecifier": "relative"
export 'Component' (imported as 'Component') was not found in 'react'
if you find your self stuck with this error simply go to mini-create-react-context, and go to cjs, and go to index.js and add "React" example: you will find this (Component) solution (React.Component) only if you extends to React.Component in you pages
Note: I have only used this on VS Code