I'm writing this app using React and I was trying to package it up in NPM to use it in a different project.
I have as my index.js entrypoint something like this:
import { MyReactComponent } from './mypackage';
export { MyReactComponent } // for 3rd party packages who use this package
// to display the component when I'm running this package to test out changes
ReactDOM.render(
<MyReactComponent />,
document.getElementById('react')
)
If I want to use my package in another library, I should delete the ReactDOM.render() part because that's causing problems. But I'd still like the render part when I'm testing changes "standalone".
Is there something I can do? I think I want a setup similar to Python's if __name__ == "__main__": paradigm. I'm also willing to switch to the React way of doing it, if there is one.
In hindsight, this question could have been better narrowed down to be about Webpack configuration, as it appears that Reactjs does not specify or care how you package things up.
I added multiple entrypoints to my Webpack config as you can see in the webpack.config.js excerpt below:
entry: {
main: './src/index.js',
standalone: './src/index-standalone.js'
},
And the contents of index.js and index-standalone.js look like this:
index.js
import React from 'react'
import ReactDOM from 'react-dom'
import { MyReactComponent } from './mypackage';
export { MyReactComponent }
index-standalone.js
import React from 'react'
import ReactDOM from 'react-dom'
import { MyReactComponent } from './mypackage';
ReactDOM.render(
<MyReactComponent />,
document.getElementById('react')
);
The intention is to have the main entry point not be hardcoded to insert a react element anywhere. This is meant for 3rd party users to import the package and do whatever they please.
The standalone entry point has the original code to interact with my test harness.
Related
I am working with a React project where each component's files are contained in their own directory. I have a component.jsx file and an index.js file that re-exports the component's default export. This works as expected. I would like to simplify my import statements by re-exporting all components up directory level from the main components folder. See below for an example of my current project foloder structure.
src
--components
----Alert
------Alert.jsx
------index.js
----LoginCard
------LoginCard.jsx
------index.js
--index.js
Alert/Alert.jsx
export default function Alert(props) {
// omitted for brevity - the component itself works fine
return <Alert />
}
Alert/index.js
export { default } from './Alert';
At this point, imports work as expected in the LoginCard component.
LoginCard.jsx
import { UserContext } from '#contexts';
import Alert from '#components/Alert';
export default function LoginCard(props) {
// omitted for brevity. Again, component works as expected
return <LoginCard />
In order to achieve my desired end result of simplifying import calls, I created components/index.js:
components/index.js
export { default as Alert } from './Alert';
Which I then attempt to import as:
LoginCard.jsx
import { Alert } from '#components'
When attempting to import from component/index.js as import { Alert} from '#components' I receive an exception that states "cannot read default property of undefined". What makes this strange is that I import/export my pages and contexts in exactly the same manner and they work as expected. I originally thought that this implied an issue with my components directory alias, but the alias is working as I can import just fine from #components/Alert, just not from #components
Have a missed something simple, or am I hitting a bug? Thanks.
I think the issue here is that you are attempting to push all the exports up the tree towards the root directory. This makes sense when importing somewhere outside that root directory. The issue lies in the fact that you are attempting to import from the root while inside the directory structure. In other words, all the exports from within the directory need to be processed before anything can be exported from the root.
The snag here is that you are attempting to import Alert from the root export from LoginCard... which while being processed hasn't finished its exports, so the root export isn't ready yet.
In other words, #components/Alert is ready, #components is not.
Just use a relative import of Alert (and any other import) from within the same components directory.
import { UserContext } from '#contexts';
import Alert from '#components/Alert';
// or
import Alert from '../Alert';
export default function LoginCard(props) {
// omitted for brevity. Again, component works as expected
return <LoginCard />
So I'm new to React.
I want to style a simple text and found out how to use styles, but when I want to change something in the CSS I have to restart my React App which always takes 3 Minutes.
I use npm start to start the React server that was created with create-react-app.
How can I let React update when the CSS file is changed?
I have an index.js that looks like this:
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import App from './Frontend/App.js';
import './Frontend/style/main.css';
ReactDOM.render(<App/>, document.getElementById('root'));
And an App.js that looks like this:
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import './style/main.css';
class App extends Component {
render() {
var pageHeading = (
<h1 className="pageHeading">bosleeir.it</h1>);
return pageHeading;
}
}
export default App;
Remember that you need to import your CSS in your component. I wouldn't recommend to do it on index.js
I'm assuming your folder structure is:
which could lead me that:
You're using an older version of React
You have modified the structure of your files
So double-check if the path are configured correctly.
I want to build a package and upload it to npm so I tried to create a demo package first.
I used this repo as a starter package: https://github.com/wobsoriano/vite-react-tailwind-starter
and updated the build script to this
"build-test": "esbuild src/App.tsx --bundle --minify --outfile=src/dist/index.js",
and the App.tsx i updated to this
import React from "react";
import "./index.css";
const App = () => {
return <div>My Dummy</div>;
};
export default App;
Then I tried to build it and import it in my main.tsx like this:
import React from "react";
import ReactDOM from "react-dom";
import App from "./dist/index.js";
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById("root")
);
And then I get this error:
The requested module '/src/dist/index.js' does not provide an export
named 'default
I only can give you a quick manual fix. For some reason the index.js file has no "export default" keywords, but you can open the src\dist\index.js file and you can just insert the "export default " at the very begin. So the begin will look like this:
export default ()=>{var K=Object.create;var _=Object.define.
Because the whole index.js just a function, you can do this.
In React when you wanna import components from other files we use:
import ComponentName from 'somePlace';
That works fine, but I wanna know if there is a way to import the content of a file instead of the exports. I wanna put all import statements for components in a single file (e.g. imports.js) and have a statement like:
import './import.js' to all documents;
so all my components are automatically imported everywhere.
Is there a way to do that?
Globally import modules? Not really, no. And neither should you need to.
A hacky "solution" would be assigning all imports to the global context (e.g. window in the browser) so it's accessible that way. That's possible, but definitely not recommended. It'll also prevent your bundler (most likely Webpack) from optimizing a lot of code.
Apart from the technical aspect, there are other reasons not to do so. If you specify the imports in each file, you know exactly what imports that file needs and under what variables it is imported as for that file.
If you still want to simplify importing the same components over and over again, you can have this setup:
imports.js
// For default exports
import ComponentA from 'wherever';
export { ComponentA };
// For regular exports
//import { ComponentB } from 'wherever';
export { ComponentB } from 'wherever';
// For whole modules
//import * as wherever from 'wherever';
export * as wherever from 'wherever';
someOtherFile.js
// Either import as a namespace
import * as Imports from './imports';
console.log([
Imports.ComponentA,
Imports.ComponentB,
Imports.wherever.someFieldFromTheWhereverModule,
]);
// Or partial import
import { ComponentA, ComponentB } from './imports';
I am trying to import an npm package into a Vue component.
The package (JSPrintManager - here) is just a JavaScript file with no exports. Consequently, I cannot use:
import { JSPM } from "jsprintmanager"
I have also had no success with the following:
import JSPM from "jsprintmanager"
import * as JSPM from "../../node_modules/jsprintmanager/JSPrintManager"
import * as JSPM from "../../node_modules/jsprintmanager/JSPrintManager.js"
Am I barking up the wrong tree?
If there is no way to import an npm package that is not a module, is there another way to load the relevant JavaScript file (currently residing in my node-modules directory) into my component?
I am using the Vue CLI
jspm.plugin.js
import * from '../../node_modules/jsprintmanager/JSPrintManager';
export default {
install(Vue) {
Vue.prototype.$JSPM = window.JSPM
}
}
main.js
import Vue from 'vue'
import JSPM from './jspm.plugin';
Vue.use(JSPM);
In any of your components you can now access JSPM as this.$JSPM
If you want to use it outside of your components (say, in store) and you want it to be the same instance as the one Vue uses, export it from Vue, in main.js
const Instance = new Vue({
...whatever you have here..
}).$mount('#app');
export const { $JSPM } = Instance
Now you can import { $JSPM } from '#/main' anywhere.
That would be the Vue way. Now, in all fairness, the fact your import is run for the side effect of attaching something to the window object which you then inject into Vue is not very Vue-ish. So the quick and dirty way to do it would be, in your component:
import * from '../../node_modules/jsprintmanager/JSPrintManager';
export default {
data: () => ({
JSPM: null
}),
mounted() {
this.JSPM = window.JSPM;
// this.JSPM is available in any of your methods
// after mount, obviously
}
}
The main point of the above "simpler" method is that you have to make the assignment after the page finished loading and running the JSPM code (and window.JSPM has been populated).
Obviously, if you disover it sometimes fails (due to size, poor connection or poor hosting), you might want to check window.JSPM for truthiness and, if not there yet, call the assignment function again after in a few seconds until it succeeds or until it reaches the max number of tries you set for it.