Can't change the base folder for lite-server in Angular 2 application - node.js

I am going through the 5 minute quickstart of Angular 2. However, my application resides in src/ folder instead of at the root of my repository, and when I run npm start the application is trying to find an index.html file at the root. I read up on lite-server and documentation shows that it uses BrowserSync and I can reconfigure BrowserSync with a bs-config.json in my repository. I did that and this is what my config looks like:
{
"port": 8123,
"server": { "baseDir": "./src" }
}
According to the log it's using the specified config:
[1] > todo-app-angular2#1.0.0 lite E:\GitHub\todo-app-angular2
[1] > lite-server "./bs-config.json"
I also tried an override through bs-config.js
module.exports = {
port: 8123,
server: {
baseDir: "./src"
}
};
However the Angular application is still opened on port 3000 and it's disregarding the baseDir defined in the config. What am I doing wrong?

You should use a file called bs-config.js (instead of a bs-config.json one) since lite-server tries to load a module using the require function. The configuration should be a valid Node module:
module.exports = {
"port": 8123,
"server": { "baseDir": "./src" }
};
See this line in the source code: https://github.com/johnpapa/lite-server/blob/master/lib/lite-server.js#L20.
This file by default is loaded from the user's project folder.
Edit
After digging a bit more, the first part of my answer relies on the code from github but not the one actually installed using npm install (version 1.3.4)
There are two options in this case:
port
baseDir
Using this command will fix your problem:
$ lite-server --baseDir ./src --port 3333
Hope it helps you,
Thierry

The answer from Thierry Templier is not quite correct (anymore), you can use either the bs-config.json or bs-config.js configuration to adjust your browser-sync configuration. This is what I came up initially for the angular2 quick start example with JIT(Just-In-Time) and AOT(Ahead-Of-Time) compilation support (bs-config.json)
{
"port": 8000,
"server": ["app", "."]
}
to host the project from multiple directories.
However, I did not like this solution because by overwriting the server section in the json file, the default middleware configuration was overwritten at the same time.
Therefore I ended with the following approach, I took the default lite-server's config-defaults.js files and modified it instead (bs-config.js):
'use strict';
var fallback = require('connect-history-api-fallback');
var log = require('connect-logger');
/*
| For up-to-date information about the options:
| http://www.browsersync.io/docs/options/
*/
module.exports = {
port: 8000,
injectChanges: false, // workaround for Angular 2 styleUrls loading
filters: ['./**/*.{html,htm,css,js}'],
watchOptions: {
ignored: 'node_modules'
},
server: ['./', 'app'],
middleware: [
log({ format: '%date %status %method %url' }),
fallback({
index: '/index.html',
htmlAcceptHeaders: ['text/html', 'application/xhtml+xml'] // systemjs workaround
})
]
};

Related

vercel not running build and instal commands and not creating Serverless functions

I am trying to move my application's API to Vercel. It is written in Typescript and uses Express.
The index.ts is located in <root>/src. The npm run build compiles it into <root>/dist directory. The file contains the following:
const app = express();
app.use((req: Request, res: Response, next: NextFunction) => {
//blah, blah, there is a lot going on here
})
app.use('/', common);
//... other app.use(s)
const port = process.env.PORT || 5000;
app.listen(port, () => console.log(`Server running on ${port}, http://localhost:${port}`));
module.exports = app;
I've got the following in the vercel.json file which is located in the root directory where the package.json also is:
{
"version": 2,
"installCommand": "npm install",
"buildCommand": "npm run build",
"outputDirectory": "dist",
"builds": [
{
"src": "dist/index.js",
"use": "#vercel/node"
}
],
"routes": [
{
"src": "/(.*)",
"dest": "dist/index.js"
}
]
}
When locally I run npm run build, then vercel dev --listen 5000 I get Ready! Available at http://localhost:5000 and can go to http://localhost:5000/ping and get a response.
Now I commit the files to git, the deployment runs, but judging by the logs the npm install and npm run build commands are not running. No functions are created my /ping endpoint returns "Page not found".
Here is the deployment log:
This is what Build & Development Settings look like (the Root Directory is left blank):
I followed several recommendations I found online and according to them everything should work. I probably miss some setting somewhere. What is it?
If more information is needed, please let me know, I'll update my question.
Thank you.
--- UPDATE ---
I have set the Root Directory to src and checked the "Include source files outside of the Root Directory in the Build Step" checkbox. Now the npm install and npm run build are executing. As you can see some static files are deployed, but there are still no serverless functions and my /ping route returns 404 and "home" page, i.e. / route returns the content of the index.js file. In addition the local is not working either anymore, also returning 404 now.
Without that checkbox I was getting
Warning: The vercel.json file should exist inside the provided root directory
and still no install or build running.
Also worth noting that I had to change my tsconfig.json to have "outDir": "src/dist" instead of "outDir": "dist", otherwise I was getting
Error: No Output Directory named "dist" found after the Build completed. You can configure the Output Directory in your Project Settings.
Removed the Root directory and back to square one, no npm commands running but local is working with / route returning Cannot GET / and /ping returning correct response.
For everyone out there who's looking for an answer, maybe this will help you.
In my case, what I needed is to create a folder, called api in my src folder, i.e. the folder that is specified as Root Directory in Build & Development Settings in Vercel. Within this directory, each serverless function needs a file named the same as the path of the route. For example, the file named "my-route.js" will be accessible via https://my-app-name.vercel.com/api/my-route.
All this file needs is an import of index.js file and module.exports. For example:
import app from '../index';
module.exports = app;
The index.js should also live the Root and contain your express setup.
If you want to have dynamic path parameters, the files' names in the api directory should be wrapped in square brakets, like [my-param.js]. You can also have sub-directories in the api foler.
Here are a few links that helped me figure this out:
https://dev.to/andrewbaisden/how-to-deploy-a-node-express-app-to-vercel-2aa
https://medium.com/geekculture/deploy-express-project-with-multiple-routes-to-vercel-as-multiple-serverless-functions-567c6ea9eb36
https://ryanccn.dev/posts/vercel-framework/#path-segments
No changes were needed in my existing Express setup and routes files.
Hope this will help someone. Took me quite a while to figure it all out :)

