generator-angular icon indicating copy to clipboard operation
generator-angular copied to clipboard

Option to change 'scripts/' (ex. to '/scripts/') when generator adds script tags to index.html

Open jjt opened this issue 10 years ago • 14 comments

I'm using html5mode and server rewrites to get rid of the hashbang, leaving me with urls like http://site.local/foo/bar instead of http://site.local/#!/foo/bar. This works on page refresh, even for deep links.

The problem is that generator-angular adds scripts to index.html with a relative url, like src="scripts/path/to/script.js". So when a user refreshes on the page /foo/bar, the browser looks for that js file at /foo/bar/scripts/path/to/script.js, which doesn't exist.

Right now what I do is manually add the leading slash in index.html every time I generate something new, but that's less than optimal. Is there a good way that I could configure the scripts path to insert into index.html?

edit: clarified title, hopefully

jjt avatar Nov 05 '13 06:11 jjt

this is a known (non-)issue. You need to setup your server to do a mod-rewrite to the index.html. But yeah, I reference everything absolutely in my app. Someday I'll look at merging my setup with the generator to see what people think

eddiemonge avatar Nov 05 '13 14:11 eddiemonge

I do have my server set up to do a mod-rewrite to index.html. /foo/bar/ gets served index.html, just the same as /.

The problem is that all of the <script src="scripts/..."> tags that the generator inserts into index.html are hardcoded to the relative path scripts/, with no apparent option to change. It's a minor annoyance, but one that should be easy to overcome.

I don't have a deep knowledge of the codebase, but some searching brings me to a likely candidate at L100 of script-base.js:

Generator.prototype.addScriptToIndex = function (script) {
  //...
      splicable: [
        '<script src="scripts/' + script + '.js"></script>'
      ]

Seems like that script tag could be made into something like:

'<script src="' + scriptsPath + script + '.js"></script>'

jjt avatar Nov 05 '13 20:11 jjt

what is your rewrite rule because i setup apache with relative urls and it seems to work fine.

here is my rewrite rule:

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_URI} !index
    RewriteRule (.*) index.html [L]
</IfModule>

eddiemonge avatar Nov 05 '13 21:11 eddiemonge

I think we've got a crossed wire in our comments here. Let me see if I can clear it up with an example of our app which has html5mode enabled, running on your apache server.

  1. We ran yo angular:controller fooBar, which created /app/scripts/controllers/fooBar.js, and added <script src="scripts/controllers/fooBar.js"></script> to index.html
  2. Go to our browser, hit http://mysite.local/foo/bar (assume we have proper routing for this)
  3. Rewrite rule serves it index.html, everything is good here
  4. index.html has the following script tag in the head: <script src="scripts/controllers/fooBar.js"></script>
  5. Browser sees the relative src url and tries to load http://mysite.local/foo/bar/scripts/controllers/fooBar.js
  6. This file doesn't exist, so it 404s and our app barfs

So, we could add another rewrite rule that handles this, like ^(.+)/scripts/(.*)$ scripts/$1. But that seems like the wrong way to solve the problem, requiring configuration outside of our project. A better solution (IMO) would be an option so generator-angular makes this:

<script src="/scripts/controllers/fooBar.js">

Instead of this:

<script src="scripts/controllers/fooBar.js">

TL;DR It's not the problem of modrewriting to index.html - I've already solved that.

jjt avatar Nov 05 '13 22:11 jjt

This is also a problem for other static assets like css.

I think generator-angular needs an html5mode option. I'll open a new issue for it.

jjt avatar Nov 05 '13 23:11 jjt

I forgot I had my dev server set to do something different. You are right on the refresh though. The easiest solution for that is: http://stackoverflow.com/questions/12858859/routing-in-subdirectory-in-angular-js tl;dr:

eddiemonge avatar Nov 06 '13 00:11 eddiemonge

Huh, yeah the base tag could work for my current project. I don't like that it makes every url on the page an absolute url, and also makes # redirect to /.

jjt avatar Nov 06 '13 00:11 jjt

do you have # links? why?

eddiemonge avatar Nov 06 '13 00:11 eddiemonge

I don't. And I don't think I have any relative links either.

It would be better to not put those restrictions on other users though, even if they wouldn't ordinarily come up in idiomatic Angular.

jjt avatar Nov 06 '13 00:11 jjt

I referenced this in #433, but any relative anchor link will break when using the <base> tag. For example, the table of contents on the Wikipedia article for Computer. Most ToCs work this way, using relative anchor links like <a href="#my-anchor">.

This is such a common pattern as to make <base> a limited solution, and shouldn't be implemented in this generator IMO.

jjt avatar Nov 07 '13 21:11 jjt

there is http://docs.angularjs.org/api/ng.$anchorScroll for such situations

eddiemonge avatar Nov 07 '13 21:11 eddiemonge

Hmm. Well, if the idiomatic way is with anchorScroll, then I guess the generator should enforce that. I'm always on the fence about opinionated choices like this though.

Funny that the demo on the docs site doesn't work.

jjt avatar Nov 07 '13 21:11 jjt

it doesnt but if you edit in plunkr it does. didnt want to try troubleshooting that at the moment

eddiemonge avatar Nov 07 '13 22:11 eddiemonge

again this should be a reference in https://github.com/eddiemonge/generator-angular-api

eddiemonge avatar Nov 19 '13 18:11 eddiemonge