19

I recently switched over to grunt 0.4.5 and it changed how connect works.

I previously used connect-modrewrite and it worked pretty well (had some issues with urls generated by /:parameter).

Here is the old version that worked with grunt 0.4.1 from generator-angular 0.8.0 with the middleware part modded by me to use html5mode.

connect: { options: { port: 9000, hostname: '*IP HERE*', livereload: 35729, middleware: function (connect, options) { var optBase = (typeof options.base === 'string') ? [options.base] : options.base; return [require('connect-modrewrite')(['!(\\..+)$ / [L]'])].concat( optBase.map(function(path){ return connect.static(path); }) ); } }, livereload: { options: { open: true, base: [ '.tmp', '<%= yeoman.app %>' ] } }, 

Here is the new version from generator-angular 0.9.0-1

connect: { options: { port: 9000, hostname: '*IP HERE*', livereload: 35729 }, livereload: { options: { open: true, middleware: function (connect) { return [ connect.static('.tmp'), connect().use( '/bower_components', connect.static('./bower_components') ), connect.static(appConfig.app) ]; } } }, 

How can I change this to use mod-rewrite or any other method to achieve html5mode?

I tried using the method provided here: https://gist.github.com/nnarhinen/7719157 I combined it to create the following:

middleware: function (connect) { return [ connect.static(modRewrite(['^[^\\.]*$ /index.html [L]'])), connect.static('.tmp'), connect().use( '/bower_components', connect.static('./bower_components') ), connect.static(appConfig.app) ]; } 

This allows me to view the normal view, but the modRewrite part does not seem to do what it needs to in order to get to any other view via url.

1
  • Strange, I'm currently using grunt 0.4.5 and the middleware worked fine. I tried a number of different implementations and this was the only one that worked with a 'base' option. Commented Mar 2, 2015 at 1:55

4 Answers 4

64

If anyone else stumbles across this here is the fix:

(the only line added was the modRewrite line)

livereload: { options: { open: true, middleware: function (connect) { return [ modRewrite(['^[^\\.]*$ /index.html [L]']), connect.static('.tmp'), connect().use( '/bower_components', connect.static('./bower_components') ), connect.static(appConfig.app) ]; } } }, 

Make sure you have the following declared at the top of your grunt file:

var modRewrite = require('connect-modrewrite'); 
Sign up to request clarification or add additional context in comments.

6 Comments

also make sure connect-modrewrite is installed npm install connect-modrewrite --save-dev
Thanks!! there is a lot of articles explaining this for old versions. I tested around 5 different ways already without success. I tested this solution and works perfectly.
@Kryx what about support for an alternative base?
@EvanPlaice No idea how that interacts with this at all.
I followed this approach but still have issues with /:params. The url to load main.css is getting prefixed with current url instead of base path. It is like localhost:9000/mypage/styles/main.css (failed to load 404) instead of localhost:9000/styles/main.css.
|
7

Given how other answers are pretty verbose and don't preserve default grunt-contrib-connect middlewares, I came up with solution that uses dedicated middleware – connect-history-api-fallback:

npm install connect-history-api-fallback --save-dev 
var history = require('connect-history-api-fallback') //... connect: { options: { middleware: function(connect, options, middleware) { middleware.unshift(history()) return middleware }, //... }, //... } 

Comments

3

Though above accepted answer is correct. Im adding the config which I use, it works perfectly on CentOs.

Below 1 to 3 steps are for making Angularjs clean URL work in your local machine using $ grunt serve

But if you want to make them run fine on Server, specially nginx you will also need to update nginx config. (step 4)

  1. $ npm install connect-modrewrite --save

  2. Edit your gruntfile.js. Add at the top of the file

    var modRewrite = require('connect-modrewrite'); 

Then in your middleware:

middleware: function (connect) { return [ modRewrite(['^[^\\.]*$ /index.html [L]']), connect.static('.tmp'), connect().use('/bower_components', connect.static('./bower_components')), connect.static(config.app) ]; } 

for e.g.

// Generated on 2015-11-09 using generator-angular 0.14.0 'use strict'; // # Globbing // for performance reasons we're only matching one level down: // 'test/spec/{,*/}*.js' // use this if you want to recursively match all subfolders: // 'test/spec/**/*.js' var modRewrite = require('connect-modrewrite'); module.exports = function (grunt) { // Time how long tasks take. Can help when optimizing build times require('time-grunt')(grunt); 

3.Then go to Livereload middleware, add modRewrite

livereload: { options: { middleware: function (connect) { return [ modRewrite([ '^[^\\.]*$ /index.html [L]' ]), connect.static('.tmp'), connect().use('/bower_components', connect.static('./bower_components')), connect.static(config.app) ]; } } }, 

4.Edit NGINX config:

server { server_name yoursite.com; root /usr/share/html; index index.html; location / { try_files $uri $uri/ /index.html; } } 

Hope it helps :)

Comments

1

Here is my solution, adapted to generator-angular setup, but can be used anywhere. It allows a rewriting syntax (the interesting part is the example livereload configuarion).

connect: { options: { port: 9000, // Change this to '0.0.0.0' to access the server from outside. hostname: 'localhost', livereload: 35729, // Modrewrite rule, connect.static(path) for each path in target's base middleware: function (connect, options) { var optBase = (typeof options.base === 'string') ? [options.base] : options.base, middleware = [require('connect-modrewrite')(['!(\\..+)$ / [L]'])] .concat(optBase.map(function (path) { if (path.indexOf('rewrite|') === -1) { return connect.static(path); } else { path = path.replace(/\\/g, '/').split('|'); return connect().use(path[1], connect.static(path[2])) } })); return middleware; } }, livereload: { options: { open: true, base: [ '.tmp', 'rewrite|/bower_components|./bower_components', 'rewrite|/app/styles|./app/styles', // for sourcemaps '<%= yeoman.app %>' ] } } } 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.