Angular 5 and Wordpress

I am attempting to setup a project that uses both Angular 5 and Wordpress. Currently my solution allows the serving of both applications using node. From the root directory I run "node index.js" to run wordpress, and in a separate terminal, in a subdirectory I run "ng serve" to run the angular implementation.
Is it possible to run both angular and wordpress on the same terminal window? An example being, by typing "node index.js" in the root directory, can I serve both the angular application in a subdirectory and the wordpress through that one console?
My projects are pretty bare but here is some base code:
/index.js
const express = require('express')
const epf = require('express-php-fpm')
const options = {
// root of your php files
documentRoot: __dirname + '/wordpress',
// extra env variables
env: {},
// connection to your php-fpm server
// https://nodejs.org/api/net.html#net_socket_connect_options_connectlistener
socketOptions: { port: 9000 },
}
const app = express()
app.use('/', epf(options))
app.listen(3000)
/subproject/protractor.conf.js
// Protractor configuration file, see link for more information
// https://github.com/angular/protractor/blob/master/lib/config.ts
const { SpecReporter } = require('jasmine-spec-reporter');
exports.config = {
allScriptsTimeout: 11000,
specs: [
'./e2e/**/*.e2e-spec.ts'
],
capabilities: {
'browserName': 'chrome'
},
directConnect: true,
baseUrl: 'http://localhost:4200/',
framework: 'jasmine',
jasmineNodeOpts: {
showColors: true,
defaultTimeoutInterval: 30000,
print: function() {}
},
onPrepare() {
require('ts-node').register({
project: 'e2e/tsconfig.e2e.json'
});
jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } }));
}
};
Thank you.
I am working on a new plugin, Xo for Angular that may provide a solve for the use case above.
https://wordpress.org/plugins/xo-for-angular/
Xo gives you the option to load an Angular App as a theme with WordPress serving only as the management interface. Routes can be generated dynamically so all pages and posts are instantly viewable on the front-end without needing to recompile.
For local development I recommend setting up either apache or nginx using a tool like XAMPP. I have detailed the setup I use for my own local development here: https://github.com/WarriorRocker/angular-xo-material
Once you have wordpress running through a server like apache you can then just run ng build and let Xo load your App/theme through the main front-end. Alternatively you can also run with ng serve for rapid development.
In production you can either have Xo load your App and inject wp_head/wp_footer as necessary (Live Redirect Mode) or redirect all front-end requests to your App's dist index.html (Offline Redirect Mode).
Additional docs (work in progress): https://angularxo.io/

How to resolve invalid host header issue in webpack?

