Build multiple pages using quasar - node.js

I need to build a multi-page website using Quasar to host on Netlify but Quasar is only building the index.html.
I have tried to use Quasar build and Quasar build --mode ssr. Both have failed in building more than the index.html.
Is there a way to accomplish multiple pages?

The concept of SPA is excellent, however it still does not suite everybody's needs, an example is having a backend app (for example django) and not willing to spend a lot of time to develop a rest api or graphql for it to serve the SPA contents.
Quasar cli at the end of the day in its core is just a webpack config that you can customize to achieve whatever you want that webpack can do, including multi page apps, here is a quick way to achieve this:
apps/myapp/pages.js
module.exports = {
main_page: {
entry: `${__dirname}/pages/main/main_page.js`
}
blog_entry_page: {
entry: `${__dirname}/pages/blog/blog_entry_page.js`
}
...
}
quasar.conf.js:
const HtmlWebpackPlugin = require('#quasar/app/node_modules/html-webpack-plugin')
const pages = require('./apps/myapp/pages')
module.exports = function (ctx) {
return {
...
build: {
...
extendWebpack (cfg) {
...
Object.keys(pages).forEach(function (page) {
// Add page webpack entry
cfg.entry[page] = pages[page].entry
// Output an html file for the page
cfg.plugins.push(
new HtmlWebpackPlugin({
template: 'mytemplate.html',
filename: `html/${page}.html`,
chunks: [page]
})
)
})
...
}
}
}
The above is a simplified example just to demonstrate the concept, for a complete and functional example see: https://gitlab.com/noor-projects/noor/tree/master/quasar-cli
(check this commit to know about what was added to enable MPA support)

Quasar framework builds single page apps by default, that is, your index.html page is the only page, and instead of going to different static pages, it uses the Vue router to load dynamic pages and components to your hearts content :)
Check out this Quasar document that explains with SPA (Single Page Apps) are and how they work (and why it's the best thing to do):
https://quasar.dev/quasar-cli/developing-spa/introduction#Introduction
Check out this Quasar document to learn how to add more routes (pages) to your app:
https://quasar.dev/layout/routing-with-layouts-and-pages#Defining-Routes
Quasar Framework is definitely the way to go, so keep at it. I'd be happy to walk you through anything. I've used the framework for nearly a dozen clients and many have gone off to recently be valued in the millions by investors. Quasar is the best mix for any platform you can think of, from a simple site to a complex web and mobile app that will be used by millions of people; it gets the job done with flying colors.
I've been writing apps and web sites for 20 years, nothing as easy to work with as Quasar has ever come along before it. You will love it!

Related

Conditionally use next.js app or create react app with the same website domain according to users login

I have a website which I've built with CRA, node.js and I want to use ISR for most of the pages.
The problem is that about 20% of the users are registered users, which get their own content, and different header, which means I can only use SSR, and not ISR.
My thought is to use something like:
In my node.js server I would check if the user is logged
If he is not logged, I would send a get request to the next.js server, get the static html file and serve it.
If the user is logged I would just send him my CRA app.
Another option that I thought about is to use a proxy server with filter on the request which check if the session ID or cookie ID is set
Is it possible? Which option is better?
Shall I be able to use CDN to serve those static files?
Is there any better idea to solve this problem?
Just keep everything in the Nextjs application.
If you need static generated pages use getStaticProps and getStaticPaths or nothing (to have the same result as a CRA app) in that page.
If you need some server related logic use getServerSideProps in that page.
UPDATE
After run next build
The page test is a simple component
const Test = () => <div>test</div>;
export default Test;
In the other pages (/gpp, /gpp/[id]) getServerSideProps is defined
.....
const GppPage: NextPage = () => (
<>
<Head>
<title>GPP</title>
</Head>
<Box>
....
</Box>
</>
);
export async function getServerSideProps(context) {
return {
props: {
session: "mysession"
}
};
}
export default GppPage;
In the image the Test page is clearly a static page (look at symbols)
If you define in _app.tsx some getInitialProps or getServerSideProps in that case you will inherit the SSR behaviour
Instead of using next.js I ended up creating my own ISR for my website. This way I could use SSR for registered users and ISR for unregistered users. While using SSR in CRA app is not recommended by the create react app team, I found out that it is pretty simple with the help of this article for SSR, this article for SSR with react router. I used react 18 and react router 5.
While this solution worked for me, it is not guaranteed that it will work later so I won't recommend it until the create react app team will recommend it.
The pros of the solution:
More freedom with the code. For example, I could serve different pages for mobile and desktop (and still serve static pages).
Reduced costs compared to next.js
The cons of the solution
Unstable because the create react team doesn't recommend it
Missing out of some of the next.js features like images optimization
The html pages are not served from CDN (I used EBS)

Use javaScript file in angular 5 project

I am building a web application using Angular 5 and nodejs with express. As both the frontend and the backend are going to run in the same server I want to use my backend javascript functions in the frontend. The solutions that I have found didn't worked for me.
appController.js
var createApp = function (appData) {
console.log("App created")
}
exports.createApp = createApp;
This is the backend file that I want to use in the front.
Javascript files don't need to export things when used in the front-end. Most of the time, they use global variables. You should go with that.
To add it to your project, add it anywhere you want, and in your Typescript, you can simply use
declare var myGlobalVariable: any;
// ...
myGlobalVariable.createApp();
I did a similar thing. I have a frontend with Angular 5 and a backend serving an API via Express:
If you want to run your Angular frontend and your NodeJS backend on the same server you'll have to build your Angular project and serve the built files with your Express server.
I think I found a tutorial on that – but I can't find it right now...
Instead maybe have a look at my code for the backend:
https://github.com/saitho/ngHashi/blob/next/backend/src/index.ts
In production mode it will serve the files in the folder /backend/dist_frontend by default (apart from the backend routes (/api)). I use a build process (GitLab CI) to move the files I need to the respective place...
I finally find a solution. It would be necessary to modify the tsconfig.json:
tsconfig.json
{
compilerOptions: {
.....
allowJS: true,
......
}
}

Webpack 2 with Multipage Express web app

we are migrating our web app from ASP.NET and jQuery to Node.js with Express and React. We are using the typical multipage application (MVC), and we are confortable with this architecture and we need it for some special cases (basically SEO, and we know that with react now you can improve the SEO).
We want to maintain our routes without using React Router, we are going to use Express MVC Router but we want to use WebPack 2 with React.
The first step was migrating the BackEnd (we are almost done), and the second part is migrate the frontend from jQuery to React (yes, React like UI Library, we don't want Redux and we can work fine with just Component State because our pages are not very complex, and we want to reuse components).
Like we are using MVC Express routes we need to use Code Spliting from WebPack 2 to generate multiple entries for each page (js files), and we want to integrate typical stuff for make more productive: live reload, production build js, etc.
We have one example working of WebPack for creating the Entry libraries, and vendors and common, but we don't know how to integrate with our server.js (Express app), and have a good flow...
Example WebPack config:
var path = require('path')
var webpack = require('webpack')
var config = {
entry: {
vendors: ['react', 'lodash'],
common: ['lodash'],
home: path.resolve(__dirname, './src/main'),
page1: path.resolve(__dirname, './src/page1'),
page2: path.resolve(__dirname, './src/page2'),
},
output: {
path: path.join(__dirname, 'js'),
filename: '[name].bundle.js',
chunkFilename: '[id].chunk.js'
},
devtool: 'source-map',
devServer: {
inline: true,
contentBase: './src',
port: 3000
},
module: {
loaders: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel'
}
]
},
plugins: [
new webpack.optimize.OccurenceOrderPlugin(true),
new webpack.optimize.DedupePlugin(),
new webpack.optimize.UglifyJsPlugin({
output: {
comments: false
},
compress: {
warnings: false,
screw_ie8: true
}
}),
new webpack.optimize.CommonsChunkPlugin({
names: ["common", "vendors"],
minChunks: Infinity
})
]
}
if (process.env.NODE_ENV === 'production') {
config.output.path = path.join(__dirname, 'dist/')
/*
Note: by default, React will be in development mode
see https://facebook.github.io/react/downloads.html
*/
config.plugins.push(new webpack.DefinePlugin({
'process.env': {
'NODE_ENV': '"production"'
}
}))
}
module.exports = config
My question is... Can we get this working with Express and live reload? Like we do with create-react-app? Any link or tutorial to explain how to work with Multipage applications and WebPack together?
Thanks!
I'm the author of quickstart-express-react. We're apparently facing similar challenges, so I've updated the repo to better illustrate your usage scenario.
The basic idea, if you're looking to build an MPA and need both "generic" reloading and react hot reloading during development, you can use browsersync programatically as a proxy, and - very importantly run webpack-dev-middleware & webpack-hot-middleware inside browsersync and not your website/application.
It took me a week of trial & error to build that scenario, hence the decision to open-source it on GitHub.
Other things to consider:
Be careful to use the latest webpack & loaders/plugins, i.e. webpack#^2.2.1 and react-hot-loader#^3.0.0-beta.6 at the moment, keep an eye on their repos and update if you're facing problems;
If you're coming from ASP.NET, you'll probably be interested in Vash template engine.
IMO, at the moment webpack and its entire loaders/plugins ecosystem is cutting-edge and evolving fast, and as you've seen, building a realistic workflow configuration is close to madness. But the benefits of having full reloading during development are tremendous.
Hopefully the madness will change, now that webpack#2 is finally out of beta.
Hope this helps, and thank you starring the repo :-)
A quick update on a potentially different approach - although I published the quickstart-express-react two months ago, I like to keep an open mind and I'm still researching other alternatives for a better developer experience. And I might have found one.
Since you wrote you've almost finished porting the backend, this is probably not what you're looking for right now, but for future projects make sure to check and keep an eye on next.js, especially if you're interested in building isomorphic/universal react apps. I think the guys at ZEIT are doing an extraordinary job of simplifying the entire development workflow, especially considering the current state of the webpack ecosystem.
I'm currently looking for a sane way of building universal React websites/apps with react-toolbox components, and next.js does look promising, especially for a single/independent developer or a small team not wanting to deal with the full complexity of setting up a webpack scenario from scratch.
They're also offering a fantastic cloud deployment solution, but it's worth mentioning that next.js is fully open-source (MIT license) and it can be used in dev/prod on any infrastructure.
Disclaimer: I am in now way affiliated with ZEIT. I was just thrilled when I came across next.js a few days ago... :-)

