I'm using renderToString function from react-dom (on my server side). The code looks like (+/-):
import Home from './app/containers/Home';
const app = express();
app.get('**', (req, res) => {
const html = renderToString(<Home />);
res.set('Cache-Control', 'public, max-age=600, s-maxage=1200');
res.send(html);
});
Everything goes smooth, until I try to deploy it on the server.
Example error in the console:
Error: Error parsing triggers: Cannot find module 'store/Home/actions'
When it appears?
If I change my path to some other component, which does not use any other components (only modules from node, like react or react-redux) it works correctly.
But if I try to use some component which uses other components and imports them, e.g.:
var _CreateUser = require('components/Pages/CreateUser'); (it's in the rendered component)
Now it will fail with error:
Error: Error parsing triggers: Cannot find module 'components/Pages/CreateUser'
So currently Im stuck, because I have to use my whole app on server side, not just a single component which doesn't import anything :)
Why does it work this way? Why does it fail? Is it bad webpack config fail?
Looking forward for any help. Thank you.
Note, as I said above, if I render to string some component with any imports (that doesn't use any other component in it) - the server side rendering works fine and Im able to see the renderedToString content before page loads.
Everywhere you import local modules you need to include the directory in the path otherwise it will search node_modules for a named package and ultimately fail.
require('./store/Home/actions');
Or:
import HomeActions from './store/Home/actions';
...depending on which import style you're using. An accurate directory is always needed as a part of the import/require statement.
You're using a relative path, cd into and deploy from the functions directory so it's correct.
It looks like your Home component is inside functions/app/containers/Home and you need access to the file functions/app/store/Home/actions.
From your containers/Home file, you need to go up two directories to the app folder, then go down two directories to correct file. So
import HomeActions from '../../store/Home/actions'`.
Each ../ represents going up one directory to the parent folder. We went from
functions/app/containers/Home to
functions/app/containers/ to
functions/app and then we can specify which path to continue on from there with
store/Home/actions
Related
I'm trying to build my Next.js project but it keeps giving me this error in the terminal:
Error: Build optimization failed: found page without a React Component as default export in
pages/components/context/Context
That's the React context API file, there isn't supposed to be any default export there. Is this a bug or what?
You should move your components outside the pages folder. pages/ should only be used for page components as Next.js routing is based on its structure.
Next.js has a file-system based router built on the concept of pages.
When a file is added to the pages directory it's automatically available as a route.
By default, Next.js assumes anything under the pages folder is a page component and will try to build each file as a page.
Even though the above is the default behaviour, you can configure your Next.js app to include non-page files in the pages directory.
To do so, you can modify the pageExtensions entry in the next.config.js file as shown below. Then rename your page components to have a file extension that includes .page (_document.page.js, _app.page.js, index.page.js, etc).
module.exports = {
pageExtensions: ['page.tsx', 'page.ts', 'page.jsx', 'page.js']
}
With this configuration, Next.js will ignore any file that doesn't contain .page for the purpose of building pages/API routes and routing.
In my case, I had an empty file index.js in a folder. Using Nextjs Default Router
It seems to be not declared default export keyword in context component.
Try it as follow:
const Context = ()=>{
...
}
export default Context
I had the same error.
If you comment out all other code but leave this NextJS won't get mad at you:
export default function Home1() {
return <>{/* nothing */}</>;
}
I like to keep older index files and components locally and on github so this is a nice hack. I just copy all of the existing code add it to a new file and then add 1 to it for example:
index1.js
You can also leave a comment to kind of bring you and other devs up to speed as to why you did this for example:
//good for history of index implementation and associated syntax logic
I am creating a VSCode extension, and following the getting started guide (https://code.visualstudio.com/api/get-started/your-first-extension) have used yeoman scaffold to get started. I created a new file, newModule.js in the same directory and want to import it as a module for use in the main extension.js script. I then do:
const newModule = require('./newModule.js');
This throws an error:
cannot find module 'newModule' require stack: -
This problem disappears if I copy my file to the node_modules folder created by default. I would like to know what is going on here, and what the best way of handling imports is when working with javascript/Node.js/vs-extensions.
I also notice that node_modules folder is not pushed to github by default, why?
The node_modules folder is for storing all the code from the libraries and packages you are using. It is excluded from git because it is a waste of space and a distraction to store them all in your versioning-control, as you can just re-download them anytime.
Just put your module in the same /src directory, and use the import syntax to import it, instead of require.
import newModule from './newModule';
For example, see how it is done in this sample code.
Please instead
const newModule = require('./newModule.js');
Try this
import newModule from './newModule');
// ^^ Do not use file extension
Also make sure that the file you are calling is in the same directory
I have a React application created using the create-react-app module. I have recently been asked by a client to integrate with oidc. For this purpose I'm using redux-oidc, as I already have redux working in my app as well.
We managed to integrate my application into their Identity server and I'm able to sign in and get the user token stored in redux. The problem is that I'm struggling to setup silent renew in my create-react-app application as I have to add an additional entry point. Is there a way to add an additional entry point to silent_renew/index.js without ejecting create-react-app?
Currently I've create a folder called silent_renew containing an index.js file. This folder also contains a silent_renew.html file with not much in it (See: example app similar to my folder structure).
Since the landing page for silent_renew is a just a simple html page, you could bypass webpack. Just put the following file in the public folder. Also, include a copy of the oidc-client.min.js library in the same folder.
public/silent_renew.html:
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<script src="oidc-client.min.js"></script>
<script>
new Oidc.UserManager().signinSilentCallback().then()
</script>
</body>
</html>
This works at my site in the develepment config. For the production config I have the following in mind (I did not test it yet but I'm pretty confident this is the way forward...).
public/index.js
const express = require('express')
const path = require('path')
const app = express()
app.use(express.static('.'))
app.use((req, res, next) => {
if (path.extname(req.path).length > 0) {
next()
} else if (path.dirname(req.path).indexOf('silent_renew') > -1) {
req.url = '/silent_renew.html'
next()
}
else if (path.dirname(req.path).indexOf('callback') > -1) {
req.url = '/callback.html'
next()
} else {
req.url = '/index.html'
next()
}
})
app.listen(3000)
As soon as create-react-app supports multiple entry points (I hope this happens soon for enterprise login scenario's) this code becomes obsolete.
You can also take the approach of loading the main bundle in the iframe and capturing the path as mentioned here.
Then you don't need to deal with exposing a path to load the oidc client lib (oidc-client.min.js or redux-oidc.js) or dumping it's content somewhere.
index.js/ts
import * as React from 'react';
import { render } from 'react-dom';
import { processSilentRenew } from 'redux-oidc';
import App from './App';
if (window.location.pathname === '/silent-renew') {
processSilentRenew();
} else {
render(<App />, document.getElementById('root'));
}
Please note that /silent-renew request performance can be potentially negatively impacted by large files that loaded along with the application. Some thoughts on it in the comment.
I got it to work by simply adding a route instead of using a separat endpoint. My setup is a create-react-app with redux, redux-oidc & react-router.
I configured the UserManager to use
{
silent_redirect_uri: `${window.location.protocol}//${window.location.hostname}${window.location.port ? `:${window.location.port}` : ""}/silent_renew`
}
I added this route in my react-router:
<Route exact={true} path={"/silent_renew"} component={SilentRenewComponent} />
The SilentRenewComponnent is a simple function component which calls the redux-oidc function to process the redirect.
import React from "react";
import { processSilentRenew } from "redux-oidc";
export const SilentRenewComponent = () => {
processSilentRenew();
return(
<div>SilentRenewComponent</div>
);
};
As previously said, changing the webpack configuration of create-react-app would defies what the purpose of this project is, providing a way to do React with zero-configuration.
I'm afraid the solution would be to eject your app, which is irreversible.
After doing so, create the silent_renew directory at the root of your project with the index.js and index.html file, create a store for redux as seen here (you probably don't need a lot of this stuff, like sagas, the router and logger middleware, just take the loadUser logic and store creation), import the store in the src/index.js file and create a redux Provider, like this.
Then, you can modify config/webpack.config.dev.js and follow what we can see at the redux-oihc-example webpack conf. Add HtmlWebpackPlugin and CommonsChunkPlugin for silentRenew, and the additional entry point.
What's a bit upsetting about CRA is that their webpack configuration for dev and prod are totally separated and do not extend a shared one. You'll have to do this operation in both prod and dev configs, or extend one other conf file to prevent redundancy, like this for example.
I would also advice you to use another simple scaffold, CRA is good when you don't have anything special to do unlike what you want (and probably more in the future). Ejecting will create a lot of files and code that you don't even need in your own codebase. A friend and I made a minimalist one, but I'm sure there is plenty of better alternatives.
You cannot add a custom webpack loader if you haven't ejected:
We don't intend to provide Webpack specific overrides because it will be very fragile. People will start depending on specific loaders and plugins and we won't be able to improve the overall experience.
source: https://github.com/facebookincubator/create-react-app/issues/99#issuecomment-234657710
If you want to add a new specific entry file you first need to yarn eject then edit config/webpack.config.dev.js:34 and config/webpack.config.prod.js:55.
The same is valid for adding new webpack loaders.
I'm trying to add a few simple routes to my Meteor app, it's my first time playing with FlowRouter. I installed with:
meteor add kadira:flow-router
meteor add kadira:blaze-layout
Then, I created a lib/routes.js file, containing this:
import '../imports/ui/body.js';
FlowRouter.route('/', {
name: 'home',
action: function(params) {
console.log("home");
BlazeLayout.render('body');
}
});
The imports/ui/body.js file loads a few other templates, like so:
import './moment.js';
And moment.js imports ./moment.html, like so:
import './moment.html';
But I get this error when visiting /:
Error: Cannot find module './moment.html'
The key thing to understand is that if I bypass FlowRouter altogether, by just putting import '../imports/ui/body.js into my client/main.js file, everything works fine.
Any ideas? Help is appreciated, thank you!
I just ran into this same problem, but I was thinking because routes.js was in lib it would get loaded first, moving it into clients means it get loaded with the other files so it can now be found. Not sure if this is correct but as you know, it works.
Just came back to meteor, and trying to figure out how to structure a project, I'm getting stuck with how to handle relative paths, my project structure is like this:
-root
--client
----components
-----layout
...... MainLayout.jsx
--server
--lib
.. routes.jsx
If I try to import in my routes.jsx file like this './../client/components/layout/MainLayout.jsx' I get the error 'Cannot find module './../client/components/layout/MainLayout.jsx...
However if I move MainLayout.jsx to the root folder, i can reach the component file like this without problems './../MainLayout.jsx'.
Maybe I'm missing something here? as I said just returned to JS programming.
When the router.js file in the root. You have use instead of
'./../client/components/layout/MainLayout.jsx'
this:
'../client/components/layout/MainLayout.jsx'
or just:
'../client/components/layout/MainLayout'