Pretty URLs with Node.js/Gulp using .htaccess? - node.js

I am deploying a static website with remote shared hosting. Each page has a .html extension, which I wanted to remove from the URLs to make them prettier.
So I added the following .htaccess file to the root of the website directory on the hosting server:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.html [NC,L]
This works perfectly on the hosting website, i.e. when I type in the url mywebsite.com/page, the server displays mywebsite.com/page.html without showing it in the URL.
The problem I have is that I am developing the website using Gulp with LiveReload. This is my gulpfile.js:
var gulp = require('gulp');
var browserSync = require('browser-sync').create();
var pkg = require('./package.json');
// Copy vendor files from /node_modules into /vendor
// NOTE: requires `npm install` before running!
gulp.task('copy', function() {
gulp.src([
'node_modules/bootstrap/dist/**/*',
'!**/npm.js',
'!**/bootstrap-theme.*',
'!**/*.map'
])
.pipe(gulp.dest('vendor/bootstrap'))
gulp.src(['node_modules/jquery/dist/jquery.js', 'node_modules/jquery/dist/jquery.min.js'])
.pipe(gulp.dest('vendor/jquery'))
gulp.src(['node_modules/popper.js/dist/umd/popper.js', 'node_modules/popper.js/dist/umd/popper.min.js'])
.pipe(gulp.dest('vendor/popper'))
gulp.src(['node_modules/jquery.easing/*.js'])
.pipe(gulp.dest('vendor/jquery-easing'))
})
// Default task
gulp.task('default', ['copy']);
// Configure the browserSync task
gulp.task('browserSync', function() {
browserSync.init({
server: {
baseDir: ''
},
notify: false
})
})
// Dev task with browserSync
gulp.task('dev', ['browserSync'], function() {
// Reloads the browser whenever HTML or CSS files change
gulp.watch('css/*.css', browserSync.reload);
gulp.watch('js/*.js', browserSync.reload);
gulp.watch('*.html', browserSync.reload);
});
Now, when I launch the development environment with gulp dev, all links that point to mywebsite.com/page are broken. So the Gulp development server does not append .html to the URLs like my hosting server does.
Is there any way to modify the development environment so the prettified URLs also work when I use gulp dev?

This can be done easily (without MAMP or mod_rewrite) using BrowserSync Options:
server: {
baseDir: "app",
routes: {
"/some_page": "app/some_page.html"
}
}
Found here.

Related

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/

Using Gulp's browser-sync with MAMP in localhost testing environment