Webpack for back-end?

I was just wondering, I started using Webpack for a new project and so far it's working fine. I almost would say I like it better than Grunt, which I used before. But now I'm quite confused how and or I should use it with my Express back-end?
See, I'm creating one app with a front-end (ReactJS) and a back-end (ExpressJS). The app will be published on Heroku. Now it seems like I should use Webpack with ExpressJS as well to get the app up and running with one single command (front-end and back-end).
But the guy who wrote this blogpost http://jlongster.com/Backend-Apps-with-Webpack--Part-I seems to use Webpack for bundling all back-end js files together, which is in my opinion really not necessary. Why should I bundle my back-end files? I think I just want to run the back-end, watch my back-end files for changes and use the rest of Webpack's power just for the front-end.
How do you guys bundle the front-end but at the same time run the back-end nodejs part? Or is there any good reason to bundle back-end files with Webpack?
Why to use webpack on node backend
If we are talking about react and node app you can build isomorphic react app. And if you are using import ES6 Modules in react app on client side it's ok - they are bundled by webpack on the client side.
But the problem is on server when you are using the same react modules since node doesn't support ES6 Modules. You can use require('babel/register'); in node server side but it transipile code in runtime - it's not effective. The most common way to solve this problem is pack backend by webpack (you don't need all code to be transpile by webpack - only problematic, like react stuff in this example).
The same goes with JSX.
Bundling frontend and backend at the same time
Your webpack config can have to configs in array: one for frontend and second for backend:
webpack.config.js
const common = {
module: {
loaders: [ /* common loaders */ ]
},
plugins: [ /* common plugins */ ],
resolve: {
extensions: ['', '.js', '.jsx'] // common extensions
}
// other plugins, postcss config etc. common for frontend and backend
};
const frontend = {
entry: [
'frontend.js'
],
output: {
filename: 'frontend-output.js'
}
// other loaders, plugins etc. specific for frontend
};
const backend = {
entry: [
'backend.js'
],
output: {
filename: 'backend-output.js'
},
target: 'node',
externals: // specify for example node_modules to be not bundled
// other loaders, plugins etc. specific for backend
};
module.exports = [
Object.assign({} , common, frontend),
Object.assign({} , common, backend)
];
If you start this config with webpack --watch it will in parallel build your two files. When you edit frontend specific code only frontend-output.js will be generated, the same is for backend-output.js. The best part is when you edit isomorphic react part - webpack will build both files at once.
You can find in this tutorial explanation when to use webpack for node (in chapter 4).
This is my second update to this answer, which is beyond outdated by now.
If you need full a stack web framework in 2023, I'd recommend nextjs (which is built on top of react). No need to go around setting up anything, it just works out of the box, and is full stack.
On the other hand, if you need to compile your nodejs project written in typescript (which you should use as much as you can for js projects), I would use tsup-node.
You don't need to be a genius to imagine that in 3-5 years I'll come back to this and say this is really outdated, welcome to javascript.
This answer is outdated by now since node now has better support for ES modules
There's only a couple of aspects I can redeem the need to use webpack for backend code.
ES modules (import)
import has only experimental support in node (at least since node 8 up to 15). But you don't need to use webpack for them work in node.
Just use esm which is very lightweight and has no build step.
Linting
Just use eslint, no need to use webpack.
Hot reloading/restart
You can use nodemon for this. It's not hot reloading but I think it's way easier to deal with.
I wished I could refer to a more lightweight project than nodemon, but it does do the trick.
The blog post you shared (which is dated by now) uses webpack for having hot reloading. I think that's an overkill, opens a can of worms because now you have to deal with webpack config issues and hot reloading can also lead to unexpected behaviour.
The benefits we get from using tools like webpack on the frontend don't really translate to backend.
The other reasons why we bundle files in frontend is so browsers can download them in an optimal way, in optimal chunks, with cache busting, minified. There's no need for any of these in the backend.
Old (and terrible, but maybe useful) answer
You can use webpack-node-externals, from the readme:
npm install webpack-node-externals --save-dev
In your webpack.config.js:
var nodeExternals = require('webpack-node-externals');
module.exports = {
...
target: 'node', // in order to ignore built-in modules like path, fs, etc.
externals: [nodeExternals()], // in order to ignore all modules in node_modules folder
...
};
to use Webpack for bundling all back-end js files together, which is in my opinion really not necessary.
I think you are absolutely right. It's not necessary at all. I've been researching on this topic for a while. I've asked lots of questions on this topic, and up to this day, I haven't found yet a single "real" reason for one to use webpack on a Node.js back-end.
I'm not saying you can't or shouldn't set up a webpack-dev-server to develop your back-end code locally. But you definitely don't need to bundle your backend code on your build process.
webpack bundles are meant for the browser. Take a look at its official docs: Why webpack?. Historically, browsers never had a built-in module system, that's the reason why you need webpack. It basically implements a module system on the browser. On the other hand, Node.js has a built-it module system out of the box.
And I do re-use all of my front-end code for SSR on my server. The very same front-end files are run on my server as-is without any bundling (they are just transpiled, but the folder structured and number of files is the same). Of course I bundle it to run on the browser, but that's all.
To run on your Node.js server, simply transpile it with babel, without webpack.
Just use ["#babel/preset-env", { targets: { node: "12" }}], on your babel config. Choose the Node version of your backend environment.
backend
dist_app // BABEL TRANSPILED CODE FROM frontend/src
dist_service // BABEL TRANSPILED CODE FROM backend/src
src
index.tsx
frontend
src
App.tsx
public // WEBPACK BUNDLED CODE FROM frontend/src
You can perfectly render your frontend code on the server, by doing:
backend/src/index.tsx
import { renderToString } from "react-dom/server";
import App from "../dist_app/App";
const html = renderToString(<App/>);
This would be considered isomorphic, I guess.
If you use path aliases on your code, you should use babel-plugin-module-resolver.

Can I use webpack on the client side without nodejs server?

I am trying to build a web app where I want to store all html, js and css files on amazon s3, and communicate with a restful server through api.
I am trying to achieve lazy loading and maybe routing with react router. It seems that webpack has this feature code splitting that would work similarly as lazy loading.
However, all of the tutorial and examples I found involves webpack-dev-server, which is a small node express server. Is there anyway I could generate bundle at build time and upload everything to amazon s3 and achieve something similar to Angular's ocLazyLoading?
It's definitely possible to create a static bundle js file, which you can use in your production code that does not include webpack-dev-server.
See this example as a reference (note: I am the owner of this repo). webpack.prod.config.js does create a production ready bundle file using webpack via node.js which itself does not require node.js anymore. Because of that you can simply serve it as a simple static file (which is done in the live example).
The key difference is how the entry points are written in the dev- and production environments. For development webpack-dev-server is being used
module.exports = {
entry: [
'webpack-dev-server/client?http://localhost:3000',
'webpack/hot/only-dev-server',
'./src/index'
],
// ...
}
In the production environment you skip the webpack-dev-server and the hot reloading part
module.exports = {
entry: [
'./src/index'
],
// ...
}
If you want to split your code into more than one bundle, you might want to have a look at how to define multiple entry points and link the files accordingly.

Resources