Related
My project has 2 folders: client(next.js with custom server) and server(node.js).
I have uploaded it in a Ubuntu 20.04 server and build next.js project in client folder. it works.
I have recently changed some pages of next.js and uploaded to client folder by "sudo git pull".
Now I would like to run "npm run build" to build next.js again, but it gives Error:
warn - No ESLint configuration detected. Run next lint to begin setup
Build error occurred
Error: > Build directory is not writeable. https://nextjs.org/docs/messages/build-dir-not-writeable
at /home/skadmin/client/node_modules/next/dist/build/index.js:275:19
at async Span.traceAsyncFn (/home/skadmin/client/node_modules/next/dist/telemetry/trace/trace.js:60:20)
at async Object.build [as default] (/home/skadmin/client/node_modules/next/dist/build/index.js:77:25)
info - Creating an optimized production build
==========My Custom server is:
'''
const express = require('express')
const next = require('next')
const { createProxyMiddleware } = require('http-proxy-middleware')
const dev = process.env.NODE_ENV !== 'production'
const app = next({ dev })
const handle = app.getRequestHandler()
app
.prepare()
.then(() => {
const server = express()
// apply proxy in dev mode
if (dev) {
server.use(
'/api',
createProxyMiddleware({
target: 'http://localhost:8000',
changeOrigin: true,
})
)
}
server.all('*', (req, res) => {
return handle(req, res)
})
server.listen(3000, (err) => {
if (err) throw err
console.log('> Ready on http://localhost:8000')
})
})
.catch((err) => {
console.log('Error', err)
})
'''
=======================package.json is=>:
'''
{
"name": "client",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"dev": "node server.js",
"build": "next build",
"start": "NODE_ENV=production node server.js"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"#ant-design/icons": "^4.5.0",
"#glidejs/glide": "^3.4.1",
"#material-ui/core": "^4.11.4",
"#material-ui/icons": "^4.11.2",
"#persian-tools/persian-tools": "^3.0.1",
"antd": "^4.13.1",
"axios": "^0.21.4",
"express": "^4.17.1",
"http-proxy-middleware": "^2.0.0",
"lodash": "^4.17.21",
"moment-jalaali": "^0.9.2",
"multer": "^1.4.4",
"next": "^11.1.3",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-icons": "^4.2.0",
"react-image-file-resizer": "^0.4.7",
"react-markdown": "^6.0.2",
"react-scroll": "^1.8.2",
"react-toastify": "^7.0.4",
"reactstrap": "^8.9.0",
"swiper": "^7.4.1"
}
}
'''
Please help me, what should I do?
when i tried to generate a build and serve SSR project with angular i got this error
C:\Projects\cloud_market_ssr\client\dist\market\server\main.js:72623
var requestFn = window.requestAnimationFrame||getPrefixed('RequestAnimationFrame') || timeoutDefer;
ReferenceError: window is not defined
at C:\Projects\cloud_market_ssr\client\dist\market\server\main.js:72623:19
at C:\Projects\cloud_market_ssr\client\dist\market\server\main.js:72404:11
at Object.4R65 (C:\Projects\cloud_market_ssr\client\dist\market\server\main.js:72406:2)
at __webpack_require__ (C:\Projects\cloud_market_ssr\client\dist\market\server\main.js:26:30)
at Module.ZeVW (C:\Projects\cloud_market_ssr\client\dist\market\server\main.js:223603:65)
at __webpack_require__ (C:\Projects\cloud_market_ssr\client\dist\market\server\main.js:26:30)
at Module.PCNd (C:\Projects\cloud_market_ssr\client\dist\market\server\main.js:178377:126)
at __webpack_require__ (C:\Projects\cloud_market_ssr\client\dist\market\server\main.js:26:30)
at Module.ZAI4 (C:\Projects\cloud_market_ssr\client\dist\market\server\main.js:221439:79)
at __webpack_require__ (C:\Projects\cloud_market_ssr\client\dist\market\server\main.js:26:30)
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
Process finished with exit code 1
this is the packages that i installed and they perfectly work
{
"name": "market",
"version": "0.0.0",
"scripts": {
"ng": "ng",
"start": "ng serve",
"build": "ng build --prod",
"test": "ng test",
"lint": "ng lint",
"e2e": "ng e2e",
"dev:ssr": "ng run market:serve-ssr",
"serve:ssr": "node dist/market/server/main.js",
"build:ssr": "npm run build && ng run market:server:production",
"full:ssr": "npm run build:ssr && npm run dev:ssr && npm run serve:ssr",
"prerender": "ng run market:prerender"
},
"private": true,
"dependencies": {
"#angular/animations": "^11.2.13",
"#angular/cdk": "^11.2.12",
"#angular/common": "^11.2.13",
"#angular/compiler": "^11.2.13",
"#angular/core": "^11.2.13",
"#angular/flex-layout": "^11.0.0-beta.33",
"#angular/forms": "^11.2.13",
"#angular/material": "^11.2.12",
"#angular/platform-browser": "^11.2.13",
"#angular/platform-browser-dynamic": "^11.2.13",
"#angular/platform-server": "^11.2.13",
"#angular/pwa": "^0.1102.12",
"#angular/router": "^11.2.13",
"#angular/service-worker": "^11.2.13",
"#nguniversal/express-engine": "^11.2.1",
"#nicky-lenaers/ngx-scroll-to": "^9.0.0",
"core-js": "^2.5.4",
"cors": "^2.8.5",
"domino": "^2.1.6",
"echarts": "^4.2.0-rc.2",
"echarts-gl": "^1.1.1",
"edit-json-file": "^1.6.0",
"express": "^4.15.2",
"font-awesome": "^4.7.0",
"hammerjs": "^2.0.8",
"jalali-moment": "^3.2.1",
"jquery": "^3.4.1",
"leaflet": "^1.7.1",
"leaflet-arc": "^1.0.2",
"localforage": "^1.5.0",
"localstorage-polyfill": "^1.0.1",
"mock-browser": "^0.92.14",
"moment-jalaali": "~0.9.2",
"ngforage": "^6.0.0",
"ngx-image-compress": "^11.0.3",
"ngx-image-zoom": "^0.6.0",
"ngx-owl-carousel-o": "^5.0.0",
"ngx-pagination": "^5.1.0",
"ngx-slick-carousel": "~0.5.1",
"rxjs": "^6.5.3",
"sass": "^1.32.6",
"slick-carousel": "~1.8.1",
"webpack-node-externals": "^3.0.0",
"zone.js": "~0.11.4"
},
"devDependencies": {
"#angular-devkit/build-angular": "~0.1002.0",
"#angular/cli": "^11.2.12",
"#angular/compiler-cli": "^11.2.13",
"#angular/language-service": "^11.2.13",
"#nguniversal/builders": "^10.1.0",
"#types/express": "^4.17.0",
"#types/jasmine": "~3.7.2",
"#types/jasminewd2": "~2.0.9",
"#types/node": "~14.14.44",
"codelyzer": "~6.0.2",
"eslint": "~7.26.0",
"jasmine-core": "~3.7.1",
"jasmine-spec-reporter": "~7.0.0",
"karma": "~6.3.2",
"karma-chrome-launcher": "~3.1.0",
"karma-coverage-istanbul-reporter": "~3.0.3",
"karma-jasmine": "~4.0.1",
"karma-jasmine-html-reporter": "^1.6.0",
"protractor": "^7.0.0",
"ts-node": "~9.1.1",
"typescript": "~4.0.6"
}
}
and this is my server.ts
import 'zone.js/dist/zone-node';
import * as express from 'express';
import { ngExpressEngine } from '#nguniversal/express-engine';
import { join } from 'path';
///Handle Error local storage & document & window not defined
const MockBrowser = require('mock-browser').mocks.MockBrowser;
const mock = new MockBrowser();
const cors = require('cors');
const exp = require('express');
const application = exp();application.use(cors());
const domino = require("domino");
const fs = require("fs");
const path = require("path");
const templateA = fs
.readFileSync(path.join("dist/browser", "index.html"))
.toString();
const win = domino.createWindow(templateA);
win.Object = Object;
win.Math = Math;
import 'localstorage-polyfill';
global['localStorage'] = localStorage;
global["window"] = mock.getWindow();
global["document"] = mock.getDocument();
global["branch"] = null;
global["object"] = win.object;
global['navigator'] = mock.getNavigator();
Object.defineProperty(document.body.style, 'transform', {
value: () => {
return {
enumerable: true,
configurable: true
};
},
});
//////////////////////////////////////
import { APP_BASE_HREF } from '#angular/common';
import { AppServerModule } from './src/main.server';
import { existsSync } from 'fs';
// The Express app is exported so that it can be used by serverless Functions.
export function app(): express.Express {
const server = express();
const distFolder = join(process.cwd(), 'dist/client/browser');
const indexHtml = existsSync(join(distFolder, 'index.original.html')) ? 'index.original.html' : 'index';
// Our Universal express-engine (found # https://github.com/angular/universal/tree/master/modules/express-engine)
server.engine('html', ngExpressEngine({
bootstrap: AppServerModule,
}));
server.set('view engine', 'html');
server.set('views', distFolder);
// Example Express Rest API endpoints
// server.get('/api/**', (req, res) => { });
// Serve static files from /browser
server.get('*.*', express.static(distFolder, {
maxAge: '1y'
}));
// All regular routes use the Universal engine
server.get('*', (req, res) => {
res.render(indexHtml, { req, providers: [{ provide: APP_BASE_HREF, useValue: req.baseUrl }] });
});
return server;
}
function run(): void {
const port = process.env.PORT || 5050;
// Start up the Node server
const server = app();
server.listen(port, () => {
console.log(`Node Express server listening on http://localhost:${port}`);
});
}
// Webpack will replace 'require' with '__webpack_require__'
// '__non_webpack_require__' is a proxy to Node 'require'
// The below code is to ensure that the server is run only when not requiring the bundle.
declare const __non_webpack_require__: NodeRequire;
const mainModule = __non_webpack_require__.main;
const moduleFilename = mainModule && mainModule.filename || '';
if (moduleFilename === __filename || moduleFilename.includes('iisnode')) {
run();
}
const nodeExternals = require('webpack-node-externals');
module.exports = {
externals: [nodeExternals()],
// etc configs here
}
export * from './src/main.server';
You are probably using some library or component in which needs the window to be rendered, as example, a chart.
Go over your code base and see if anything could be using the window and that doesnt need to be rendered server side.
Once you find it, use the platform id injector from angular to check wheter you are on the browser or the server, if it is on server do not render said component.
error image I am trying to implement angular universal and pwa together.
I referred the below link:
https://medium.com/digital-diplomacy/how-to-enable-server-side-rendering-and-pwa-for-your-angular-app-2831b16fa99b
after executing command: npm run serve:ssr
getting the below error.
\server\main.js
var userLangAttribute = navigator.language || navigator.userLanguage || navigator.browserLanguage; ^
ReferenceError: navigator is not defined
package.json
{
"name": "my-hilarious-app",
"version": "0.0.0",
"scripts": {
"ng": "ng",
"start": "ng serve",
"build": "ng build",
"test": "ng test",
"lint": "ng lint",
"e2e": "ng e2e",
"dev:ssr": "ng run my-hilarious-app:serve-ssr",
"serve:ssr": "node dist/my-hilarious-app/server/main.js",
"build:ssr": "ng build --prod && ng run my-hilarious-app:server:production",
"prerender": "ng run my-hilarious-app:prerender"
},
"private": true,
"dependencies": {
"#agm/core": "^1.0.0-beta.5",
"#angular/animations": "~11.2.5",
"#angular/cdk": "^11.2.4",
"#angular/common": "~11.2.5",
"#angular/compiler": "~11.2.5",
"#angular/core": "~11.2.5",
"#angular/fire": "^6.0.5",
"#angular/forms": "~11.2.5",
"#angular/material": "^11.2.4",
"#angular/platform-browser": "~11.2.5",
"#angular/platform-browser-dynamic": "~11.2.5",
"#angular/platform-server": "~11.2.5",
"#angular/router": "~11.2.5",
"#angular/service-worker": "~11.2.5",
"#fortawesome/fontawesome-free": "^5.15.2",
"#ng-bootstrap/ng-bootstrap": "^9.0.2",
"#ngrx/effects": "^11.0.1",
"#ngrx/store": "^11.0.1",
"#nguniversal/express-engine": "^11.2.1",
"#types/googlemaps": "^3.36.0",
"angularx-social-login": "^3.5.4",
"bootstrap3": "^3.3.5",
"core-js": "^3.9.1",
"crypto-js": "^3.1.9-1",
"express": "^4.17.1",
"firebase": "^8.3.0",
"font-awesome": "^4.7.0",
"globalthis": "^1.0.2",
"hammerjs": "^2.0.8",
"jquery": "^3.6.0",
"ngx-cookie-service": "^11.0.2",
"ngx-owl-carousel-o": "^5.0.0",
"ngx-toastr": "^13.2.0",
"ngx-xml2json": "^1.0.2",
"rxjs": "~6.6.6",
"smart-app-banner": "^2.0.0",
"tslib": "^2.1.0",
"webpack-dev-server": ">=3.11.2",
"zone.js": "~0.11.4"
},
"devDependencies": {
"#angular-devkit/build-angular": "~0.1102.4",
"#angular/cli": "~11.2.4",
"#angular/compiler-cli": "~11.2.5",
"#nguniversal/builders": "^11.2.1",
"#types/express": "^4.17.11",
"#types/jasmine": "~3.6.6",
"#types/node": "^14.14.33",
"codelyzer": "^6.0.1",
"jasmine-core": "~3.6.0",
"jasmine-spec-reporter": "~6.0.0",
"karma": "~6.2.0",
"karma-chrome-launcher": "~3.1.0",
"karma-coverage": "~2.0.3",
"karma-jasmine": "~4.0.1",
"karma-jasmine-html-reporter": "^1.5.4",
"protractor": "~7.0.0",
"ts-node": "~9.1.1",
"tslint": "~6.1.3",
"typescript": "~4.1.5"
}
}
server.ts
import 'zone.js/dist/zone-node';
import { ngExpressEngine } from '#nguniversal/express-engine';
import * as express from 'express';
import { join } from 'path';
import { AppServerModule } from './src/main.server';
import { APP_BASE_HREF } from '#angular/common';
import { existsSync } from 'fs';
const domino = require('domino');
const fs = require('fs');
const path = require('path');
const template = fs.readFileSync(path.join('.', 'dist/my-hilarious-app/browser', 'index.html')).toString();
const win = domino.createWindow(template);
// tslint:disable-next-line:no-string-literal
global['window'] = win;
// tslint:disable-next-line:no-string-literal
global['document'] = win.document;
// tslint:disable-next-line:no-string-literal
global['DOMTokenList'] = win.DOMTokenList;
// tslint:disable-next-line:no-string-literal
global['Node'] = win.Node;
// tslint:disable-next-line:no-string-literal
global['Text'] = win.Text;
// tslint:disable-next-line:no-string-literal
global['HTMLElement'] = win.HTMLElement;
// tslint:disable-next-line:no-string-literal
global['navigator'] = win.navigator;
// The Express app is exported so that it can be used by serverless Functions.
export function app(): express.Express {
const server = express();
const distFolder = join(process.cwd(), 'dist/my-hilarious-app/browser');
const indexHtml = existsSync(join(distFolder, 'index.original.html')) ? 'index.original.html' : 'index';
// Our Universal express-engine (found # https://github.com/angular/universal/tree/master/modules/express-engine)
server.engine('html', ngExpressEngine({
bootstrap: AppServerModule,
}));
server.set('view engine', 'html');
server.set('views', distFolder);
// Example Express Rest API endpoints
// server.get('/api/**', (req, res) => { });
// Serve static files from /browser
server.get('*.*', express.static(distFolder, {
maxAge: '1y'
}));
// All regular routes use the Universal engine
server.get('*', (req, res) => {
res.render(indexHtml, { req, providers: [{ provide: APP_BASE_HREF, useValue: req.baseUrl }] });
});
return server;
}
function run(): void {
const port = process.env.PORT || 4000;
// Start up the Node server
const server = app();
server.listen(port, () => {
console.log(`Node Express server listening on http://localhost:${port}`);
});
}
// Webpack will replace 'require' with '__webpack_require__'
// '__non_webpack_require__' is a proxy to Node 'require'
// The below code is to ensure that the server is run only when not requiring the bundle.
declare const __non_webpack_require__: NodeRequire;
const mainModule = __non_webpack_require__.main;
const moduleFilename = mainModule && mainModule.filename || '';
if (moduleFilename === __filename || moduleFilename.includes('iisnode')) {
run();
}
export * from './src/main.server';
[1]: https://i.stack.imgur.com/P7vyi.png
[1]: https://i.stack.imgur.com/ZiulH.png
above file is my server.ts and package.json.As main.js is readonly file we cannot make any changes on it.I am able to run the command: ng build --prod && ng run my-hilarious-app:server:production. but after this when I am running this command:ng run my-hilarious-app:serve-ssr.I am facing issue.
Thanks!
I got the solution. I found that smart-app-banner which a third party plugin was giving the error.So I replaced that smart app banner code by ngx smart banner.I installed and implemented ngx smart banner.And was able to run it smoothly.
So basically with my app i have react js and node js. Everything works fine but I have a section of the web app that makes a post request to the node backend to get data related to getting an array of items through the ebay api. This worked fine during development but when I tried to do the same thing after deployment, I get a 404 error
Response {type: "basic", url: "https://udabasili.herokuapp.com/api/ebay", redirected: false, status: 404, ok: false, …}
The client link is https://udabasili.herokuapp.com/
The server link is https://ud-portfolio-app.herokuapp.com/
I even used postman to send a post request to the node domain deployed on heroku and it works, so the problem seems to be from the react js app
The app is a quite big but basically i have the node and react on two different domains with have the static.json linking the node serveri have deployed already to react js using proxy
The important sections of the app involved :
STATIC.JSON
{
"root":"build/",
"routes":{
"/**":"index.html"
},
"proxies":{
"/api/":{
"origin":"https://ud-portfolio-app.herokuapp.com/"
}
}
}
NODE.JS
const express = require("express");
const app = express()
const path = require("path")
const Ebay = require('ebay-node-api');
const cors = require("cors")
const bodyParser = require("body-parser");
const PORT = process.env.PORT || 8081;
let access_token = '';
let ebay = new Ebay({
clientID: '******************',
clientSecret: '*******************',
body: {
grant_type: 'client_credentials',
scope: 'https://api.ebay.com/oauth/api_scope'
}
});
app.use(cors());
app.use(bodyParser.urlencoded({extended:true}));
app.use(bodyParser.json());
// An api endpoint that returns a short list of items
app.post('/api/ebay', (req,res) => {
const item = req.body.itemName;
ebay.findItemsByKeywords({
keywords: `${item} movie`,
}).then((data) => {
res.json(data[0].searchResult[0].item);
}, (error) => {
console.log(error);
});
});
app.listen(PORT);
REST API SECTION
At this section I fetch the two apis . The youtube one work but the ebay has the 404 error
function fetchProducts(name) {
const itemName = name;
const ebayApi = fetch("/api/ebay",
{
method: "POST",
cache: "no-cache",
headers:{
"Content-Type": "application/json"
},
body:JSON.stringify({itemName:itemName})
}
);
const youtubeApi = fetch(`https://www.googleapis.com/youtube/v3/search?part=snippet&q=${name}%20movie%20trailer&key=**************`);
return (dispatch) => {
Promise.all([ebayApi, youtubeApi])
.then( values => Promise.all(values.map(value =>{
console.log(value);
return value.json()})
))
.then(res => {
const youtube = `https://www.youtube.com/embed/${res[1].items[0].id.videoId}?autoplay=1&showinfo=0&rel=0`;
return (res[0], res[1].items[0].id.videoId)
})
.catch((error) => {
console.log(error);
});
};
}
export default fetchProducts;
CLIENT PACKAGE.JSON
{
"name": "client",
"version": "0.1.0",
"proxy": "http://localhost:8081",
"private": true,
"dependencies": {
"babel-eslint": "^10.0.3",
"d3": "^5.12.0",
"ebay-node-api": "^2.7.2",
"flag-icon-css": "^3.4.5",
"font-awesome": "^4.7.0",
"node-sass": "^4.13.0",
"prop-types": "^15.7.2",
"react": "^16.11.0",
"react-dom": "^16.11.0",
"react-redux": "^7.1.1",
"react-router-dom": "^5.1.2",
"react-scripts": "3.2.0",
"react-transition-group": "^4.3.0",
"redux": "^4.0.4",
"redux-persist": "^6.0.0",
"redux-thunk": "^2.3.0",
"topojson-client": "^3.0.1",
"youtube-api-search": "^0.0.5"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject",
"lint": "eslint --ext .js --ext .jsx ."
},
"eslintConfig": {
"extends": "react-app"
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"devDependencies": {
"eslint": "^6.6.0",
"eslint-config-airbnb": "^18.0.1",
"eslint-plugin-import": "^2.18.2",
"eslint-plugin-jsx-a11y": "^6.2.3",
"eslint-plugin-react": "^7.16.0",
"eslint-plugin-react-hooks": "^1.7.0"
}
}
I need to connect Vue.js app to the remote MSSQL server.
I am using node.js, mssql library.
After setting up I get error.
How to make configuration settings in order to connect to mssql?
How to solve issues related to installation of libraries?
ERROR Failed to compile with 5 errors 1:39:06 PM
These dependencies were not found:
* dgram in ./node_modules/native-dns-cache/lookup.js, ./node_modules/native-dns/lib/server.js and 2 others
* fs in ./node_modules/native-dns/lib/platform.js
To install them, you can run: npm install --save dgram fs
package.json dependencies:
...
},
"dependencies": {
"dgram": "^1.0.1",
"dns": "^0.2.2",
"firebase": "^4.10.0",
"fs": "0.0.1-security",
"highcharts": "^6.0.7",
"mssql": "^4.1.0",
"net": "^1.0.2",
"tls": "0.0.1",
"vue": "^2.5.3",
"vue-highcharts": "0.0.10",
"vue-router": "^3.0.1",
"vuetify": "^0.17.7",
"vuex": "^3.0.1"
}, ...
I solve this problem. As I am very new in this environment. Vue app renders client-side. I build server-side using template "webpack-ssr".
Here is more information about server-side rendering
here is my test code:
...
const sql = require('mssql')
...
// Create connection to database
const databaseConfig = {
userName: 'USER_NAME',
password: 'PASSWORD',
server: 'SERVER_NAMECLOUDAPP.AZURE.COM',
database: 'DATABASE',
options: {
encrypt: true // Use this if you're on Windows Azure
}
}
...
Data conncetion:
// mssql connect for database
sql.connect(databaseConfig, err => {
// ... error checks
if (err) {
console.log('error: ' + err)
} else {
console.log('conencted')
}
// Query
new sql.Request().query('select 1 as number', (err , result) => {
// ... error checks
...
console.dir(result + ' hmmm ... not good')
})
})
...