How to use Express with Parceljs middleware in Production - express

I am using Parcel middleware with express as explained here: https://parceljs.org/api.html#middleware
When I run this in production I don't want hot-module replacement to be turned on.
How can I set this up so that it works in dev with HMR and in prod without HMR? Essentially I don't know how to use the build mode with this middleware: https://parceljs.org/production.html#%E2%9C%A8-production
Should I only use parcel-bundler if this is in dev and use static config if this is in prod?
Adding sample code for reference:
const Bundler = require('parcel-bundler');
const app = require('express')();
const file = 'index.html'; // Pass an absolute path to the entrypoint here
const options = {}; // See options section of api docs, for the possibilities
// Initialize a new bundler using a file and options
const bundler = new Bundler(file, options);
// Let express use the bundler middleware, this will let Parcel handle every request over your express server
app.use(bundler.middleware());
// Listen on port 8080
app.listen(8080);

You can set options for the bundler as so
const bundlerOptions = { production: process.env.NODE_ENV === 'production' };
const bundler = new Bundler( filePath, bundlerOptions );
This will disable HMR as described in the parcel documentation https://parceljs.org/api.html.

Related

How to use node server with Vue Vite bundler

Does someone know how to use Nodejs server instead of Vite own frontend dev server on the port 3000. I tried all command combinations like those below but with no success
vite
vite preview
vite preview --port:5000
Thanks
UPDATE Feb 8-th 2022
I have found a way. We have to add flag --watch to the vite build command, like: vite build --watch That way Vite will bundle only changes to the front-end and store it in the /dist folder but it will watch outside server like Nodejs. That way we can develop both front and back end file simultaneously and see the result immediately. We have to launch server file separately and serve index.html from there. If we use Nodejs and Express on the server side we also have to point default directory to be /dist because Vite will put bundled files there, like app.use(express.static(__dirname + '/dist'));. node will automatically serve index.html and other bundled files from this folder.
Basically you will set the middlewareMode to ssr on the server options:
const fs = require('fs')
const path = require('path')
const express = require('express')
const { createServer: createViteServer } = require('vite')
async function createServer() {
const app = express()
// Create Vite server in middleware mode. This disables Vite's own HTML
// serving logic and let the parent server take control.
//
// If you want to use Vite's own HTML serving logic (using Vite as
// a development middleware), using 'html' instead.
const vite = await createViteServer({
server: { middlewareMode: 'ssr' }
})
// use vite's connect instance as middleware
app.use(vite.middlewares)
app.use('*', async (req, res) => {
// serve index.html - we will tackle this next
})
app.listen(3000)
}
createServer()
This is explained in the doc: https://vitejs.dev/guide/ssr.html#setting-up-the-dev-server
Update for Vite 2.x
For Vite 2.x set server.middlewareMode to true and appType to custom:
// ...
const vite = await createViteServer({
server: { middlewareMode: true },
appType: 'custom'
})

How do I force or redirect my next.js website to use https

I thought this would be a simple task, but I struggle to find a way to force my webpage to use https.
The next.js webapp lives on the heroku servers and I've set up the SSL. Both https and http version works, but how to I force or redirect the website to use the https version.
I've seen some solution using express, but nothing in my webapp are using express, is it required?
Thanks.
As of Nextjs v12, you can use middleware instead of a setting up a custom server.
Middleware is a better solution for the following reasons:
a custom server often requires additional dependencies (like express)
you give up some of the box features like automatic static optimization
Middleware can be scope to specific paths using the built in routing paradigm
Create a /pages/_middleware.ts (or .js) file with something similar to this:
import { NextFetchEvent, NextRequest, NextResponse } from 'next/server'
type Environment = "production" | "development" | "other";
export function middleware(req: NextRequest, ev: NextFetchEvent) {
const currentEnv = process.env.NODE_ENV as Environment;
if (currentEnv === 'production' &&
req.headers.get("x-forwarded-proto") !== "https") {
return NextResponse.redirect(
`https://${req.headers.get('host')}${req.nextUrl.pathname}`,
301
);
}
return NextResponse.next();
}
I also created an npm package for this.
import sslRedirect from 'next-ssl-redirect-middleware';
export default sslRedirect({});
There is a solution with an NPM library called heroku-ssl-redirect.
First off, install the library using npm i heroku-ssl-redirect.
Then, create a new server.js file with the following script.
const next = require('next');
const express = require('express');
const sslRedirect = require('heroku-ssl-redirect').default; // to make it work with 'require' keyword.
const PORT = process.env.PORT || 3000;
const dev = process.env.NODE_ENV !== 'production';
const app = next({ dev });
const handle = app.getRequestHandler();
app.prepare().then(() => {
const server = express();
// Express's middleware to automatically redirect to 'https'.
server.use(sslRedirect());
server.all('*', (req, res) => {
return handle(req, res);
});
server.listen(port, err => {
if (err) throw err;
console.log(`Server starts on ${PORT}.`);
});
});
Then, change the start script to be like this:
"scripts": {
"dev": "next",
"build": "next build",
"start": "node server.js"
}
It should work.
Note that you could replace Express with the createServer method from native Node.js's http module. But I do this with Express to simplify the syntax.
Further reading: How to setup a custom server in Next.js.

