« Back to home

Before going into production

Daj się poznać

I have been dealing with my project for a while and I haven’t shown anything to my Imaginary Client. They are starting to think that I haven’t done anything but burn their Imaginary Money. But I have done something. I have written posts, I have done research and I have learned a lot new things. To convince my Imaginary Client that I haven’t wasted their Imaginary Money I should quickly deploy something to production but before I do this I should tune my application a bit.

The first thing I did was update Angular 2. There have been two new versions since I started this series. You can check this by command npm outdated executed in terminal.

npm outdated output

It turned out that not only was Angular 2 outdated, but 5 other packages were outdated as well. I changed the versions of every outdated package in package.json to the newest one and after this I executed npm update.

Next, I added some npm packages by entering this in terminal:

npm install concurrently event-stream gulp-sourcemaps gulp-typescript gulp-inline-ng2-template --save-dev

The package concurrently I used in my postinstall script in package.json:

"scripts": {
 //...
 "build-dev":"gulp build-dev",
 "postinstall": "concurrently \"typings install\" \"npm run build-dev\""
},

Now every time I execute npm install the typings will be installed and my build-dev gulp task will be executed.

The package event-stream is what I needed to merge the streams into one and return it for further processing.

The gulp-sourcemaps package generates source maps that are embedded in the source file. Something like this is added at the bottom of every .js file created from a TypeScript file:

//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImFwcC9tYWlu….

The package gulp-typescript is used to compile TypeScript files.

Finally, this package gulp-inline-ng2-template inlines HTML and CSS files into the JavaScript files of Angular 2 components.

All the packages I combined in one gulp task that looked like this:

gulp.task('build-prod', ['build.lib'], function () {
   var tsProject = typescript.createProject('./tsconfig.json', { typescript: require('typescript') });
   var tsSrcInlined = gulp.src([webroot + '**/*.ts'], { base: webroot })
       .pipe(inlineNg2Template({ base: webroot }));
   return eventStream.merge(tsSrcInlined, gulp.src(['typings/browser/**/*.ts','typings/browser.d.ts']))
       .pipe(sourcemaps.init())
       .pipe(typescript(tsProject))
       .pipe(sourcemaps.write())
       .pipe(gulp.dest(webroot))
});

This task complies all TypeScript files in my application and inlines source maps, CSS styles and HTML templates inside components and saves all the process files inside wwwroot folder. This processing reduces the number of requests to my application. I know in the HTTP2 world it won’t be needed, but as far as I know, kestrel doesn’t have support for HTTP2 yet.

The next thing which I did was a conditional import of Javascript and CSS files. Dependent on the environment, I loaded them either from CDN for production or from local for development environment. An example how I did this in the file _Layout.cshtml looked like this:

        <environment names="Development">
            <link rel="stylesheet" href="lib/material-design-lite/dist/material.blue-teal.min.css">
            <script src="lib/material-design-lite/material.min.js"></script>
        </environment>
        <environment names="Staging,Production">            
            <link rel="stylesheet" href="https://code.getmdl.io/1.1.3/material.blue-teal.min.css"
             asp-fallback-href="lib/material-design-lite/dist/material.blue-teal.min.css"
             asp-fallback-test-class="mdl-ripple" />
            <script src="https://code.getmdl.io/1.1.3/material.min.js"
                    asp-fallback-src="lib/material-design-lite/material.min.js"
                    asp-fallback-test="window.componentHandler">
            </script>
          </environment>

An environment tag is a new thing in ASP .NET Core and you can find out more about it here. As you can see, I used a fallback test to check if loading assets from CDN succeeded, if not, I loaded the local files. I did something similar in the Home/Index.cshtml file which you can see in my github repository.

In this file, I also turned on production mode in Angular 2 by executing the following script:

  System.import('angular2/core')
            .then(function(core){
                    core.enableProdMode();
                    return System.import('./app/main');
            })
            .catch(console.log.bind(console));

In order to have this tag environment working properly, I had to add this package Microsoft.AspNet.Mvc.TagHelpers to dependencies in project.json and in the file _ViewImports.cshtml I added following line:

@addTagHelper "*, Microsoft.AspNet.Mvc.TagHelpers"

To see this tag in action, I must run my application in development mode. By default, dnx web command runs an application in a production environment, so, to run the application in development mode I could do this by executing this command:

env ASPNET_ENV=”Development” dnx web

After this, you can see that in development, my files are served from localhost:

assets from local

To test the production mode, I published my application in the local folder on my computer by entering the command:

dnu publish -o ~/publishednotifier

~/publishednotifier - it is the folder where my application will be published.

Inside this folder, there is another folder called approot where I can find scripts for every command declared in the section commands in project.json file. I had only one command web. Entering this command in terminal ( ~/publishednotifier/approot/web) ran my application and I could see this in a web browser:

Final result

I could see in the debug tool of the browser that my files are loaded from the CDN.

Loaded form CDN

I left space for further improvement in my project setup but I will leave the details for another post where I’ll write about package Microsoft.AspNet.AngularServices. Now, I am ready to publish my application to Azure. In the next post, I am going to write about what this process looked like.

Related posts:

Comments

comments powered by Disqus