expressjs and create react app deployment with zeit now - express

I was able to deploy a Create-React-App and express back-end with now.sh
but the problem is that it only gets the home route(I can route to /about from home but on page reload/refresh, i get a 404 error). I have tried several config. Please i need help.
"public": false,
"version": 2,
"builds": [
{
"src": "server/index.js",
"use": "#now/node",
"config": {
"maxLambdaSize": "20mb"
}
},
{
"src": "package.json",
"use": "#now/static-build",
"config": {
"distDir": "build"
}
}
],
"routes": [
{
"src": "/api/(.*)",
"dest": "/server/index.js"
},
{
"src": "/(.*)",
"dest": "/build/$1"
}
]
}

This sounds like a problem described here - https://create-react-app.dev/docs/deployment/
If you use routers that use the HTML5 pushState history API under the hood (for example, React Router with browserHistory), many static file servers will fail. For example, if you used React Router with a route for /todos/42, the development server will respond to localhost:3000/todos/42 properly, but an Express serving a production build as above will not.
This is because when there is a fresh page load for a /todos/42, the server looks for the file build/todos/42 and does not find it. The server needs to be configured to respond to a request to /todos/42 by serving index.html. For example, we can amend our Express example above to serve index.html for any unknown paths:
app.use(express.static(path.join(__dirname, 'build')));
-app.get('/', function (req, res) {
+app.get('/*', function (req, res) {
res.sendFile(path.join(__dirname, 'build', 'index.html'));
});
When users install your app to the homescreen of their device the default configuration will make a shortcut to /index.html. This may not work for client-side routers which expect the app to be served from /. Edit the web app manifest at public/manifest.json and change start_url to match the required URL scheme, for example:
"start_url": ".",
This helped when I had 404 with Zeit - https://itnext.io/fix-404-error-on-single-page-app-with-zeit-now-b35b8c9eb8fb -
In order to solve the 404 error message, we have to make sure that when a user goes to any URL which is not the root URL (e.g. www.myapp.com/something or www.myapp.com/dashboard/example) and they have never loaded our web app before, they are redirected to the root URL. Once they have loaded the root URL then they can be redirected back to the page they were trying to access and everyone is happy!
Step 1 - in your project's public folder make another package.json file -
{
"name": "myapp-spa",
"version": "1.0.0",
"scripts": {
"start": "serve --single --cache=60000"
},
"dependencies": {
"serve": "latest"
}
}
Step 2 - Configure the 404 page
Now that our files are being served, if a person goes to a non-root URL, the server will look for a 404.html file to send them instead. This is our chance to redirect them and take them to the index.html page. Put the 404.html file in the same public folder as the index file.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>404 Not Found | My App</title>
</head>
<body>
<script>
(function redirect() {
if (document && document.location) {
document.location.replace(`/?redirect=${encodeURIComponent(document.location.pathname)}`);
}
}());
</script>
</body>
</html>
Step 3. - Prepare for deployments
Now that, we have our redirect code, all we have to do is add a deploy command to our original myapp/package.json (this is not the file we created earlier):
{
"scripts": {
...
"deploy": "yarn run build && now ./build --name=myapp-spa",
"start": "react-scripts start",
"build": "react-scripts build",
...
}
}
Sweet, now all we need to do is call yarn run deploy and our app should stop getting the 404 error pages.
Step 4: Clean up
In order to get back to the page we originally requested e.g. myapp.com/something we need to redirect the page to the ?redirect parameter we set earlier in the tutorial. To do this, we need to install the query-string library to parse the parameter. Then you can include the following code into your app in a place that loads after your routing code loads.
const queryString = require('query-string');
...
const params = queryString.parse(document.location.search);
const redirect = params.redirect; // this would be "abcdefg" if the query was "?redirect=abcdefg"
if (document.location.pathname === '/' && redirect) {
document.location.assign(`${document.location.origin}/${redirect}`);
}
It’s important that you do not redirect the user with the above code until after the routing code is cached in the browser. Once you’ve finished, your app should be working just as it should be.
Basically pasted the whole thing, but make sure to check the article.
Apparently there's another possible solution, might be worth trying:
{
...
"builds": [
{ "src": "build/**", "use": "#now/static" }
],
"routes": [
{
"src": "/(.*)\\.(.*)",
"dest": "/build/$1.$2"
},
{
"src": "/",
"dest": "/build/index.html"
},
{
"src": "/(.*)",
"status": 301, "headers": { "Location": "/" }
}
]

Related

Nuxt content /articles not found on production

Hey I just incorporated Nuxt content into my website
It works like a breeze on development but it breaks on production idk why
Here is the code of my page
const articles = await $content('articles').sortBy('date', 'desc').fetch()
and this is the error message
[GET] /blog 07:36:06:28 ERROR /articles not found at QueryBuilder.fetch (node_modules/#nuxt/content/lib/query-builder.js:190:13)
What stuff should I try out to get more info? Maybe the folder content/articles is getting lost on build?
This is my dev script
"dev": "cross-env NODE_ENV=development nodemon server/index.js --watch server"
Maybe it has something to do with express?
Include the content directory as a server file in vercel.json.
{
"builds": [
{
"src": "nuxt.config.js",
"use": "#nuxtjs/vercel-builder",
"config": {
"serverFiles": [
"content/**"
]
}
}
]
}

How to setup multiple Environments in CypressJs

I haven't been able to figure out how to setup my cypressJs environments correctly to test. I'd love some help.
In my index.html file, in the <script> area, i am adding a CONFIG object. In production, this config object is added in by the MVC app. This config object can have many different states (some info might be missing or different for each user). In the cypress.json file, under "env" I have this same object. I use this in the spec.js files by calling Cypress.env("CONFIG"); which works just fine.
However, I want to change the state of the app/environment variable for different tests. Is this possible?
I'd like to run a spec file using a CONFIG that has all the data and one spec file using a CONFIG object that is missing data (ex. address == null) so I can test properly under both circumstances.
Is this possible or am I doing something fundamentally wrong?
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<script>
CONFIG = {
dealer: {
id: 19285,
address: "343 Somewhere Lane SpringField, TN 47383",
name: "HUDSON TRACTOR & RENTAL EQUIPMENT & OTHER HEAVY THINGS
}
</script>
</head>
</html>
cypress.json
{
"env": {
"CONFIG": {
dealer: {
id: 19285,
address: "343 Somewhere Lane SpringField, TN 47383",
name: "HUDSON TRACTOR & RENTAL EQUIPMENT & OTHER HEAVY THINGS
}
}
}
}
It is more of a best practice to run spec files against a single environment one at a time. It is either you use an overriding cypress.env.json or create 2 config files for each environment (test and prod for example) which will override env variables both set in cypress.env.json and cypress.json. https://docs.cypress.io/guides/guides/environment-variables.html#Option-2-cypress-env-json
However, if you want a quick and dirty solution to your issue above (I don't suggest this), you can set your spec files with the below:
cypress.json
{
"env": {
"CONFIG": {
"id": "19285",
"address": "343..."
},
"CONFIG_PROD": {
"id": "19285",
"address": ""
}
}
}
spec_1.js
const config = Cypess.env("CONFIG")
spec_2.js
const config = Cypress.env("CONFIG_PROD")
or just simply put them under fixture files (which I believe is more appropriate for this case):
config.json
{
"test": {
"id": "19285",
"address": "343..."
},
"prod": {
"id": "19285",
"address": ""
}
}
spec_1.js
import {test, prod} from '../fixtures/config.json'
const address = test.address
const address_null = prod.address //If you would like to run this on another 'it' test
spec_1.js
import {prod} from '../fixtures/config.json'
const address_null = prod.address

Getting a 404 response back from my local host

I've been given a home assignment for a job interview. For me to get going I need to work with an API end point they've provided me but I can't get it running for some reason. It should be straight forward but I keep getting 404 back.
This is my package.json:
{
"name": "frontend-dev-assignment",
"version": "0.1.0",
"private": true,
"dependencies": {
"canned": "0.3.12"
},
"devDependencies": {
"concurrently": "3.5.1"
},
"scripts": {
"start": "canned -p 5000 ./api/"
},
"proxy": "http://localhost:5000"
}
In that same directory I have a folder named api and in it a file called _search.get.json. This is the contents of that file (shortened):
[
{
"term": "Abyssinian",
"resultCount": 61
},
{
"term": "Aegean",
"resultCount": 26
},
{
"term": "American Curl",
"resultCount": 56
}
]
In the parent folder I ran npm install and then npm start. I got this line in my CLI:
starting canned on port 5000 for C:\Users\Yanay\Documents\Coding\Autocomplete\api (Autocoplete is that parent folder).
But when I try to access http://localhost:5000/ or http://localhost:5000//search?q=xxxx I keep getting a 404 back.
What could I be doing wrong here?

Mocha tests don't run with Webpack and mocha-loader

Background
I am porting some npm scripts to Webpack loaders to better learn how Webpack works and I’ve got everything working except for my Mocha tests: I have one failing test, but it is not showing that Mocha is being run with the mocha-loader or that the test is failing:
Question
What do I need to do differently to get all src/**/*.test.js files to run with with Mocha in Webpack?
Steps to reproduce
Clone https://github.com/trevordmiller/webpack-loaders-playground
Run npm test to see how tests should work
Run npm run dev to see how tests don't run with Webpack
Mocha loader won't run tests while building, it's used to create a bundle specifically containing your tests which you can then run from your browser.
I would recommend creating a separate webpack config file for your tests, which you can then host on a webpack-dev-server that uses a different port from your application. Here's an example that's more-or-less the pattern that I use for my own projects (as of writing this answer):
webpack.tests.config.js
module.exports = {
entry: 'mocha!./tests/index.js',
output: {
filename: 'test.build.js',
path: 'tests/',
publicPath: 'http://' + hostname + ':' + port + '/tests'
},
module: {
loaders: [
{
test: /\.js$/,
loaders: ['babel-loader']
},
{
test: /(\.css|\.less)$/,
loader: 'null-loader',
exclude: [
/build/
]
},
{
test: /(\.jpg|\.jpeg|\.png|\.gif)$/,
loader: 'null-loader'
}
]
},
devServer: {
host: hostname,
port: port
}
};
tests/index.js
// This will search for files ending in .test.js and require them
// so that they are added to the webpack bundle
var context = require.context('.', true, /.+\.test\.js?$/);
context.keys().forEach(context);
module.exports = context;
package.json
"scripts": {
"test": "find ./ -name '*.test.js' | xargs mocha -R min -r babel/register",
"devtest": "webpack-dev-server --config webpack.tests.config.js",
"dev": "webpack-dev-server --config webpack.config.js"
}
test.html
<!DOCTYPE html>
<html>
<head>
<title>Mocha</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="./node_modules/mocha/mocha.css" />
<script src="/tests/test.build.js"></script>
</head>
<body>
</body>
</html>
Then run npm run devtest, open http://localhost:<port you picked>/webpack-dev-server/test.html, and mocha should run your tests.
If you don't require CSS/LESS or images through your modules, you can remove those loaders from webpack.tests.config.js.
With hot loading enabled this is a really great setup because I can have both my application and my tests running in different browser tabs, then update my code and see my changes and my tests re-running immediately.
You can also run npm run test to execute the same tests through the command line.
Hope this helps.
I liked JimSkerritt's answer, but couldn't get it to work on my computer for some reason. With the two config files below you can run the app via:
npm start // then http://localhost:8080/bundle
and run your tests with:
npm test // then http://localhost:8081/webpack-dev-server/test
both servers auto-reload && you can run both simultaneously!
Config Files
webpack.config.js
module.exports = {
entry: "./index.js",
output: {
path: __dirname + "/build",
filename: "bundle.js"
},
module: {
loaders: [
{ test: /\.css$/, loader: "style!css" }
]
}
};
package.json
{
"name": "2dpointfinder",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "webpack-dev-server --inline",
"test": "webpack-dev-server 'mocha!./tests/test.js' --output-filename test.js --port 8081"
},
"author": "",
"license": "ISC",
"dependencies": {
"css-loader": "^0.19.0",
"style-loader": "^0.12.4"
},
"devDependencies": {
"mocha": "^2.3.3",
"mocha-loader": "^0.7.1",
"should": "^7.1.0"
}
}

What is the proper way to load an external javascript in Sencha Touch 2

In my development I need to include third part javascripts; like money.js (http://josscrowcroft.github.com/money.js/)
What is the best 'clean'/'proper' way to achieve it ? Just include it in index.html ?
No. Don't directly add the additional javascript files in the index.html file. That is not the recommended way (though it may work).
Instead, do like this,
Include the following line in your index.html. microloader is the folder that is shipped with sencha sdk and contains three files mainly, development.js, production.js and testing.js , each one for it's own purpose.
< script id ="microloader" type="text/javascript" src="../../microloader/development.js"> < /script >
Then, in your <appname> folder, you will need to have a file called as app.json. It will look something like this ..
{
"name": "Sencha",
// All javascript files go here ...
"js": [
{
"path": "../../sencha-touch-all-debug.js"
},
{
"path": "app.js",
"update": "delta"
},
{
"path": "http://josscrowcroft.github.com/money.js/",
"update": "delta"
}
],
"css": [
{
"path": "../../resources/css/sencha-touch.css",
"update": "delta"
},
{
"path": "resources/css/app.css",
"update": "delta"
}
],
.....
.....
.....
}
If you are using Sencha Cmd your index.html may look like this:
<!-- The line below must be kept intact for Sencha Command to build your application -->
<script id="microloader" type="text/javascript" src=".sencha/app/microloader/development.js"></script>
So after changing app.json you'll need to refresh your app:
sencha app refresh
Pure javascript did the trick for me. I just included this block of code in the launch function:
var scriptTag = document.createElement('script');
scriptTag.src = 'specify the path here...';
document.body.appendChild(scriptTag);
The scriptTag gets appended into the body of your index file.
The following worked for me with Ext JS 5.0.0, if the external JavaScript library is local. After the editing, run "sencha app build"
Make changes to three JSON elememtns in app.json.
(1) js
(2) css
(3) resources
{
"name": "Sencha",
// All javascript files go here ...
"js": [
{
"path": "app.js",
"bundle": true
},
{
"path": "leaflet/leaflet.js",
"bundle": true
}
],
"css": [
{
"path": "bootstrap.css",
"bootstrap": true
},
{
"path": "leaflet/leaflet.css",
"bootstrap": true
}
],
.....
/**
* Extra resources to be copied along when build
*/
"resources": [""leaflet/leaflet.js","leaflet/leaflet.css"
],
.....
.....
}