LESS happens to be written in JavaScript, so installing it can be as easy as downloading its JavaScript library (less.js
), linking it to our index.html
page, and letting its magic work without having to set up anything else.
Should we do that, then? Not a chance. As we said earlier, delegating the compilation task on the client side would be highly inefficient, especially in a client-intensive Angular 2-based native web app. This is what we're going to do instead:
style.less
file to our project.style.css
file into the /wwwroot/
folder..css
file to the /wwwroot/index.html
root application file.Let's get to work.
Considering how many files we've added so far, this is going to be a trivial task. Add a new /less/
folder inside the /Scripts/
root directory, then right-click on it, choose Add | New Item, and select LESS Style Sheet from the client-side set item tab: name the new file style.less
and click on OK.
Once done, open the newly created file and add the following content:
item-list { min-width: 332px; border: 1px solid #aaaaaa; display: inline-block; margin: 0 10px; padding: 10px; &.latest { background-color: #f9f9f9; } &.most-viewed { background-color: #f0f0f0; } &.random { background-color: #e9e9e9; } }
We might recognize the preceding lines, as these are the styles
of our /Scripts/app/home.component.ts
Angular 2 component file, we just applied some mixins as described previously to shrink the code a bit.
The first thing we need to do is to add the LESS plugin for Gulp
. Open the package.json
file, locate the devDependencies
node and add the following line to the gulp
section. We'll be placing it right after the gulp-concat
package to keep the alphabetical sorting:
"gulp": "^3.9.1",
"gulp-clean": "^0.3.2",
"gulp-concat": "^2.6.0",
"gulp-less": "^3.1.0",
"gulp-sourcemaps": "^1.6.0",
"gulp-typescript": "^2.13.6",
"gulp-uglify": "^2.0.0",
"typescript": "^1.8.10"
As soon as we save the file we'll issue a real-time refresh to the project's NPM dependencies.
Now switch to the gulpfile.js
file and get ready to add/modify a few lines of code (new/updated lines are highlighted):
var gulp = require('gulp'), gp_clean = require('gulp-clean'), gp_concat = require('gulp-concat'), gp_less = require('gulp-less'), gp_sourcemaps = require('gulp-sourcemaps'), gp_typescript = require('gulp-typescript'), gp_uglify = require('gulp-uglify'); /// Define paths var srcPaths = { app: ['Scripts/app/main.ts', 'Scripts/app/**/*.ts'], js: [ 'Scripts/js/**/*.js', 'node_modules/core-js/client/shim.min.js', 'node_modules/zone.js/dist/zone.js', 'node_modules/reflect-metadata/Reflect.js', 'node_modules/systemjs/dist/system.src.js', 'node_modules/typescript/lib/typescript.js' ], js_angular: [ 'node_modules/@angular/**' ], js_rxjs: [ 'node_modules/rxjs/**' ], less: [ 'Scripts/less/**/*.less' ] }; var destPaths = { app: 'wwwroot/app/', css: 'wwwroot/css/', js: 'wwwroot/js/', js_angular: 'wwwroot/js/@angular/', js_rxjs: 'wwwroot/js/rxjs/' }; // Compile, minify and create sourcemaps all TypeScript files and place them to wwwroot/app, together with their js.map files. gulp.task('app', ['app_clean'], function () { return gulp.src(srcPaths.app) .pipe(gp_sourcemaps.init()) .pipe(gp_typescript(require('./tsconfig.json').compilerOptions)) .pipe(gp_uglify({ mangle: false })) .pipe(gp_sourcemaps.write('/')) .pipe(gulp.dest(destPaths.app)); }); // Delete wwwroot/app contents gulp.task('app_clean', function () { return gulp.src(destPaths.app + "*.*", { read: false }) .pipe(gp_clean({ force: true })); }); // Copy all JS files from external libraries to wwwroot/js gulp.task('js', function () { gulp.src(srcPaths.js_angular) .pipe(gulp.dest(destPaths.js_angular)); gulp.src(srcPaths.js_rxjs) .pipe(gulp.dest(destPaths.js_rxjs)); return gulp.src(srcPaths.js) .pipe(gulp.dest(destPaths.js)); }); // Delete wwwroot/js contents gulp.task('js_clean', function () { return gulp.src(destPaths.js + "*.*", { read: false }) .pipe(gp_clean({ force: true })); }); // Process all LESS files and output the resulting CSS in wwwroot/css gulp.task('less', ['less_clean'], function () { return gulp.src(srcPaths.less) .pipe(gp_less()) .pipe(gulp.dest(destPaths.css)); }); // Delete wwwroot/css contents gulp.task('less_clean', function () { return gulp.src(destPaths.css + "*.*", { read: false }) .pipe(gp_clean({ force: true })); }); // Watch specified files and define what to do upon file changes gulp.task('watch', function () { gulp.watch([ srcPaths.app, srcPaths.js, srcPaths.less], ['app', 'js', 'less']); }); // Global cleanup task gulp.task('cleanup', ['app_clean', 'js_clean', 'less_clean']); // Define the default task so it will launch all other tasks gulp.task('default', ['app', 'js', 'less', 'watch']);
What we did here was quite straightforward:
gulp-less
plugin, assigning it to the gp_less
variable just like we did with the other plugins.less
key to the srcPaths
variable; that key contains a listing of the locations of all the .less
files we want to process: everything inside Scripts/less/
, including subfolders, as long as it ends with the .less
extension.css
key to the destPaths
variable, defining the folder where the resulting compiled .css
files will be generated.Gulp
how to handle LESS files:less
task to compile the .less
files found inside the srcPaths.less
folder(s) and then output the result to the wwwroot/css
target folder.less_clean
task to erase the contents of the target folder; since it does the same job as the other existing cleanup tasks, there's no need to explain how it works. We also added it as a dependent task to the previous one, just like we did with the app_clean
and app
tasks back in Chapter 1, Getting Ready.
As soon as we perform these changes and save the file, go to the Task Runner Explorer panel in Visual Studio 2015. Once there, stop the Gulpdefault
task, then re-run it again: a new /wwwroot/css/
folder should be created shortly, together with a freshly-compiled style.css
file inside. Open it and ensure it has the same content placed into the /Scripts/less/style.less
file, then proceed to the next part.
Open the /wwwroot/index.html
file and add the following line within the <head>
block, right below the <meta>
element:
<!-- Stylesheets --> <link rel="stylesheet" type="text/css" href="/css/style.css" media="screen" />
Before going further, it's advisable to run a quick check in order to ensure that everything we made so far is working as it should.
Open the /Scripts/app/home.component.ts
file and remove everything within the styles
block so that it will look like the following:
styles: []
Alternatively, we could entirely remove it, as we're not going to use it anymore.
Once done, run the application in Debug mode by hitting F5 and check if the item-list
components still have their CSS styles applied to them:
They definitely should, since we placed them on the style.less
file that, in its .css
compiled form, should now be linked to our application.