React Application Reloading (Webpack) when Saving Image to Server

I am writing a React App in Visual Studio 2019 (ASP NET Core 3.1) and having an issue where the App reloads in the browser when I save a new profile picture (to disc).
This is causing issue on the page as its running the UseEffect() before it begins processing the async response with the updated info.
I am able to reproduce this behavior by simply overwriting or deleting the image file from file explorer. And it is important to NOTE that if I attempt to move my images folder outside of SRC folder, I get an error saying this is not allowed.
My initial investigation tells me this has to do with Webpack watching the images folder. But every attempt I have made to prevent it from watching the folder has failed. I have gone over the Webpack documentation many times but nothing seems to change.
I have two config files in my application Webpack.config.js and WebpackDevServer.config.js. It doesn't seem to matter what config I modify it always reloads the App. I have also tried setting the ENV mode to 'development' but again no dice.
Can someone please tell me how to modify the webpack configs to avoid the application from reloading.
If you can provide the above back with the necessary change it would be MUCH appreciated.
src\Images\Users\Profile Pictures - is the path I would like to ignore.
Webpack.config.js
/**
* Copyright (c) 2015-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
// #remove-on-eject-end
'use strict';
const fs = require('fs');
const path = require('path');
const webpack = require('webpack');
const resolve = require('resolve');
const PnpWebpackPlugin = require('pnp-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin');
const InlineChunkHtmlPlugin = require('react-dev-utils/InlineChunkHtmlPlugin');
const TerserPlugin = require('terser-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const safePostCssParser = require('postcss-safe-parser');
const ManifestPlugin = require('webpack-manifest-plugin');
const InterpolateHtmlPlugin = require('react-dev-utils/InterpolateHtmlPlugin');
const WorkboxWebpackPlugin = require('workbox-webpack-plugin');
const WatchMissingNodeModulesPlugin = require('react-dev-utils/WatchMissingNodeModulesPlugin');
const ModuleScopePlugin = require('react-dev-utils/ModuleScopePlugin');
const getCSSModuleLocalIdent = require('react-dev-utils/getCSSModuleLocalIdent');
const paths = require('./paths');
const modules = require('./modules');
const getClientEnvironment = require('./env');
const ModuleNotFoundPlugin = require('react-dev-utils/ModuleNotFoundPlugin');
const ForkTsCheckerWebpackPlugin = require('react-dev-utils/ForkTsCheckerWebpackPlugin');
const typescriptFormatter = require('react-dev-utils/typescriptFormatter');
// #remove-on-eject-begin
const getCacheIdentifier = require('react-dev-utils/getCacheIdentifier');
// #remove-on-eject-end
const postcssNormalize = require('postcss-normalize');
const appPackageJson = require(paths.appPackageJson);
// Source maps are resource heavy and can cause out of memory issue for large source files.
const shouldUseSourceMap = process.env.GENERATE_SOURCEMAP !== 'false';
// Some apps do not need the benefits of saving a web request, so not inlining the chunk
// makes for a smoother build process.
const shouldInlineRuntimeChunk = process.env.INLINE_RUNTIME_CHUNK !== 'false';
const isExtendingEslintConfig = process.env.EXTEND_ESLINT === 'true';
const imageInlineSizeLimit = parseInt(
process.env.IMAGE_INLINE_SIZE_LIMIT || '10000'
);
// Check if TypeScript is setup
const useTypeScript = fs.existsSync(paths.appTsConfig);
// style files regexes
const cssRegex = /\.css$/;
const cssModuleRegex = /\.module\.css$/;
const sassRegex = /\.(scss|sass)$/;
const sassModuleRegex = /\.module\.(scss|sass)$/;
// This is the production and development configuration.
// It is focused on developer experience, fast rebuilds, and a minimal bundle.
module.exports = function (webpackEnv) {
const isEnvDevelopment = webpackEnv === 'development';
const isEnvProduction = webpackEnv === 'production';
// Variable used for enabling profiling in Production
// passed into alias object. Uses a flag if passed into the build command
const isEnvProductionProfile =
isEnvProduction && process.argv.includes('--profile');
// We will provide `paths.publicUrlOrPath` to our app
// as %PUBLIC_URL% in `index.html` and `process.env.PUBLIC_URL` in JavaScript.
// Omit trailing slash as %PUBLIC_URL%/xyz looks better than %PUBLIC_URL%xyz.
// Get environment variables to inject into our app.
const env = getClientEnvironment(paths.publicUrlOrPath.slice(0, -1));
// common function to get style loaders
const getStyleLoaders = (cssOptions, preProcessor) => {
const loaders = [
isEnvDevelopment && require.resolve('style-loader'),
isEnvProduction && {
loader: MiniCssExtractPlugin.loader,
// css is located in `static/css`, use '../../' to locate index.html folder
// in production `paths.publicUrlOrPath` can be a relative path
options: paths.publicUrlOrPath.startsWith('.')
? { publicPath: '../../' }
: {},
},
{
.....
WebpackDevServer.config.js
/**
* Copyright (c) 2015-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
// #remove-on-eject-end
'use strict';
const fs = require('fs');
const errorOverlayMiddleware = require('react-dev-utils/errorOverlayMiddleware');
const evalSourceMapMiddleware = require('react-dev-utils/evalSourceMapMiddleware');
const noopServiceWorkerMiddleware = require('react-dev-utils/noopServiceWorkerMiddleware');
const ignoredFiles = require('react-dev-utils/ignoredFiles');
const redirectServedPath = require('react-dev-utils/redirectServedPathMiddleware');
const paths = require('./paths');
const getHttpsConfig = require('./getHttpsConfig');
const host = process.env.HOST || '0.0.0.0';
const sockHost = process.env.WDS_SOCKET_HOST;
const sockPath = process.env.WDS_SOCKET_PATH; // default: '/sockjs-node'
const sockPort = process.env.WDS_SOCKET_PORT;
module.exports = function(proxy, allowedHost) {
return {
// WebpackDevServer 2.4.3 introduced a security fix that prevents remote
// websites from potentially accessing local content through DNS rebinding:
// https://github.com/webpack/webpack-dev-server/issues/887
// https://medium.com/webpack/webpack-dev-server-middleware-security-issues-1489d950874a
// However, it made several existing use cases such as development in cloud
// environment or subdomains in development significantly more complicated:
// https://github.com/facebook/create-react-app/issues/2271
// https://github.com/facebook/create-react-app/issues/2233
// While we're investigating better solutions, for now we will take a
// compromise. Since our WDS configuration only serves files in the `public`
// folder we won't consider accessing them a vulnerability. However, if you
// use the `proxy` feature, it gets more dangerous because it can expose
// remote code execution vulnerabilities in backends like Django and Rails.
// So we will disable the host check normally, but enable it if you have
// specified the `proxy` setting. Finally, we let you override it if you
// really know what you're doing with a special environment variable.
disableHostCheck:
!proxy || process.env.DANGEROUSLY_DISABLE_HOST_CHECK === 'true',
// Enable gzip compression of generated files.
compress: true,
// Silence WebpackDevServer's own logs since they're generally not useful.
// It will still show compile warnings and errors with this setting.
clientLogLevel: 'none',
// By default WebpackDevServer serves physical files from current directory
// in addition to all the virtual build products that it serves from memory.
// This is confusing because those files won’t automatically be available in
// production build folder unless we copy them. However, copying the whole
// project directory is dangerous because we may expose sensitive files.
// Instead, we establish a convention that only files in `public` directory
// get served. Our build script will copy `public` into the `build` folder.
// In `index.html`, you can get URL of `public` folder with %PUBLIC_URL%:
// <link rel="icon" href="%PUBLIC_URL%/favicon.ico">
// In JavaScript code, you can access it with `process.env.PUBLIC_URL`.
// Note that we only recommend to use `public` folder as an escape hatch
// for files like `favicon.ico`, `manifest.json`, and libraries that are
// for some reason broken when imported through webpack. If you just want to
// use an image, put it in `src` and `import` it from JavaScript instead.
contentBase: paths.appPublic,
contentBasePublicPath: paths.publicUrlOrPath,
// By default files from `contentBase` will not trigger a page reload.
watchContentBase: true,
// Enable hot reloading server. It will provide WDS_SOCKET_PATH endpoint
// for the WebpackDevServer client so it can learn when the files were
// updated. The WebpackDevServer client is included as an entry point
// in the webpack development configuration. Note that only changes
// to CSS are currently hot reloaded. JS changes will refresh the browser.
hot: true,
// Use 'ws' instead of 'sockjs-node' on server since we're using native
// websockets in `webpackHotDevClient`.
transportMode: 'ws',
// Prevent a WS client from getting injected as we're already including
// `webpackHotDevClient`.
injectClient: false,
// Enable custom sockjs pathname for websocket connection to hot reloading server.
// Enable custom sockjs hostname, pathname and port for websocket connection
// to hot reloading server.
sockHost,
sockPath,
sockPort,
// It is important to tell WebpackDevServer to use the same "publicPath" path as
// we specified in the webpack config. When homepage is '.', default to serving
// from the root.
// remove last slash so user can land on `/test` instead of `/test/`
publicPath: paths.publicUrlOrPath.slice(0, -1),
// WebpackDevServer is noisy by default so we emit custom message instead
// by listening to the compiler events with `compiler.hooks[...].tap` calls above.
quiet: true,
// Reportedly, this avoids CPU overload on some systems.
// https://github.com/facebook/create-react-app/issues/293
// src/node_modules is not ignored to support absolute imports
// https://github.com/facebook/create-react-app/issues/1065
watchOptions: {
ignored: ignoredFiles(paths.appSrc)
},
...
Thanks Again,
Adam

Problem deploying only Apollo Server to heroku

I am deploying an Apollo Server for my database to heroku and it is giving an application error. It is not simply show that there is a problem with the get route, it says that the application has an error and the error logs say that the app is crashing. It runs fine locally.
I have set up the procfile with: web: node app.js .
I have tried it with the procfile removed.
I have set playground and introspection to true. I saw that that could be the problem but it did not seem to help.
The port is set to process.env.PORT || 8080 .
Here is the minimal code:
const { ApolloServer } = require('apollo-server-express');
const express = require('express');
const db = require('./models');
const typeDefs = require('./data/schema');
const resolvers = require('./data/resolvers');
const app = express();
const server = new ApolloServer({
typeDefs,
resolvers,
context: { db },
introspection: true,
playground: true,
});
server.applyMiddleware({ app });
const PORT = process.env.PORT || 8080;
app.get('/', (req, res) => {
res.send('hello');
});
app.listen(PORT, () => {
console.log(`Server is ready at ${PORT}`);
});
I am also using some other functions (trying to set up a cron process), but those are commented out.
I would expect to get the / get route to at least say hello, or for the /graphql route to display playground. I am getting neither of those options.
It turns out that I needed to add the following to package.json:
"scripts": {
"start": "app.js",
...
}
And I needed to install packages listed in the heroku logs --tail, but I have had those errors before. Writing the script start key into the package.json file is for when you are deploying your server independently of your react (or client) side.

Use Express.js in an existing Nuxt.js project

I have a project built with Nuxt.js and I want to use express to be able to report bugsnag errors on my asyncData method etc.
How would I go to import that? I suppose is not as simple as npm install express --save.
I already have an api written in PHP so I would not use that as an api or anything else.
Is it overkill? Or is it a necessary evil? :D
To start using Express with an existing Nuxt project, you'll need to set up a simple server.js file that sets up your Express server and adds your Nuxt application as middleware. The only slight complication is setting it up to auto-rebuild in development. Here's a quick example server.js file that pulls in Nuxt and handles building when not in production.
const { Nuxt, Builder } = require('nuxt');
const app = require('express')();
// We instantiate Nuxt.js with the options
const isProd = process.env.NODE_ENV === 'production';
const config = require('./nuxt.config.js');
config.dev = !(isProd);
const nuxt = new Nuxt(config);
// No build in production
if (!isProd) {
const builder = new Builder(nuxt);
builder.build();
}
app.use(nuxt.render);
app.listen(3000);
console.log('Server is listening on http://localhost:3000');
You can then incorporate bugsnag as you normally would in express, I assume by requiring it and including it as middleware.
You dont need express to handle errors in asyncData. To handle errors in asyncData/fetch on ssr you just need to hook into render:errorMiddleware. See sentry plugin for nuxt for example
But it would only catch errors that happens on SSR. On client unfortunately that wont catch anything ( as well as express wont do anything for client). There is a bug for this in nuxt see here