I created a new angular project and ran the following command:
ng add #spartacus/schematics --baseUrl https://spartacus-demo.eastus.cloudapp.azure.com:8443/ --baseSite=electronics-spa --ssr. After, I ran the command npm run dev:ssr, opened http://localhost:4200 and found the following problem:
Any ideas how to correct this bug and make the app run SSR instead of CSR? This warning message is showing for every route I try to access.
(https://github.com/SAP/spartacus/issues/10638)
it's because of SSR optimization feature available in Spartacus 3.0 and up.
You can either extend the timeout in your server.ts (passing a second parameter to NgExpressEngineDecorator.get method) or set it to 0, so it won't be fallbacking to CSR at all. Here is an example:
const ngExpressEngine = NgExpressEngineDecorator.get(engine, { timeout: 0 });
You can use API documentation to get a list of available options:
https://sap.github.io/spartacus/interfaces/SsrOptimizationOptions.html
Additionally, an extended documentation regarding this feature is on its way and should be available soon.
I encountered same issue, but changing timeout does not help!
The root cause is: the certificate of Commerce Cloud is invalid, as it is self-assigned.
Because I am using local commerce, with URL: localhost://9002
And the workaround is:
Add below config to package.json
"scripts": {
"dev:ssr": "cross-env NODE_TLS_REJECT_UNAUTHORIZED=0 ng run mystore:serve-ssr",
},
[...]
"devDependencies": {
[...]
"cross-env": "^7.0.0"
}
Then run following to start Spartacus
yarn dev:ssr
Related
Since the upgrade to Spartacus v3.0 SSR stop working with this output:
Unknown http response error: -1
Unknown http response error: -1
SSR rendering exceeded timeout, fallbacking to CSR for /
This happens for every route on the first render and then it fallback to CSR.
I tried to raise the timeout to a higher value, but that didn't help:
server.ts
...
const ngExpressEngine = NgExpressEngineDecorator.get(engine, { timeout: 10000 });
...
I get the same behaviour when I create a new Angular app and add the Spartacus schematics. Any idea how I can debug this?
Unknown http response error: -1 might indicate, that there is an issue with connection to backend server, did you check if everything works as intended?
If server indeed is missing proper ssl certificate, try adding
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
to server.ts (for debugging only!)
You can also disable the timeout and Spartacus built-in SSR optimizations completely with:
const ngExpressEngine = NgExpressEngineDecorator.get(engine, null);
You can also debug your SSR server, as explained in the docs (https://sap.github.io/spartacus-docs/how-to-debug-server-side-rendered-storefront/#nodejs-debugging-in-vs-code)
After setting below to package.json, the SSR begin to work:
"scripts": {
"dev:ssr": "cross-env NODE_TLS_REJECT_UNAUTHORIZED=0 ng run mystore:serve-ssr",
},
[...]
"devDependencies": {
[...]
"cross-env": "^7.0.0"
}
You need run
yarn dev:ssr
I'm trying to get Spartacus to work with SSR. When opening the default URL, http://localhost:4200, the storefront renders, as expected, but only after I clear the site data first. When I attempt to browse the storefront, API calls fail with a 504 (Gateway timeout). Chrome dev tools indicates the error is happening in the service worker. At this point, I'm wondering if I configured Spartacus incorrectly. When running Spartacus using yarn start rather than yarn serve:ssr, I can load the home page and browse the site normally.
OS: Ubuntu 16.04.6 LTS
Chrome Version: 73.0.3683.75
Node version: 11.15.0
Angular CLI version: 8.3.8
Yarn version: 1.19.1
ng new ssr-spartacus-app --style=scss
cd ssr-spartacus-app
ng add #spartacus/schematics --baseUrl https://localhost:9002 --baseSite cmssiteuid --pwa --ssr
rm src/app/app.component.html
echo "<cx-storefront>Loading...</cx-storefront>" > src/app/app.component.html
yarn build:ssr
yarn serve:ssr
Before running yarn build:ssr, I made following change to the app.module.ts file:
Before
context: {
baseSite: ['cmssiteuid'],
},
After
authentication: {
client_id: 'mobile_android',
client_secret: 'secret',
},
context: {
urlParameters: ['baseSite', 'language', 'currency'],
baseSite: ['cmssiteuid'],
},
I also set anonymousConsents to false. With this set to true, I was getting a lot of CORs errors.
If been scratching my head with this for a little while now and I'm hoping someone with more knowledge of Spartacus' inner workings can shed some light on why Spartacus is behaving this way with SSR.
I'm not sure that I can give you some certain recipe to fix the issue, obviously I need more details and logs relates to your problem, but still, based on my experience I can share with you some tips and tricks about how we should play with such issues (which relates to SSR).
Some set of theory which relates to SSR
https://angular.io/guide/universal (you can feel free to use Angular official documentation as a primary source, cuz Spartacus uses Angular OOTB features to make it works)
https://sap.github.io/spartacus-docs/server-side-rendering-in-spartacus/
https://enable.cx.sap.com/tag/tagid/spartacus (SSR related videos)
Practical approaches for debugging SSR
You should observe and analyze console output during starting your application in Node.js
You can use SSR configuration from example Storefront application (https://github.com/SAP/spartacus/tree/develop/projects/storefrontapp) like a starting point, cuz OOTB SSR works like a charm
Something from Spartacus team https://sap.github.io/spartacus-docs/how-to-debug-server-side-rendered-storefront/
Common set of theory to ensure that application has been configured correctly
SAP Commerce Cloud configuration for working with Spartacus https://sap.github.io/spartacus-docs/installing-sap-commerce-cloud/
Take a look on the guide https://sap.github.io/spartacus-docs/building-the-spartacus-storefront-from-libraries/ to ensure, that your frontend application has correct configuration
Double check your configuration which B2cStorefrontModule is using (here you can find an example project here https://github.com/SAP/spartacus/tree/develop/projects/storefrontapp)
Take a look on Network and Console browser tabs and try to resolve all errors
did you turn off PWA?
Turn PWA off.
As soon as Spartacus is installed in PWA mode, a service worker is installed, and it serves a cached version of index.html, along with the js files. This results in SSR being completely skipped. The following steps describe how to turn off PWA:
Check that there are no service workers registered in your app. If you do find any service workers, remove them.
Turn PWA off in your app module configuration, as follows:
StorefrontModule.withConfig({
backend: {
occ: {
baseUrl: 'https://[your_enpdoint],
},
},
pwa: {
enabled: false,
},
};
Rebuild your local Spartacus libraries by running the following command:
yarn build:core:lib
Build your local Spartacus shell app by running the following command:
yarn build --prod
Build the SSR version of your shell app by running the following command:
yarn build:ssr
Start Spartacus with the SSR server by running the following command:
yarn serve:ssr
If you are getting 504 after hitting the API service you need to check your API logs.
IF you have err log:
{"instant":{"epochSecond":1644915623,"nanoOfSecond":929833000},"thread":"hybrisHTTP1","level":"ERROR","loggerName":"org.springframework.web.servlet.DispatcherServlet","message":"Context initialization failed","thrown":{"commonElementCount":0,"localizedMessage":"Error creating bean with name 'cartEntriesController': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'defaultStockValidator' defined in ServletContext resource [/WEB-INF/config/v2/validators-v2-spring.xml]: Unsatisfied dependency expressed through constructor parameter 0: Could not convert argument value of type [de.hybris.platform.ycommercewebservices.stock.impl.DefaultCommerceStockFacade] to required type [de.hybris.platform.commercewebservices.core.stock.CommerceStockFacade]: Failed to convert value of type 'de.hybris.platform.ycommercewebservices.stock.impl.DefaultCommerceStockFacade' to required type 'de.hybris.platform.commercewebservices.core.stock.CommerceStockFacade'; nested exception is java.lang.IllegalStateException: Cannot convert value of type 'de.hybris.platform.ycommercewebservices.stock.impl.DefaultCommerceStockFacade' to required type 'de.hybris.platform.commercewebservices.core.stock.CommerceStockFacade': no matching editors or conversion strategy found","message":"Error creating bean with name 'cartEntriesController': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'defaultStockValidator'
You can try resolution:
Remove template extension ycommercewebservices extension from manifest.json, rebuild and redeploy with "Migrate Data" mode.
I have a Vue project generated by the Vue cli 3 and my hot reloading suddenly stopped working in my browsers. Changes made to the code are still picked up by the terminal, however, my browser is not picking up the changes. I have to manually refresh in order to pick up the new changes. As suggested by some others I manually set poll: true in my vue.config.js and I also tried to set the proxy, but both had no success.
Any suggestions to make this work again?
Update:
After some Vue updates, it suddenly started working again. I still don't know the reason for this. It might have been a bug in the vue-cli?
My problem was WDS
Console displayed:
[HMR] Waiting for update signal from WDS...
[WDS] Disconnected!
GET http://ip:port/sockjs-node/info?t=some-number
net::ERR_CONNECTION_TIMED_OUT sockjs.js?some-number
Solution for me was:
in
package.json
change
"serve": "vue-cli-service serve",
to
"serve": "vue-cli-service serve --host localhost",
or
add
module.exports = {
devServer: {
host: 'localhost'
}
}
to
vue.config.js
:)
HMR has problems in various environments, in those situations you can maybe help yourself with the poll option:
https://github.com/vuejs-templates/webpack/blob/develop/template/config/index.js#L21
var devMiddleware = require('webpack-dev-middleware')(compiler, {
publicPath: webpackConfig.output.publicPath,
stats: {
colors: true,
chunks: false
},
watchOptions: {
aggregateTimeout: 300,
poll: 1000
}
})
Seems I finally found it: my $cat /proc/sys/fs/inotify/max_user_watches was on 8192 and this helped me:
echo 100000 | sudo tee /proc/sys/fs/inotify/max_user_watches
Now Vue hot reload works without sudo and without poll ! ))))
One failure mode I've come across here is if you've managed to end up with multiple installations of webpack in your node_modules.
The reload relies on these two bits of code emitting events to each other:
webpack-dev-server/client/index.js
var hotEmitter = require('webpack/hot/emitter');
hotEmitter.emit('webpackHotUpdate', currentHash);
webpack/hot/dev-server.js
var hotEmitter = require("./emitter");
hotEmitter.on("webpackHotUpdate", function(currentHash) {
However, if you have multiple webpacks installed (e.g. a top-level one and one under #vue/cli-service) the require will resolve the first to ./node_modules/webpack/hot/emitter.js and the second to ./node_modules/#vue/cli-service/node_modules/webpack/hot/emitter.js which aren't the same object and so the listener never gets the event and reloads fail.
To resolve this I just uninstalled and reinstalled #vue/cli-service which seemed to clear the package-lock.json and resolve to the single top-level webpack.
I don't know if there's any way to ensure this doesn't happen -- however, it might be possible for vue-cli-3 to spot the situation and at least log a warning in dev mode?
[BTW adding devServer: { clientLogLevel: 'info' } } to vue.config.js was really helpful in debugging this.]
I faced the same issue (the console showed an error that said "[WDS] Disconnected") and here's what I did. Note that I was using the Vue UI tool for managing my project and I did not edit any config files.
Under Tasks/serve, I stopped the task.
I clicked the parameters button and in the input for "Specify host" label, I added the IP of my localhost i.e. 127.0.0.1 and in the input for "Specify port" label, I added 8080.
I saved the parameters and ran the server again from the tool.
Not sure why but this seemed to work for me. I'd love if someone can explain why it works.
I also have this WDS issue with each Vue project I make (kind of annoying, even with latest vue cli 4.5.0 and vue 2.6.11).
So the following solution is what I copy paste each and every time.
In vue.config.js file :
module.exports = {
devServer: {
// Fixing issue with WDS disconnected and sockjs network error
host: '0.0.0.0',
public: '0.0.0.0:8080',
disableHostCheck: true,
// End of fix
}
}
What was the cause in my case:
It seems that the value of: max_user_watches
in the /proc/sys/fs/inotify/max_user_watches
is affecting webpack => which is interfering with hot reloading.
To check your actual value
$cat /proc/sys/fs/inotify/max_user_watches
16384
16384 was in my case and it still wasnt enough.
I tried different type of solutions like:
$ echo fs.inotify.max_user_watches=100000 | sudo tee -a /etc/sysctl.conf
$ sudo sysctl -p
But it seems that even if I changed the value, when I restarted my PC it would go back to default one 16384.
SOLUTION if you have Linux OS(my case, I have Manjaro):
Create the file:
sudo nano /etc/sysctl.d/90-override.conf
And populate it with:
fs.inotify.max_user_watches=200000
It seems 200000 is enough for me.
After you create the file and add the value, just restart the PC and you should be ok.
Maybe this can help https://webpack.js.org/configuration/watch/#changes-seen-but-not-processed
"Verify that you have enough available watchers in your system. If this value is too low, the file watcher in Webpack won't recognize the changes:"
cat /proc/sys/fs/inotify/max_user_watches
"On macOS, folders can get corrupted in certain scenarios. See this article."
And in the link above you can check other known issues.
set NODE_ENV=development might solve your problem.
Adding NODE_ENV=development to your .env file will solve the problem.
I hope that this could be helping someone, I'd used of the terminal in my WebStorm and vue-cli-service didn't work, then I opened a normal terminal and that's it, maybe something in WebStorm didn't let the correct way in the vue-cli-service
I used proxy extension in my Firefox browser. Try turning that off if you have one
Please make sure you don't have any error in your code.
This happens usually because of error in any of our code files.
Just run
npm install -g #vue/cli-init
You can run vue-cli-service serve --public localhost
According the docs:
--public specify the public network URL for the HMR client
https://cli.vuejs.org/guide/cli-service.html#vue-cli-service-serve
This was my problem anyway, HMR was running on the network IP instead, for some reason. Causing CORS and connection refused issues.
For me More Tools >> Clear Browsing data in Chrome did the trick. Also try incognito before.
In Firefox everything was fine.
So before editing your vue.config.js take a look at the browsers.
I solved this problem by changing the versions of my dependencies and devDependencies:
"dependencies": {
"core-js": "^3.4.4",
"vue": "^2.6.10",
},
"devDependencies": {
"#vue/cli-plugin-babel": "~4.1.0",
"#vue/cli-plugin-eslint": "~4.1.0",
"#vue/cli-service": "~4.1.0",
"babel-eslint": "^10.0.3",
"eslint": "^5.16.0",
"eslint-plugin-vue": "^5.0.0",
"vue-template-compiler": "^2.6.10"
},
This is my first question here. I have already spent hours reading topics, but never posted a question before.
At this moment I am developping an Angular4 application. I am running my app with "ng build --watch" and a local PHP webserver pointed to the 'dist' folder of my angular app. (When using build-in liveload server 'ng serve' there isn't a PHP server available, so i fixed this with 'ng build --watch' and a local PHP build-in server of PHPStorm)
To communicate with my MYSQL database, I used before single-php files in a directory called '/api'. I added this folder to my assets in the angular-cli.json file, so the API folder is also being pushed to the 'dist' folder when running the app local.
In this case, I was able to use relative paths to point my http requests. (like a POST action to '/api/insert.php'). So when publishing my app, it was not necessary to modify the paths of my HTTP requests.
But now I would like to use a backend framework, after some research I found http://api-platform.com, a PHP framework builded on Symfony3. When i am running this API, this runs for example on localhost:8000 while my angular applciation runs on localhost:4200.
So, that means i would have to use absolute paths for my HTTP requests. (eq http://localhost:8000/api/insert.php instead of /api/insert.php).
At this moment I have 2 projects: one front-end and one back-end. To make developping faster, easier, and simpler I would like to put both projects together. I know some developpers don't like this way of architecture, but in my case it is the best solution, one project, with a front and back-end included.
Concrete: Is it possible to run a debug-webserver in development zone with my angular app running on eq localhost and my symfony3/api-platform on eq localhost/api on the same time, same domain, and same port?
I would like to keep this project folder structure to keep it clean:
- projectname (root)
--- frontend
----- (all directories/files from angular)
--- backend
----- (all directories from api-platform / symfony3)
Sincerely,
Lander
running both application on the same domain (f.ex. localhost) is no problem, but they need to run on different ports. In your case angular is running on 4200 and your PHP application on 8000. You can configure angular with a proxy, which passes requests to http://localhost:4200/api to http://localhost:8000/api
In your angular root directory (where your package.json is), create a file proxy.conf.json
{
"/api": {
"target": "http://localhost:8000",
"secure": false
}
}
then change your package.json to use this proxy:
"scripts": {
"ng": "ng",
"start": "ng serve --proxy-config proxy.conf.json",
// other scripts
}
now run the webpack server with npm start instead of ng serve
Personally, I git ignore the proxy.conf.json, because some colleagues run their backend on a different port. Therefore we created a proxy.conf.dist.json with the above contents in git. If you want to use a different port, you can just copy it and change the port, while those, who want to use the default, can simply symlink to it.
UPDATE:
We recently switched to another method, namely using environment configurations.
By default, Angular has a dev and prod environment, specified in the .angular-cli.json
"environments": {
"dev": "environments/environment.ts",
"prod": "environments/environment.prod.ts"
}
In these files, specify the API path:
environment.ts
export const environment = {
production: false,
apiUrl: '//localhost:8000'
};
environment.prod.ts
export const environment = {
production: true,
apiUrl: '//my-api-domain.tld'
};
You can add as many environments as you want (f.ex. for tests, beta, etc.). In angular, you can use the environment by importing it:
import {environment} from '../environments/environment';
But I suggest creating a config service following this answer: https://stackoverflow.com/a/43193574/7933618
I ended up by using another backend. In my case an nodeJS server was the best, fast and most simple solution.
I'm attempting to use the spine.app cli and I'm encountering a couple of errors and I'm uncertain what the root cause actually is.
The guide found at: http://spinejs.com/docs/started gives these steps
spine app my-app
cd my-app
npm install .
hem server
following these steps, initially yields this error on the terminal:
Cannot find module: es5-shimify. Have you run `npm install .` ?
Investigating, it seems es5-shimify has been deprecated in favor of es5-shim, so my initial inclination was to replace the dependency to es5-shim. So I updated setup.coffee to require('es5-shim'), and I updated the referenced slug.json module and restarted the server. This seems to get me a little further, but still produces an error ( though not in the terminal, instead in the chrome console )
Uncaught TypeError: Property 'jQuery' of object [object Object] is not a function
This appears to be occurring on line 8 of public/index.html. I did some debugging here and it appears that require('jqueryify') is returning undefined, and I'm not certain what the expected result is. Any guidance on the right way to approach this process or perhaps information on what the root issue might be would be greatly appreciated.
Use the latest version try again.
The package.json as following
{
"name": "app",
"version": "0.0.1",
"dependencies": {
"spine": "~1.3.0"
}
}
all others dependencies has been removed,and it works for me.