I'm getting invalid host header error, if i access my page through browser with online ip. Locally it is working perfectly, but i don't know why this error is coming in live server. I'm following three steps to run my react js application, that is,
'npm install'
'npm run build'
'npm run serve'
webpack config file host setup
// replace localhost with 0.0.0.0 if you want to access
// your app from wifi or a virtual machine
const host = process.env.HOST || '0.0.0.0';
const port = process.env.PORT || 3000;
const stats = {
hash: false,
version: false,
timings: false,
assets: false,
chunks: false,
modules: false,
reasons: false,
children: false,
source: false,
errors: false,
errorDetails: false,
warnings: false,
publicPath: false,
colors: {
green: '\u001b[32m',
},
};
package.json scripts
"build": "rimraf build && cross-env NODE_ENV=production webpack --env.prod=true --env.sw=true",
"serve": "pushstate-server build/ 3000",
Webpack dev server has recently had a host check added by default as a security measure https://github.com/webpack/webpack-dev-server/releases/tag/v2.4.3
You will now need to either disable it via disableHostCheck option (not wise if publicly accessible) or specify the public host or IP that you will be accessing it at when starting the server --public your-hostname-or-public-ip:3000
EDIT: Webpack in question name and webpack-dev-server tag was misleading - this actually uses different server altogether...
Ah it looks like this is not actually webpack related at all - you are using a different server pushstate-server which strangely has the host option in the module, but is not exposed in the binary. You will have to roll your own server startup script to pass a different host to it (it is 0.0.0.0 by default).
Save this to ./server.sh
#!/usr/bin/env node
require('pushstate-server').start({
directory: process.argv[2],
port: process.argv[3],
file: process.argv[4],
host: process.argv[5]
}, (err, address) =>
console.log(`Listening on port ${address.port} (http://${address.address}:${address.port})`)
)`
Change your npm script change to
server.sh build/ 3000 index.html your-publicly-accessible-hostname
I had the same error when I came across to these:
https://help.crossbrowsertesting.com/faqs/testing/invalid-host-header-error/
In my case it was solved by restarting the service.

React UI and Node.js/Express app served/monitored with webpack

I am new to React and Node, trying to setup an environment to work.
I worked a little with Node.js/Express before and I used nodemon to monitor file changes and restart my app.
Also I recently started to work with React and I use webpack dev server (specifically webpack-dev-server --content-base src --inline --hot --history-api-fallback) setup that monitors file changes and reload the UI.
The problem
Now, I want to tie it together.
First solution I found was: Start my node app on specific port, say 3000 then start webpack dev server on 8080 port and proxy requests to specific urls to my backend app.
devServer: {
proxy: {
'/backend-api/': {
target: {
"host": "localhost",
"protocol": 'http:',
"port": 3000
},
ignorePath: false,
changeOrigin: true,
secure: false
}
}
},
It should work but i do not feel right starting two servers for single application.
Is there any way (and simple example i could understand) to start single server that would serve both: a server side app and React UI?
And of course, it should track file changes and restart server app if server code changes OR reload UI if client side code changes.
You can use webpack through Express middleware using this package: https://github.com/webpack/webpack-dev-middleware
You can use it by simply adding it to the app:
var webpackMiddleware = require("webpack-dev-middleware");
app.use(webpackMiddleware(webpack({/* webpack options */})));
In addition there's a package that builds on this to offer hotloading and "Create React App" style terminal display: https://www.npmjs.com/package/webpack-express-middleware

Gulp: Trouble setting browserSync and Watch

I'm learning Gulp and NPM and decided to test myself by using Browser-Sync with a PHP project I'm working on (using XAMPP). I know Browser-Sync doesnt work with PHP files, but I wanted to use it with my .css files (and later on perhaps add Sass).
I installed npm, Gulp, Gulp-watch and Browser Sync to my project's root directory and all seemed fine.
I then created a gulp.js file with the following:
var gulp = require('gulp'),
watch = require('gulp-watch'),
browserSync = require('browser-sync').create();
gulp.task('watch', function() {
browserSync.init({
server: {
baseDir: "./"
}
});
watch('css/*.css', function() {
browserSync.reload();
});
});
However, when I gulp watch a new browser window does open but just shows the Cannot GET / error.
Also, the URL shows http://localhost:3002/ rather than http://localhost:myproejct
I read this may have something to do with my baseDir so tried:
baseDir: ""
baseDir: "./"
baseDir: "../myproject"
Would anyone know what I've done wrong?
You are doing way more than is necessary to do what you want. You can just use browsersync as a proxy layer over the top of your hosted site.
See the following example from the docs
# Proxy a PHP app + serve static files & watch them
$ browser-sync start --proxy 'mylocal.dev' --serveStatic 'public' --files 'public'
I think this is what you will need, run it from the physical root of your site and replace mylocal.dev with your php server address
npm install browser-sync -g
browser-sync start --proxy 'mylocal.dev' --serveStatic 'css' --files 'css/*.css'
Your code works fine for me. Assuming your target HTML file works if opened in the browser manually: One common cause of the Cannot Get/ error is using an index file other than Browsersync's default expectation, index.html. Could that be the problem you're having? If you need a custom index file, you can set the index option:
browserSync.init({
server: {
baseDir: 'mybasedirectorypath',
index: 'notindex.html'
}
});
Fwiw, you can also do this more efficiently, and save yourself the weight of installing gulp-watch (this example adapted and simplified from this Browsersync docs example):
var gulp = require('gulp'),
browserSync = require('browser-sync').create();
gulp.task('watch', function() {
browserSync.init({
server: {
baseDir: './'
}
});
gulp.watch('css/*.css').on('change',browserSync.reload)
});
As for using a custom url, check out https://github.com/BrowserSync/browser-sync/issues/646 which has some solutions.

Resources