I have searched around but no posts pinpointed the pitholes to avoid when using Gulp's BrowserSync with a localhost testing environment. So here is this post.
I am using gulp browser-sync, doing testing with MAMP. Right now I cannot get my browser-sync watch to work. I want to reload browser whenever I save my files.
Under MAMP settings,
Apache port: 80
Nginx port: 80
MySQL port: 3306
gulpfile.js
var gulp = require('gulp');
var browserSync = require('browser-sync'); // create a browser sync instance.
//tasks for development
// Start browserSync server
gulp.task('browserSync', function() {
browserSync({
server: {
baseDir: "app"
},
proxy: "localhost:8080" // can be [virtual host, sub-directory, localhost with port]
});
gulp.task('watch', ['browserSync'], function () {
gulp.watch('app/*.{php,css,js}', browserSync.reload);
});
Since we are talking about MAMP here, my directory is in htdocs/test as shown below:
Also, my index.php file is inside /app
I am thinking I have made mistakes on many levels but right now any combination of my solutions doesnt seem to help and Ive spent hours on this. Any suggestions?
Finally got it to work.
var gulp = require('gulp');
var browserSync = require('browser-sync').create();
gulp.task('default', function() {
browserSync.init({
proxy: "http://localhost/test/app"
});
gulp.watch("./app/*.php").on("change", browserSync.reload);
});
Few things to look out for that the documentation might not explicitly mention:
Do not miss out .create and .init() as we are referring to an instance here.
If you are using some test local server like MAMP, be careful to use 'proxy' instead of 'server'.
Note the URL address I am using refers to the position of the index.php
Lastly, '.on("change", browserSync.reload)' to RELOAD on CHANGE.
Hope my day spent on this saved you some time.
I was struggling with this and found an updated solution that works w/ both MAMP and custom local dev proxies.
In the gulpfile.js gulp.task( 'browser-sync', function() block I removed:
browserSync.init( cfg.browserSyncWatchFiles, cfg.browserSyncOptions );
and replaced with
browserSync.init({
proxy: "your/local/dev/url/here"
});
Hope that saves someone some time!

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.

browser sync with ejs, the proxy just loads

I'm trying to get my MEAN application to work with browser sync.
I'm using .ejs file as template, but whenever I click to open the index.ejs file it downloads it.
I tried this two settings in my gulpfile, but none of them works.
//this downloads the ejs file
gulp.task('serve', function () {
browsersync.init({
server: {
baseDir: [''],
directory: true
}
});
});
//this just loads and I can't access localhost
gulp.task('serve', function () {
browsersync.init({
proxy: 'http://localhost:3000'
});
});
there is a npm package called browser-sync-ejs, but the documentation is non existent and I have no idea how to use it.

Unable to get connect-livereload to work with express server in gulp task

I am working off of Yeoman's gulp-webapp generator. I have modified my gulp serve task to use my Express server, rather than the default connect server it ships with. My issue is with Livereload functionality. I am trying to simply port the connect-livereload to work with my Express server rather than having to install new dependencies. It's to my understanding that most connect middleware should work fine with Express, so I am assuming connect livereload is compatible with Express 4.
Here are the contents of the relevant tasks in my gulpfile:
gulp.task('express', function() {
var serveStatic = require('serve-static');
var app = require('./server/app');
app.use(require('connect-livereload')({port: 35729}))
.use(serveStatic('.tmp'));
app.listen(3000);
});
gulp.task('watch', ['express'], function () {
$.livereload.listen();
// watch for changes
gulp.watch([
'app/*.ejs',
'.tmp/styles/**/*.css',
'app/scripts/**/*.js',
'app/images/**/*'
]).on('change', $.livereload.changed);
gulp.watch('app/styles/**/*.css', ['styles']);
gulp.watch('bower.json', ['wiredep']);
});
gulp.task('styles', function () {
return gulp.src('app/styles/main.css')
.pipe($.autoprefixer({browsers: ['last 1 version']}))
.pipe(gulp.dest('.tmp/styles'));
});
gulp.task('serve', ['express', 'watch'], function () {
require('opn')('http://localhost:3000');
});
With this simple setup, when I run gulp serve in my cmd everything spins up fine and I can accept requests at http://localhost:3000.
Now if I go and change the body's background color from #fafafa to #f00 in main.css and hit save, my gulp output will respond with main.css was reloaded, as seen in the bottom of this screenshot.
However, my webpage does not update. The background color is still light-grey instead of red.
Is there perhaps a conflict between my express server config and the way gulp handles its files? Is my Express server forcing the use of app/styles/main.css rather than the use of .tmp/styles/main.css? Shouldn't the livereload script handle the injection of the new temporary file?
Thanks for any help.
EDIT:
I was able to move forward a bit by adding livereload.js to the script block of my index file, like so:
<script src="http://localhost:35729/livereload.js"></script>
I am now able to get live changes pushed to the client. Why was this file not getting injected before? How can I ensure this is getting used programatically as opposed to pasting it into my files?
I was able to get past this issue by removing the app.use(require('connect-livereload')({port: 35729})) from my gulpfile, along with a couple of other lines, and having that instantiate in my Express server's app.js file.
My gulpfile's express task now looks like this:
gulp.task('express', function() {
var app = require('./server/app');
app.listen(3000);
});
I added in the connect-livereload just above where I specify my static directory in Express:
if (app.get('env') === 'development') {
app.use(require('connect-livereload')());
}
app.use(express.static(path.join(__dirname, '../app')));
Once I started using this setup, I was getting the livereload.js script injected into my document, and client-side changes are now auto-refreshed just how I wanted.
Hope this helps someone!

Resources