asp.net core <environment> equivalent in angular2? - asp.net

In asp.net core, I can conditionally include css/js in my layout html page using <environment> tags:
<environment names="Development,Staging">
<script type="text/javascript" href="js/debug.js"></script>
<link rel="stylesheet" type="text/css" href="css/style.css" />
</environment>
<environment names="Production">
<link rel="stylesheet" type="text/css" href="css/style.min.css" />
</environment>
How can I achieve this in angular 2? The css/js files that I'm talking about are site-wide, not component-specific
(PS. I'm new to angular 2)

If you are using angular2 CLI then you could use enironment.ts.
Properties specified in this file will be available throughout entire application.
You can create multiple environments like this-
In components import default environment file like this-
import { environment } from '../../environments/environment';
Import DOCUMENT from platform-browser like this-
import { DOCUMENT } from '#angular/platform-browser';
Inject into component (e.g. main AppComponent),
constructor (#Inject(DOCUMENT) private document) { }
Use environment condition and apply dynamic style-sheet like this-
if(environment.EnvName === 'prod') {
this.document.getElementById('theme').setAttribute('href', 'prod.css');
}
else {
this.document.getElementById('theme').setAttribute('href', 'dev.css');
}
Angular CLI takes care of which file to use for each environment during build process.
This is how you can specify environment at a time build-
ng build --env=prod
Hope this helps in your use case.

Related

NextJS looses global vars from script on deep link / page refresh

In Pages/_document.tsx I have a script that loads some global public configuration like below.
The script just sets some global variable on the window object.
If I visit the home route of the app, the page loads everything is fine, but if I refresh the page on a nested route, (or deep link) it throws an error saying ReferenceError: window is not defined.
I'm guessing this is the server complaining, but I only need this config on the client, and I don't want to package the config vars up during build time, as I want to promote the built app down a pipeline and just update a few variables. Is this the right approach?
import Script from 'next/script'
...
...
render() {
return (
<Html lang='en'>
<Head>
<meta charSet='UTF-8' />
<meta httpEquiv='X-UA-Compatible' content='IE=edge' />
</Head>
<body>
<Main />
<NextScript />
<Script src='/scripts/public-config.js' strategy='beforeInteractive' />
</body>
</Html>
)
}
Maybe there's a better way, but I ended up checking if window exists anywhere I use it, so in my public-config.js file I did this:
if (typeof window !== 'undefined') {
window.MY_PUBLIC_CONFIG = {
MY_VAR: 'HELLO WORLD'
}
}
and anywhere referencing it needs to do the same:
export const config = (typeof window !== 'undefined')
? window.MY_PUBLIC_CONFIG
: {}

using WebOptimizer and pre-minimized files?

If I am using the WebOptimizer -- https://github.com/ligershark/WebOptimizer -- for bundling and minification in my ASP.Net Core application is there any need to keep the minified versions of the client-side libraries that are being used around?
For example, do I still need code like this in the layout page:
<environment include="Development">
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" />
</environment>
<environment exclude="Development">
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
</environment>
Or can I just have the link to the un-minified version and WebOptimizer will minify it on the fly and then I can delete the boostrap.min.css file from my project?
And on a related note, what would the WebOptimizer middleware do if it encountered a pre-minified file?
This is a bit old but I thought it was good to answer this.
Instead of doing it on the HTML part of things, you could configure the bundle to minify the file or not in your configuration, and just reference bootstrap.css in your html normally.
Here you can find an example of how this is done: https://www.vinayjadav.com/posts/bundle-js-css-aspnet-core
public static class WebOptimizerBootstrapper
{
public static void Configure(ServiceRegistry services)
{
string environment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");
bool isDevelopment = environment == Environments.Development;
services.AddWebOptimizer(pipeline =>
{
pipeline.AddCssBundle("/css/site.css", "css/**/*css");
pipeline.AddJavaScriptBundle("/js/site.js", "js/**/*.js");
if (!isDevelopment)
{
pipeline.MinifyCssFiles();
pipeline.MinifyJsFiles();
}
});
}
}
And in your Program.cs (for .net core)
builder.Services.AddWebOptimizer(services=>WebOptimizerBootstraper.Configure)

How to link css to ejs templates in node

I am working on a beginner node js server. I am able to render dynamic html using ejs templates but i cannot link css styling to them
I have set up a public directory to store the assets like images and external css files. i have linked to the static contents to express using
app.use(express.static('/public', __dirname + '/public'));
my public folder has images(.jpg) which are rendered but the css in the public folder cannot be rendered.
file structure :
node_modules
models
views
public > app.css, hero.jpg
server.js
package.json
the express app is as below : server.js
const express = require('express');
const app = express();
const ejs = require('ejs');
app.use('/public', express.static(__dirname + '/public');
app.set("view engine", "ejs");
app.set('views',__dirname+'/views');
app.get('/', (req,res) =>{
res.render('home',{
title: "HomePage",
date : new Date().getFullTYear()
}
app.listen(3000);
the home.ejs file has a head section as :
<head>
<meta charset = "utf-8">
<title> My Website <%= title %> </title>
<link rel="stylesheet" href="/app.css" type="text/stylesheet">
</head>
I expected the app.css to load like the in the home.ejs file. But its not working
Looking at your code, I could guess you are setting the static file folder to be /public.
Try modifing you css link to <link rel="stylesheet" href="/public/app.css" type="text/stylesheet">
or try setting the static file config like this:
app.use('/static', express.static(path.join(__dirname, 'public')))
and then <link rel="stylesheet" href="/static/app.css" type="text/stylesheet">
You should declare your public folder this way
app.use(express.static(__dirname + '/public'));
That means you can serve these files as if these were in the root folder. So you can link your css and images this way
<link rel="stylesheet" href="/app.css" type="text/stylesheet">
// in case of image
<img src="/hero.jpg">
When you declare public folder like this
app.use(express.static('/public', __dirname + '/public'));
you set a virtual path prefix for your files and in that case you have to add public in the url path of each file, like this <link rel="stylesheet" href="/public/app.css" type="text/stylesheet">
To use the absolute path of the directory that you want to serve as a part of public folder:
app.use(express.static(path.join(__dirname, 'public')));
Create public folder under the root folder. Under that folder create css folder if you want. So, structure will be link public/css/style.css
You can access style.css like:
<link rel="stylesheet" href="/css/style.css">

Defining Firebase default in angular 2

I'm new to angular 2, so be patient!
I'm trying to put together Angular2 and Firebase to have a real time app to update information on the page. By looking at the Firebase github for Angular2, they say to inject Firebase and also define a base url for the whole app, like so:
import {FIREBASE_PROVIDERS, defaultFirebase} from 'angularfire2';
bootstrap(App, [
FIREBASE_PROVIDERS,
defaultFirebase('https://my.firebaseio.com')
]);
The problem is, I'm using AngularRouter defined on the bootstrap as well. When I try to initiate the app like this:
import {ROUTER_PROVIDERS} from 'angular2/router'
import {FIREBASE_PROVIDERS, defaultFirebase} from 'angularfire2'
bootstrap(AppComponent, [ROUTER_PROVIDERS,
FIREBASE_PROVIDERS,
defaultFirebase('https://my.firebaseio.com') //In my code I'm using my own url
]);
I get this error:
angular2-polyfills.js:1243 SyntaxError: Unexpected token <(…)
My structure is like this:
app.component.ts
boot.ts
--home/home.component.ts
--user/user.component.ts
--post/post.component.ts
And the firebase is going to be used on the user and post component (at least for this test).
I know, based on the Angular doc we should avoid this type of declaration on a root level because it will create an instance of each independent. But in this case, isn't it necessary to declare it here?
What is going on and how can I solve this?
Edited:
As requested, this is my html file:
<head>
<base href="/">
<title>Angular 2 Firebase</title>
<link rel="stylesheet" href="assets/stylesheets/bootstrap.min.css" />
<script src="node_modules/systemjs/dist/system-polyfills.js"></script>
<script src="node_modules/angular2/bundles/angular2-polyfills.js"></script>
<script src="node_modules/systemjs/dist/system.src.js"></script>
<script src="node_modules/rxjs/bundles/Rx.js"></script>
<script src="node_modules/angular2/bundles/angular2.dev.js"></script>
<script src="node_modules/angular2/bundles/router.dev.js"></script>
<script src="node_modules/angular2/bundles/http.dev.js"></script>
<script src="https://cdn.firebase.com/js/client/2.4.1/firebase.js"></script>
<script>
System.config({
packages: {
app: {
format: 'register',
defaultExtension: 'js'
}
}
});
System.import('app/boot').then(null, console.error.bind(console));
</script>
</head>
<body>
<my-app>Loading...</my-app>
</body>
Note: The error only appear when I insert the code for default firebase in the boot.ts. Before I do this, the application works just fine!
You need to include angularfire2 into your HTML file in your SystemJS configuration:
System.config({
map: {
firebase: '/node_modules/firebase/lib/firebase-web.js',
angularfire2: ' node_modules/angularfire2'
},
packages: {
angularfire2: {
main: 'angularfire2.js',
defaultExtension: 'js'
},app: {
format: 'register',
defaultExtension: 'js'
}
},
});
to be able to inject elements from this library.
You also need to remove the script element for Firebase in the head of your HTML page:
<!-- script src="https://cdn.firebase.com/js/client/2.4.1/firebase.js"></script -->
The library needs to be installed using npm install firebase and referenced from the SytemJS configuration.
See the following HTML page as a reference:
https://github.com/angular/angularfire2/blob/master/test/e2e/firebase_list/index.html

How to conditionally load / bundle CSS files in Meteor 1.0?

I know this question has been asked before but I'm wondering if something has changed with the advent of 1.0.
I don't want Meteor to automatically bundle together every single CSS file in my app. My admin pages are going to have a completely different CSS than my client-facing pages and using namespaces seems like a really over-complicated solution. How do I have Meteor load certain CSS files on certain pages and NOT load certain CSS files on certain pages?
The same question goes for JS files.
I know someone said this would be useful:
https://github.com/anticoders/meteor-modules
Any comments on this package for conditional CSS and JS?
You can just put your CSS files somewhere under /public and manually include them from your templates where required. Everything under /public will NOT get bundled, and the URL will have the /public removed e.g.
Create two files: your_meteor_project/public/one.css and ......./two.css. These will be available from your client at http://example.com/one.css (i.e. the "public" does not form part of the URL, it's like the document root for using meteor as a plain old web server).
meteor create cssSwitcher
cd cssSwitcher/
mkdir public
echo 'html, body { background-color: red; }' > public/one.css
echo 'html, body { background-color: blue; }' > public/two.css
Create a reference to a helper function "appropriateStylesheet" in the head of your HTML :
HTML template
<!-- add code to the <body> of the page -->
<body>
<h1>Hello!</h1>
{{> welcomePage}}
</body>
<!-- define a template called welcomePage -->
<template name="welcomePage">
<!-- add code to the <head> of the page -->
<head>
<title>My website!</title>
<link rel="stylesheet" href="/{{appropriateStylesheet}}" type="text/css" />
</head>
<p>Welcome to my website!</p>
<button id="red">Red</button>
<button id="blue">Blue</button>
</template>
Create a helper function.
JavaScript:
if (Meteor.isClient) {
Session.set("stylesheet","red.css");
Template.registerHelper("appropriateStylesheet", function() {
return Session.get("stylesheet");
});
Template.welcomePage.events({
'click #blue' : function() { Session.set("stylesheet","two.css"); },
'click #red' : function() { Session.set("stylesheet","one.css"); },
});
}
You can do exactly the same thing with JS files. Put them under /public and meteor ignores them.

Resources