I've got a little project in Angular. I'm trying to keep everything in the Single Responsibility way and
I'm quite happy with me app structure. The only think I feel is not looking very good is index.html. All js files are included on
the bottom of the file and I do not like the look of it. I'm adding more files (controllers, services, etc) as I go and the list
could grow quite long.
So my question is: Is it normal,that the index file includes all these or is there way to move all these in a single file and reference that in the index.html?
<html>
<head>
...
</head>
<body>
...
...
<script src="assets/js/angular.js"></script>
<script src="assets/js/angular-route.js"></script>
<script src="assets/js/angular-touch.js"></script>
<script src="assets/js/angular-sanitize.js"></script>
<script src="assets/js/angular-animate.min.js"></script>
<script src="assets/js/jquery-2.1.3.min.js"></script>
<script src="assets/js/bootstrap.min.js"></script>
<script src="app/app.js"></script>
<script src="app/app.routes.js"></script>
<script src="controllers/controllerOne.js"></script>
<script src="controllers/controllerTwo.js"></script>
<script src="controllers/controllerThree.js"></script>
<script src="directives/directiveOne.js"></script>
<script src="directives/directiveTwo.js"></script>
<script src="services/serviceOne.js"></script>
<script src="services/serviceTwo.js"></script>
<script src="services/serviceThree.js"></script>
</body>
</html>
Update 07/04/2015
I have end up using Gulp. For anyone looking for bit of help on this, I have followed this small tutorial: https://medium.com/#dickeyxxx/best-practices-for-building-angular-js-apps-266c1a4a6917
There are few possible solutions that I know that will automatically inject your script tags for index.html:
Using Gulp - Task / Build runner.
You can use Gulp-Inject which is:
a stylesheet, javascript and webcomponent reference injection plugin
for gulp
Grunt - JavaScript Task Runner
You can use Grunt-Injector for:
Inject references to files into other files (think scripts and stylesheets into an html file)
Another option which I didn't use is RequireJS.
See - http://www.startersquad.com/blog/angularjs-requirejs/
You can find many discussions on Gulp vs Grunt, Both will make your life easier and solve your problem.
See:
Grunt vs Gulp
Another Grunt vs Gulp
What i would suggest is using a task runner of some sort to concatenate all your files, and build them in to something like a single 'app.js' file.
My personal preference is gulp, but another popular alternative is grunt. Here is a nice introduction to using gulp with angular which I suggest checking out.
Using require.js , u can manage all tags in one line
This approach is utterly normal for a development stage as it facilitates debugging. You shouldn't be worried about the way it looks.
However, when releasing your application to production you should concatenate all scripts into one single file as this'll significantly boost your bootstrap time. There are different ways of achieving this goal and usually they involve usage of front-side build tools like Grunt or Gulp. It's is up to you to decide which tool will work best for you.
Moreover, require.js has built-in modularity with a easy-to-use tool for concatenation, though, it's argued that Angular benefits from using it as Angular has it's own modularity. The main advantage of require.js is that there's no need to pay attention to order in which your files are concatenated since it's responsibility of the tool. Unfortunately, it costs a lot of boilerplate code.
As a simple solution, in HTML5 you can do this
<link rel="import" href="header.html">
and place all your
<script src="libs/....js"></script>
<script src="libs/....js"></script>
<script src="libs/....js"></script>
in the header.html
It's ok. Separating different scripts into different files is a part of basic recommandations for code styling.
The best way is to use Google Style recommendations in work. These 2 are for html&css and javascript:
https://google-styleguide.googlecode.com/svn/trunk/htmlcssguide.xml
https://google-styleguide.googlecode.com/svn/trunk/javascriptguide.xml
Related
Rationale
I'm making a small website using svelte and sveltekit, and a library (roslibjs) that seems to be only usable within <head>.
It worked only in those 2 types of scenarios for me:
put everything in <head> and output to the console
import the library in <head>, but only by using <script src='https link here'></script>.
Everything else goes into onMount, outside of <head>.
1 is not acceptable, and while 2 is a temporary fix, I really don't want to rely on external links. (the site might be used in an offline environment)
What I tried
Since if I have all the code relying on the library inside <head> it works just fine, I tried to do so. But so long I couldn't find a way to export variables from <head>.
Example:
<svelte:head>
<script>
let a = 10
</script>
</svelte:head>
<p>{a}</p>
This throws an error saying 'a' is not defined.
Change the import line to <script src="node_modules/roslib/build/roslib.js"></script>, directly from the node_modules folder.
While this works in npm run dev, it doesn't once after npm run build.
What I expect
To be able to use the library with svelte3, but by using it from npm, not an external link.
One way to tackle this might be to export variables from <head>, but I couldn't find a way to do so.
For some reason I didn't use JSP in my JAVA project and I only use plain html. Now I want to use jawr bundle files in my plain html, as I have searched, it should include a jawr_loader.js as following:
<script type="text/javascript" src="./jawr_loader.js" ></script>
<script>
JAWR.loader.style('/bundles/all.css');
JAWR.loader.script('/bundles/global.js');
</script>
I don't know if there is a jawr_loader.js already exist or I need to create one. If I need to create one, what the content I should write in the file,
Sorry maybe this problem is too stupid, but I new to java project using jawr, and I look for solution for few days but still cannot find answer, plz help me, thx.
I have a asp.net MVC app, and I want to start unit testing the javascript closures I use with the app. I have watched a few demo's on plural site, and played with the sample code in the github repository.
however, all the actual mocha.js examples assume I want to host with node, and that the npm system will get all of my dependencies. At this time I cannot install node.js on my laptop. the test code in the plural site courses all are horribaly orginized, and when I look at the files named "mocha.js" they actually contain the require.js code as well.
in any regards, Does anyone has a good "html" hostable template for mocha.js code, and a nice way to orginize the dependencies outside of the node npm system?
Mocha can run in the browser without having to worry about dependencies. The documentation has a section about it. As shown in the documentation, you need a page that loads and starts Mocha, and loads anything else you need:
<html>
<head>
<meta charset="utf-8">
<title>Mocha Tests</title>
<link rel="stylesheet" href="mocha.css" />
</head>
<body>
<div id="mocha"></div>
<!-- Load the libraries you need -->
<script src="jquery.js"></script>
<script src="expect.js"></script>
<script src="mocha.js"></script>
<!-- Tell Mocha what interface to use for the tests. You must do this
before you read the test files. -->
<script>mocha.setup('bdd')</script>
<!-- Load the test files. This is where your tests would be located. -->
<script src="test.array.js"></script>
<script src="test.object.js"></script>
<script src="test.xhr.js"></script>
<!-- Run the tests. -->
<script>
mocha.checkLeaks();
mocha.globals(['jQuery']);
mocha.run();
</script>
</body>
</html>
I've added some comments above to indicate what is going on.
I have been looking at a HTML 5 boilerplate template (from http://html5boilerplate.com/) and noticed the use of "?v=1" in URLs when referring to CSS and JavaScript files.
What does appending "?v=1" to CSS and JavaScript URLs in link and script tags do?
Not all JavaScript URLs have the "?v=1" (example from the sample below: js/modernizr-1.5.min.js). Is there a reason why this is the case?
Sample from their index.html:
<!-- CSS : implied media="all" -->
<link rel="stylesheet" href="css/style.css?v=1">
<!-- For the less-enabled mobile browsers like Opera Mini -->
<link rel="stylesheet" media="handheld" href="css/handheld.css?v=1">
<!-- All JavaScript at the bottom, except for Modernizr which enables HTML5 elements & feature detects -->
<script src="js/modernizr-1.5.min.js"></script>
<!------ Some lines removed ------>
<script src="js/plugins.js?v=1"></script>
<script src="js/script.js?v=1"></script>
<!--[if lt IE 7 ]>
<script src="js/dd_belatedpng.js?v=1"></script>
<![endif]-->
<!-- yui profiler and profileviewer - remove for production -->
<script src="js/profiling/yahoo-profiling.min.js?v=1"></script>
<script src="js/profiling/config.js?v=1"></script>
<!-- end profiling code -->
These are usually to make sure that the browser gets a new version when the site gets updated with a new version, e.g. as part of our build process we'd have something like this:
/Resources/Combined.css?v=x.x.x.buildnumber
Since this changes with every new code push, the client's forced to grab a new version, just because of the querystring. Look at this page (at the time of this answer) for example:
<link ... href="http://sstatic.net/stackoverflow/all.css?v=c298c7f8233d">
I think instead of a revision number the SO team went with a file hash, which is an even better approach, even with a new release, the browsers only forced to grab a new version when the file actually changes.
Both of these approaches allow you to set the cache header to something ridiculously long, say 20 years...yet when it changes, you don't have to worry about that cache header, the browser sees a different querystring and treats it as a different, new file.
This makes sure you are getting the latest version from of the css or js file from the server.
And later you can append "?v=2" if you have a newer version and "?v=3", "?v=4" and so on.
Note that you can use any querystring, 'v' is not a must for example:
"?blah=1" will work as well.
And
"?xyz=1002" will work.
And this is a common technique because browsers are now caching js and css files better and longer.
The hash solution is nice but not really human readable when you want to know what version of file is sitting in your local web folder. The solution is to date/time stamp your version so you can easily compare it against your server file.
For example, if your .js or .css file is dated 2011-02-08 15:55:30 (last modification) then the version should equal to .js?v=20110208155530
Should be easy to read properties of any file in any language. In ASP.Net it's really easy...
".js?v=" + File.GetLastWriteTime(HttpContext.Current.Request.PhysicalApplicationPath + filename).ToString("yyMMddHHHmmss");
Of coz get it nicely refactored into properties/functions first and off you go. No more excuses.
Good luck, Art.
In order to answer you questions;
"?v=1" this is written only beacuse to download a fresh copy of the css and js files instead of using from the cache of the browser.
If you mention this query string parameter at the end of your stylesheet or the js file then it forces the browser to download a new file, Due to which the recent changes in the .css and .js files are made effetive in your browser.
If you dont use this versioning then you may need to clear the cache of refresh the page in order to view the recent changes in those files.
Here is an article that explains this thing How and Why to make versioning of CSS and JS files
Javascript files are often cached by the browser for a lot longer than you might expect.
This can often result in unexpected behaviour when you release a new version of your JS file.
Therefore, it is common practice to add a QueryString parameter to the URL for the javascript file. That way, the browser caches the Javascript file with v=1. When you release a new version of your javascript file you change the url's to v=2 and the browser will be forced to download a new copy.
During development / testing of new releases, the cache can be a problem because the browser, the server and even sometimes the 3G telco (if you do mobile deployment) will cache the static content (e.g. JS, CSS, HTML, img). You can overcome this by appending version number, random number or timestamp to the URL e.g: JSP: <script src="js/excel.js?time=<%=new java.util.Date()%>"></script>
In case you're running pure HTML (instead of server pages JSP, ASP, PHP) the server won't help you. In browser, links are loaded before the JS runs, therefore you have to remove the links and load them with JS.
// front end cache bust
var cacheBust = ['js/StrUtil.js', 'js/protos.common.js', 'js/conf.js', 'bootstrap_ECP/js/init.js'];
for (i=0; i < cacheBust.length; i++){
var el = document.createElement('script');
el.src = cacheBust[i]+"?v=" + Math.random();
document.getElementsByTagName('head')[0].appendChild(el);
}
As you can read before, the ?v=1 ensures that your browser gets the version 1 of the file. When you have a new version, you just have to append a different version number and the browser will forget about the old version and loads the new one.
There is a gulp plugin which takes care of version your files during the build phase, so you don't have to do it manually. It's handy and you can easily integrate it in you build process. Here's the link: gulp-annotate
As mentioned by others, this is used for front end cache busting. To implement this, I have personally find grunt-cache-bust npm package useful.
Is there a decent way with static HTML/XHTML to create common header/footer files to be displayed on each page of a site? I know you can obviously do this with PHP or server side directives, but is there any way of doing this with absolutely no dependencies on the server stitching everything together for you?
Edit: All very good answers and was what I expected. HTML is static, period. No real way to change that without something running server side or client side. I've found that Server Side Includes seem to be my best option as they are very simple and don't require scripting.
There are three ways to do what you want
Server Script
This includes something like php, asp, jsp.... But you said no to that
Server Side Includes
Your server is serving up the pages so why not take advantage of the built in server side includes? Each server has its own way to do this, take advantage of it.
Client Side Include
This solutions has you calling back to the server after page has already been loaded on the client.
JQuery load() function can use for including common header and footer. Code should be like
<script>
$("#header").load("header.html");
$("#footer").load("footer.html");
</script>
You can find demo here
Since HTML does not have an "include" directive, I can think only of three workarounds
Frames
Javascript
CSS
A little comment on each of the methods.
Frames can be either standard frames or iFrames. Either way, you will have to specify a fixed height for them, so this might not be the solution you are looking for.
Javascript is a pretty broad subject and there probably exist many ways how one might use it to achieve the desired effect. Off the top of my head however I can think of two ways:
Full-blown AJAX request, which requests the header/footer and then places them in the right place of the page;
<script type="text/javascript" src="header.js"> which has something like this in it: document.write('My header goes here');
Doing it via CSS would be really an abuse. CSS has the content property which allows you to insert some HTML content, although it's not really intended to be used like this. Also I'm not sure about browser support for this construct.
The simplest way to do that is using plain HTML.
You can use one of these ways:
<embed type="text/html" src="header.html">
or:
<object name="foo" type="text/html" data="header.html"></object>
You can do it with javascript, and I don't think it needs to be that fancy.
If you have a header.js file and a footer.js.
Then the contents of header.js could be something like
document.write("<div class='header'>header content</div> etc...")
Remember to escape any nested quote characters in the string you are writing.
You could then call that from your static templates with
<script type="text/javascript" src="header.js"></script>
and similarly for the footer.js.
Note: I am not recommending this solution - it's a hack and has a number of drawbacks (poor for SEO and usability just for starters) - but it does meet the requirements of the questioner.
you can do this easily using jquery. no need of php for such a simple task.
just include this once in your webpage.
$(function(){
$("[data-load]").each(function(){
$(this).load($(this).data("load"), function(){
});
});
})
now use data-load on any element to call its contents from external html file
you just have to add line to your html code where you want the content to be placed.
example
<nav data-load="sidepanel.html"></nav>
<nav data-load="footer.html"></nav>
The best solution is using a static site generator which has templating/includes support. I use Hammer for Mac, it is great. There's also Guard, a ruby gem that monitors file changes, compile sass, concatenate any files and probably does includes.
The most practical way is to use Server Side Include. It's very easy to implement and saves tons of work when you have more than a couple pages.
HTML frames, but it is not an ideal solution. You would essentially be accessing 3 separate HTML pages at once.
Your other option is to use AJAX I think.
You could use a task runner such as gulp or grunt.
There is an NPM gulp package that does file including on the fly and compiles the result into an output HTML file. You can even pass values through to your partials.
https://www.npmjs.com/package/gulp-file-include
<!DOCTYPE html>
<html>
<body>
##include('./header.html')
##include('./main.html')
</body>
</html>
an example of a gulp task:
var fileinclude = require('gulp-file-include'),
gulp = require('gulp');
gulp.task('html', function() {
return gulp.src(['./src/html/views/*.html'])
.pipe(fileInclude({
prefix: '##',
basepath: 'src/html'
}))
.pipe(gulp.dest('./build'));
});
You can try loading them via the client-side, like this:
<!DOCTYPE html>
<html>
<head>
<!-- ... -->
</head>
<body>
<div id="headerID"> <!-- your header --> </div>
<div id="pageID"> <!-- your header --> </div>
<div id="footerID"> <!-- your header --> </div>
<script>
$("#headerID").load("header.html");
$("#pageID").load("page.html");
$("#footerID").load("footer.html");
</script>
</body>
</html>
NOTE: the content will load from top to bottom and replace the content of the container you load it into.
No. Static HTML files don't change. You could potentially do this with some fancy Javascript AJAXy solution but that would be bad.
Short of using a local templating system like many hundreds now exist in every scripting language or even using your homebrewed one with sed or m4 and sending the result over to your server, no, you'd need at least SSI.
The only way to include another file with just static HTML is an iframe. I wouldn't consider it a very good solution for headers and footers. If your server doesn't support PHP or SSI for some bizarre reason, you could use PHP and preprocess it locally before upload. I would consider that a better solution than iframes.