I have simple React application and I want to add SSR in Express.js.
I made a bit of a gaff in the beginning and in my repository I just have a frontend folder and in it the whole React app with typescript, babel and webpack configured.
I haven't played with SSR yet, so I'm curious, if I want to make such a server and have its file in the folder next to the frontend folder, would I have to install and set all the dependencies I made inside the`frontend folder, and only then create the server.js file ?
Then in the middle of "frontend/src" I would have 2 files - index.tsx (with React.render() method), because I would like to be able to run the application also without the server. And 2nd file would be indexServer.tsx with React.hydrate() method, which would go to server.js file (i.e. would be for generating application by server). Is this concept right ?
Link to my github repo with this react app: https://github.com/poldeeek/spider-game
If I want to make such a server and have its file in the folder next to the frontend folder, would I have to install and set all the dependencies I made inside the`frontend folder, and only then create the server.js file ?
You'll probably need to re-install all the dependencies if you choose to setup two separate folders like that. I would recommend putting server.js in frontend/server, which can then use the same node_modules as your frontend/src/index.js is using.
Then in the middle of "frontend/src" I would have 2 files - index.tsx (with React.render() method), because I would like to be able to run the application also without the server. And 2nd file would be indexServer.tsx with React.hydrate() method, which would go to server.js file (i.e. would be for generating application by server). Is this concept right ?
There is no right or wrong answer here. If this setup suits your needs, then go with it. The only challenge with this setup is that you have to configure babel and webpack to point to two different files: index.tsx (in case you don't want the server) and indexServer.tsx (in case you want to include the server).
Related
I have a React application created using create-react-app. I also have an external application that is using this application by including the bundled JS and CSS files (the ones create using the build script).
Right now, I'm using the React template created by the dotnet new command, and I have configured the server to serve static files located in the build folder.
For this reason, I have created a couple of additional NPM scripts that rename the bundle files (remove the hash from the name), so that I don't need to update my external application's links with every build.
Right now, whenever I change something in the code, the whole build process has to be processed to create the two files.
I have created a "watch" task to run my build scripts whenever I have a change, but I was wondering if there is a way to speed up the process and somehow configure the React application to be served from memory or something just like when we "normally" run the application.
So, maybe a couple of questions:
How to achieve this in a "normal" React app created by create-react-app?
how to achieve this in the context of the dotnet template?
you can use nodemon in the build folder of the create react app.
as the documentation says
By default nodemon monitors the current working directory. If you want to take control of that option, use the --watch option to add specific paths:
so you can use something like this:
nodemon --watch app --watch libs app/server.js
for details try other approaches given here
This could be due to your filesystem, file extensions or the Create-React-App default webpack/project configuration. You don't necessarily have to change all of this because hot-reloading is supposed to work out of the box, and more so if the project has just started.
For example, I once had an issue with a Typescript installation(^17.0.1) where some files with extension .ts will not trigger hot reloading. I had to change to .tsx and add a React import. The same could happen with .js and .jsx files.
In case of problems with your filesystem (Unix, Mac) you can try the React config (FAST_REFRESH=false) here... or changing folder names, but I haven't bumped much into this.
I am trying to push a project I created using the Yeoman's angular generator template to a server.
This is my project -
This is in my app folder -
This is the node-modules folder. For some reason, Yeoman has installed several node-modules. I am not using all of these.
The list goes on. This is just a small snippet of what's in the node-modules folder.
In order to push to the server, I am using grunt build. This generates a dist folder with the following content -
.
However when I navigate to my views, (e.g. reset-password), I get an error that this file is not available.
I am guessing this is because the dist folder doesn't have the views folder that the app folder does.
My final requirement is I want to push this project to the server, so that it is accessible to anyone. I don't want to push all the node-modules because I am not using them.
UPDATE -
This is the content in dist/scripts/ -
In the script.2a4ac124.js file, all my views are referenced but when I try to navigate to - file:///Users/proj/Documents/sso/dist/reset-password I get a file not found error, but when I navigate to file:///Users/proj/Documents/sso/dist/index.html#/ I see the index page.
installing node modules is normal - it installs development dependencies, which will be used in the grunt tasks that Yeoman creates. The reason there are so many is because the dev dependencies have their own dependencies that need to be resolved.
reset-password navigation error is most likely some build error, though it is difficult to tell just from the description. Yeoman converts the view files into angularJS templateCache and puts them into the concat/uglified js file (usually the app-.js file). First see if they are there. If they aren't, the view files aren't getting build. If they are there, it could be that the templates are incorrectly cached, or it could also be something else totally.
To deploy your application, simply copy the contents of dist folder to wherever you are deploying. You don't need the node_modules, since they are only used for performing dev. tasks.
Also,
Your screenshots show a SignUpCtrl.js file at the app root. Yeoman scaffoldings, whichever one you are using, usually aren't designed to have script files at the app root. Try putting it back inside the scripts file first.
I have a folder structure for a Node.js /w Angular.js project with some files like so (from project root):
frontend
frontend-file1.ts
frontend-file2.ts
backend
backend-file1.ts
backend-file2.ts
I use a TypeScript compiler along with many other gulp plugins to compile this into a build folder like so (notice how frontend files get placed into public):
build
backend-file1.js
backend-file2.js
public
frontend-file1.js
frontend-file2.js
In the source folders, I use ES6/TypeScript import statements to import files.
Example: backend-file1.ts
import './backend-file2';
Situation
I've written some custom utility functions that should be used by both backend and frontend. I don't want to repeat the same functions in both folders, since this is prone to errors and is double work.
I've considered creating a shared folder at the project root amongs the frontend and backend folders, but I can't import files in the browser that go up further than the index.html file, which is in the frontend folder.
Question
How would I be able to write a TypeScript file once and be able to import this file in both frontend and backend folders?
I would just structure the code like this:
- src/
- server/
- client/
- shared/
You can place all your shared libraries into shared directory then import/require them from your server or client source files:
import '../shared/library'
To extend the already given answer for outFile case I will show my way of dealing with class sharing in case when you cant or do not want to use webpack/browserify/outFile options.
The structure looks similar
-client
index.html
app.ts
-server
service.ts
-common
helper.ts
-dist
-client
-index.html
-lib
-client
app.js
-common
helper.js
-server
service.js
-common
helper.js
The idea is how you build the dist folder with the results of your build. I do this with gulp tasks and by having the structure above it allows me to reuse components both server and client side from the common library.
Note. To work at client side do not forget to setup base url for systemjs in index.html:
System.config({
baseURL: './lib'
});
System.defaultJSExtensions = true;
Hope this helps.
I wanted to share what I've done so that others have the same option. I felt the other options which are cleaner required a lot more work, and since this is a personal project I set it up in a simpler but more crude way.
Basically I wanted to use symlinks so that I could edit it from either location without issue and without making too many changes to the current project structure. I'm also lucky that I don't need to support Windows for this.
I already had a single repo with a React app in the fe folder and the backend server in be, both using TypeScript. Here's my resulting folder setup:
be/
src/
shared -> ../../fe/src/shared
fe/
src/
shared/
I'll note that React does not support symlinks (IIRC it's because webpack does not support symlinks) and so the "real" folder should be in the frontend.
I also wanted this to work without manual setup, and so I made an extra script in package.json which makes sure the symlink is already set up. It also creates a broken symlink if the symlink is already there, but again, this is for a personal project and I'm okay with it. (Happy to update it if someone has a better understanding of ln than I do.) In the backend's package.json:
"prebuild": "ln -f -s ../../fe/src/shared src/shared",
"build": "tsc",
I know how to get the current directory from a Meteor package, but how do I get the path of a specific file in the project?
node's __dirname and __filename don't work in Meteor.
It is complicated.
meteor run copies your project files to a tree of directories inside <project-dir>/.meteor/local/build, reorganizes them in non-obvious ways (e.g.. the private subdirectory in the original tree becomes the assets subdirectory) and mixes it in with various npm modules to create a bundle that can be executed as a nodejs project. Indeed, to avoid duplications, there is a .gitignore file automatically set up in the .meteor directory that tells git, if you use it for version control, not to copy the .meteor/local directory.
The original project directory gets watched in case you change a file. The change then gets copied into the current project build directory and the project rebuilt.
If you deploy to a remote system, the build gets copied to a server and then run.
process is usually a defined global server-side object, and works according to the node.js API, because the meteor server code is ultimately running in node.js.
So you can run console.log(process.cwd()); in your server-side to obtain the current working directory for the server process, usually something like:
~/<meteor project directory>/.meteor/local/build/programs/server
This suggests that when meteor run is done locally, original project files are in ../../../../../, but don't use that as it may change in the future.
Instead, for the directory containing the original project files, you could use:
baseDir = process.cwd().replace(/\/\.meteor.*$/, '');
This will get the working directory, and truncate everything beginning with /.meteor
This won't work for a server deploy, though, because the original project tree is not needed on the server, only the build. Files that aren't intended to be client or server code could possibly be stuck in the private subdir, which as I mentioned becomes the assets subdir in the build. Ways to currently find files in the build is either manual inspection .meteor/local in a local run, or use of a JS library that calls or imitates gnu find.
Since you mentioned packages, I note that in the build, server-side package code finally ends up in:
~/<project-dir>/.meteor/local/build/programs/server/packages
and client side in:
~/<project-dir>/.meteor/local/build/programs/web.browser/packages
Using the ember-starter-kit all I had to do was throw the contents of it in the /my_laravel_app/public folder and everything was fine.
Now I am trying to create a project with laravel and ember-cli
I'm a little confused as to how I need to structure my application? In which laravel folder should I be running the ember new my-app command? Furthermore, how can I use apache for testing my ember-cli application instead of using ember server command since I need to test it with my laravel generated apis.
Any help is much appreciated!
Here is one way to do it
Go into your root laravel folder and run the ember new my_app_name
Then go into your my_app_name folder and create a new file build_custom.sh add the following lines to the file
ember build
cp dist/index.html ../app/views/ember.php
cp -r dist/assets ../public/assets
Explanation: the first line builds your ember-cli app and generates all the necessary files in the dist/ folder. The second line copies the index.html file generated to app/views/ folder and renames it ember.php so laravel can recognize it. The last line just copies all the assets into your laravel public folder
You can add the following in your app/routes.php file in laravel to serve your ember app. Make sure it's all the way at the bottom so your other api routes take preference
Route::get('{ember?}', function() {
return View::make('ember');
})->where('ember', '.*');
That should be it, everything should work as intended. Good luck.
Here is another way to do it:
You can create two separate folders: backend (laravel app) and frontend (ember app)
. Let's say, your laravel app is running under 192.168.10.10, you can then proxy your ember app ajax requests using ember-cli command: ember serve --proxy http://192.168.10.10. Using this proxy option, all commands will be passed to ip address, specified with --proxy option - in this case ip address, where laravel app is running (where api is listening).
If you getting UnrecognizedURLError: /ember try to remove welcome route on laravel...