I want to do different things in my gulpfile.js based on the hosting environment (Development, Staging or Production), for example I don't want to minify and uglify my scripts in Development.
Node.js has it's own NODE_ENV environment variable (See StackOverflow) that has to be set separately.
Is there some way to get the ASP.NET 5 hosting environment in my gulpfile.js or alternatively is there a way we can set the NODE_ENV based on the ASP.NET 5 hosting environment?
me too
@DamianEdwards @madskristensen thoughts?
I believe you can use the ASPNET_ENV variable, can't you?
function isForDevelopment() {
var env = process.env.ASPNET_ENV || "Development";
return env === "Development";
}
@djanosik yeah that's what I was going to suggest. That's what we use to populate the value.
Ok cool, I was not aware of that setting. It's coming back as undefined but I guess that this comes from the Windows environment variables and I would need to set it there. This should definitely be part of the default gulpfile.js. I'm going to add it to ASP.NET MVC Boilerplate here.
A short JavaScript snippet to help with determining the environment in your gulpfile.js.
// Read the launchSettings.json file into the launch variable.
var launch = require('./Properties/launchSettings.json');
// Holds information about the hosting environment.
var environment = {
// The names of the different environments.
development: "Development",
staging: "Staging",
production: "Production",
// Gets the current hosting environment the application is running under.
current: function () {
return process.env.ASPNETCORE_ENVIRONMENT ||
(launch && launch.profiles['IIS Express'].environmentVariables.ASPNETCORE_ENVIRONMENT) ||
this.development;
},
// Are we running under the development environment.
isDevelopment: function () { return this.current() === this.development; },
// Are we running under the staging environment.
isStaging: function () { return this.current() === this.staging; },
// Are we running under the production environment.
isProduction: function () { return this.current() === this.production; }
};
I have tried the snippet above, for some reason process.env.ASPNET_ENV is always undefined. Is there any other config that needs to be done?
You need to create an environment variable in the system settings if you are using Windows. If you do not do this, the default Development environment is assumed to be the current one.
I have added the system environement variable and it now picks this value up. What is the purpose of the Environment Variables on the project properties page? How do I change the ASPNET_ENV depending on build configuration e.g Debug or Release?
I think the idea behind the one in project properties is for convenience and debugging.
I also would like to be able to bind these variable names to Visual Studio's build events. This was accomplished in Visual Studio 2013 by accessing the Project Settings Build Events and adding the following post build event
cd $(ProjectDir)
set NODE_ENV=$(ConfigurationName)
gulp
I was able to then intelligently change my gulp workflow in gulpfile.js like
if (process.env.NODE_ENV === "Debug") {
tasksToRun.push('debugTask');
}
else {
tasksToRun.push('build-css');
tasksToRun.push('build-js');
tasksToRun.push('releaseTask');
}
Can this be accomplished in ASP 5?
Can we have this for using the VS 2015 build configuration name, too?
I imagine something similar to
var isDebug = /DEBUG/i.test(process.build.config.name)
SetTrend is exactly correct in that we need access to the config that is being run against and it needs to be set in some form so that when prepublish occurs we can do transforms on files.
If you have an angular site for instance you'll no doubt have a serviceUrl somewhere in your static files that needs to be transformed, and adding mvc just to set this intelligently from a configuration file is just ridiculous.
Hence we need an automated way to run a gulp task that goes into certain files and runs replace on values like the serviceUrl so that it's pointing to the right spot without having to manually modify them.
As it stands right now the veriable doesn't work, AND it still doesn't tell us the build configuration.
To me this is a show stopper headslapper that needs to be fixed before release to production because without it we can't intelligently deploy static sites like Angular which is a very large part of your use case.
You can read other json files in your gulpfile.js like so:
var config = require("./config.json"), // Read the config.json file into the config variable.
hosting = require("./hosting.json"), // Read the hosting.json file into the hosting variable.
project = require("./project.json"); // Read the project.json file into the project variable.
This gives you access to everything you could want.
@SetTrend and @JohnGalt1717, what is your actual use case for having the build configuration. There may be a scenario I am missing but don't think we need to know the build configuration in gulpfile.js. The environment is now the standard way of switching code paths. The build configuration can go back to only dealing with enabling/disabling C# or Razor optimizations.
Let me explain: The more config files there are the more maintenance is necessary and the more errors may occur.
Having access to the host environment enables switching configuration safely with one single click to the Visual Studio build configuration dropdown box.
And it's even easily distributable to continuous integration. Setting build to "Release" will be all there is to create a release version.
This will be true for server _and_ client parts of the code then.
First the environment isn't set anymore and second it is set to development or not and if you change that it causes issues.
Second it can't be set conditionally on the machine doing the publishing which is where you need to update you app.js to change the path not on the destination server that would have the unique environment variable which client js cannot read anyhow.
So tell me how in your example I could ever tell that my qa deployment is running and replace the serviceUrl in app.js to point to qaapi.XXX.com instead of the development localhost:60000 during publish with ms deploy.
The answer is you can't. You must have access to either the deployment name that's being run or the build configuration.
This is absolutely no different than web.config transforms back in the day. You MUST know the build config and be able to act upon it during deploy.
On Dec 17, 2015 11:04 AM, Muhammad Rehan Saeed [email protected] wrote:
You can read other json files in your gulpfile.js like so:
var config = require("./config.json"), // Read the config.json file into the config variable.
hosting = require("./hosting.json"), // Read the hosting.json file into the hosting variable.
project = require("./project.json"); // Read the project.json file into the project variable.
This gives you access to everything you could want.
@SetTrendhttps://github.com/SetTrend and @JohnGalt1717https://github.com/JohnGalt1717, what is your actual use case for having the build configuration. There may be a scenario I am missing but don't think we need to know the build configuration in gulpfile.js. The environment is now the standard way of switching code paths. The build configuration can go back to only dealing with enabling/disabling C# or Razor optimizations.
Reply to this email directly or view it on GitHubhttps://github.com/aspnet/Home/issues/724#issuecomment-165494353.
How exactly does what you're suggesting help me at all? I still can't get the specific build configuration that is executing the compilation and thus gulp so that I can use gulp.replace to replace the api service url.
Please explain how I can know AT COMPILE OR PUBLISH TIME (and not at the executing destination server) that this is going be compiled for "DEMO" build configuration or "DEMO" publishing.
i.e. in the project.json, there isr a scripts section and in there "prepublish". You can call gulp in there. AT that point I need visual Studio's Build Configuration that is set for the build and publish OR I need the Publishing target for the build and publish.
Absolutely nothing else will work. This is exactly the same as web.config transforms that created transformations for each build config that would merge them during the deploy so that you could have custom connection strings etc. for each build config and thus each publishing target. In this case instead of a connection string to a database, it's the connection string to the REST API that has to be custom set.
But you can't right now. That's the bug. You've got no one in gulp to know the context you're executing on during compile and publish because neither are gettable in gulp and the environment variable in the VS.net project file is global instead of build configuration specific.
The easy solution is to fix the vs.net project setting of the environment variables so that they are build configuration specific and then this all works. But baring that there is no way to automate builds of sites that use static files and things like Angular or Durandal etc. and set configuration information.
And to be 100% clear: This is no big deal if you're using MVC. You can just inject the value from the merged server side configuration files.
This is only a show stopper if you're building a SPA that doesn't need to have the overhead of MVC and thus doesn't have it running to be able to inject it from the server side. Thus it must be done at time of compile and publish and must be done using something like gulp which then must know the build configuration.
Perfect world you would just set an environment variable that is the build configuration.
@JohnGalt1717
I cannot get a clear understanding of what you have been writing. Can you please elaborate or rephrase?
Which development environment are you using? I'm referring to Visual Studio 2015.
Visual Studio 2015 Update 1 with ASPNET 5 RC1 Update
AngularJS Static file application. (i.e. a bunch of *.html files in a /app folder)
The app.js of the angular.js app contains the RESTful api's root Uri for all $http calls. (It's really type script but I'm simplifying)
In a development environment this Uri looks like this: var serviceUrl = "http://localhost:6000/" but when deploying to our demo enviornment it would like like this: var serviceUrl = "https://demoapi.xxx.com/"
Production would have a different uri, so would QA.
This gets deployed through VS.net's publish functionality and MS Build on visual studio TFS for continuous deploy.
Thus I need to automate setting the serviceUrl variable in the app.js upon publish and do so contextually to where it is being published. To do this, currently the only way that I have found would be to use a prepublish script set in the project.json file. This prepublish script there would call gulp and gulp would use gulp.replace and a regex expression to put in the new value. (This all works, I've tried it).
The issue is that gulp, executing either on the developer's computer from within visual studio.net or on the build server using msbuild has no way to know the publishing target or the build configuration associated with that publishing target. Thus it has no way to do this.
This is exactly the same problem with task runners as was the problem solved by web.config transforms per build configuration. I'm solving the exact same issue as classic asp.net had, but this time it's for SPAs and the solution presented by vs.net in aspnet 5 is using task runners.
Thus task runners need access to the build configuration and/or the publishing configuration.
There are many ways to get at that (inject an environment variable that contains these on build and publish, or let us set environment variables in the vs.net project properties on a PER BUILD CONFIGURATION basis instead of globally.) Either will do, but we need one or the other. The current way is broken and doesn't allow automation this way.
(And yes, I understand that this is trivial with mvc.net and the environment variable, but that's server side execution which the vast majority of new projects are not going to be using mvc.net, they're going to be SPAs using static html files and have no way to get at server side variables at run time. Hence we're not talking about server side runtime variables we're talking about gulp executing at compile or publish time.
Most helpful comment
Visual Studio 2015 Update 1 with ASPNET 5 RC1 Update
AngularJS Static file application. (i.e. a bunch of *.html files in a /app folder)
The app.js of the angular.js app contains the RESTful api's root Uri for all $http calls. (It's really type script but I'm simplifying)
In a development environment this Uri looks like this: var serviceUrl = "http://localhost:6000/" but when deploying to our demo enviornment it would like like this: var serviceUrl = "https://demoapi.xxx.com/"
Production would have a different uri, so would QA.
This gets deployed through VS.net's publish functionality and MS Build on visual studio TFS for continuous deploy.
Thus I need to automate setting the serviceUrl variable in the app.js upon publish and do so contextually to where it is being published. To do this, currently the only way that I have found would be to use a prepublish script set in the project.json file. This prepublish script there would call gulp and gulp would use gulp.replace and a regex expression to put in the new value. (This all works, I've tried it).
The issue is that gulp, executing either on the developer's computer from within visual studio.net or on the build server using msbuild has no way to know the publishing target or the build configuration associated with that publishing target. Thus it has no way to do this.
This is exactly the same problem with task runners as was the problem solved by web.config transforms per build configuration. I'm solving the exact same issue as classic asp.net had, but this time it's for SPAs and the solution presented by vs.net in aspnet 5 is using task runners.
Thus task runners need access to the build configuration and/or the publishing configuration.
There are many ways to get at that (inject an environment variable that contains these on build and publish, or let us set environment variables in the vs.net project properties on a PER BUILD CONFIGURATION basis instead of globally.) Either will do, but we need one or the other. The current way is broken and doesn't allow automation this way.
(And yes, I understand that this is trivial with mvc.net and the environment variable, but that's server side execution which the vast majority of new projects are not going to be using mvc.net, they're going to be SPAs using static html files and have no way to get at server side variables at run time. Hence we're not talking about server side runtime variables we're talking about gulp executing at compile or publish time.