Grunt v ASP .NET Core a Visual Studio 2017 - časť 3 final

DOWNLOAD

V predošlej časti sme vytvorili základný cleanTask a buildTask, ktorý v závislosti od zvolenej konfigurácie projektu volá rôzne grunt tasky, a tieto sme nabindovali na build udalosti projektu. Teraz vytvoríme jednoduchú javascriptovú aplikáciu s rôznymi konfiguráciami pre rôzne prostredia a doplníme buildTask tak, aby pre release build vytvoril jednosúborový bundle.

Použijeme nasledovné knižnice:

Tieto knižnice umiestnime do priečinka js/libs.

Aplikácia bude tvorená jednoduchým knockout komponentom app, ktorý umiestnime do priečinka js/components/app:

<div class="app">
   demo
</div>
app.html
.app {
    height
: 1vh;
    min-height
: 100vh;
    display
: flex;
    flex-direction
: column;

    display
: flex;
    position
: absolute;
    left
: 0;
    top
: 0;
    bottom
: 0;
    overflow-y
: scroll;
    right
: -17px;

    .app__content 
{
        flex
: 1 0 auto;
        position
: relative;
        padding
: 20px 0;

        > .container 
{
            width
: 70%;
            max-width
: none;
        
}
    }
}
app.less
define([
    
"require",
    
"module",
    
"jquery",
    
"text!./app.html",
    
"knockout"
], function (require, module, $, view, ko) {
    
var global (function () { return this; })();
    var 
cnf module.config() || {};
    var 
$this = null;

    
// Konštruktor
    
var Model = function (args, info) {
        console.log(
"App : ctor()");

        
$this = this;
    
};

    
// Dispose
    
Model.prototype.dispose = function () {
        console.log(
"App : dispose()");
    
};

    
// Vytvorenie modelu
    
Model.createViewModel = function (params, componentInfo) {
        global.app 
= new Model($.extend({}, cnf, params), componentInfo);

        
$.each(cnf.components || {}, ko.components.register);

        return 
global.app;
    
};

    return 
{
        viewModel: { createViewModel: Model.createViewModel },
        template: view
    }
;
});
app.js

Do priečinka js pridáme súbory config.js (konfigurácia pre prostredie Development) a config.Production.js (konfigurácia pre prostredie Production). Obsah môžeme nateraz nechať rovnaký.

require({
    urlArgs: 
"t=" + (new Date()).getTime(),
    paths: {
        
"jquery""libs/jquery",
        
"knockout""libs/knockout",
        
"text""libs/require.text"
    
},
    config: {
        
"main": {
        },
        
"components/app/app": {
            components: {
            }
        }
    }
}, [
"main"]);
config.js

Ako posledný argument je odkaz na module main, ktorý sa automaticky dotiahne pri spracovaní obsahu súboru config.js.

define([
    
"module",
    
"jquery",
    
"knockout"
], function (module, $, ko) {
    
// Zaregistrujeme komponenty
    
ko.components.register("app", { require: "components/app/app" });
     
    
// Spustime aplikaciu
    
$(function () {
        ko.applyBindings({})
;
    
});
});
main.js

Doplníme obsah súboru Index.cshtml tak, aby sa vždy použila konfigurácia pre aktuálne prostredie:

<body>
    
<app></app>
    
<environment include="Development">
        
<script data-main="@Url.Content("~/js/config.js")" 
                src
="@Url.Content("~/js/libs/require.js")">
        
</script>
    
</environment>
    
<environment exclude="Development">
        
<script data-main="@Url.Content("~/js/config." + Model.EnvironmentName + ".js")" 
                src
="@Url.Content("~/js/libs/require.js")">
        
</script>
    
</environment>
</body>
Index.cshtml

Ak teraz spustíme aplikáciu v konzole sa zobrazí chybová hláška: "Loading failed for the <script> with source "http://localhost:2926/js/libs/require.js".". Je to preto, že pridané javascriptové súbory nie sú v priečinku wwwroot. A tu už prichádza narad grunt. Preto doplníme súbor gruntfile.js o tasky, ktoré prekopírujú zdrojové js súbory a pre build s konfiguráciou Release (ktorá je určená pre prostredie Production) vyrobia bundle pomocou requirejs.

module.exports = function (grunt) {
    
// Konfigurácia grunt taskov
   
grunt.initConfig({
        clean: {
            css: [
                
"wwwroot/css/*"
            
],
            js: [
                
"wwwroot/js/*"
            
],
            cssmin: [
                
"wwwroot/css/*",
                
"!wwwroot/css/site.min.css"
            
],
            html: [
                
"wwwroot/js/components/**/*.html"
            
],
            config: [
                
"wwwroot/js/config.js"
            
]
        },
        copy: {
            css: {
                files: [{
                    expand: 
true,
                    cwd: 
"css/",
                    src: [
"**"],
                    dest: 
"wwwroot/css/",
                    filter: 
"isFile"
                
}]
            },
            js: {
                files: [{
                    expand: 
true,
                    cwd: 
"js/",
                    src: [
"**""!**/*.less"],
                    dest: 
"wwwroot/js/",
                    filter: 
"isFile"
                
}]
            }
        },
        concat: {
            css: {
                options: {
                    process: 
function (src, filepath) {
                        
var fileName filepath.split("/");
                        return 
'/**\n * ' + fileName[fileName.length - 1].replace(".min.css""") + '\n */\n' + src;
                    
}
                },
                src: [
                    
"wwwroot/css/site.min.css",
                    
"wwwroot/css/app.min.css"
                
],
                dest: 
"wwwroot/css/site.min.css"
            
}
        },
        less: {
            options: {
                paths: [
"less"],
                strictMath: 
false
            
},
            src: {
                files: {
                    
"wwwroot/css/site.css""less/site.less",
                    
"wwwroot/css/app.css""js/components/app/app.less"
                
}
            }
        },
        csslint: {
            options: {
                
"universal-selector"false,
                
"order-alphabetical"false,
                
"outline-none"false
            
},
            src: [
                
"wwwroot/css/**/*.css",
                
"!wwwroot/css/**/*.min.css"
            
]
        },
        cssmin: {
            options: {
            },
            build: {
                files: [{
                    expand: 
true,
                    cwd: 
"wwwroot/css",
                    src: [
"*.css""!*.min.css"],
                    dest: 
"wwwroot/css",
                    ext: 
".min.css"
                
}]
            }
        },
        jshint: {
            options: {
                debug: 
true,
                multistr: 
true,
                sub: 
true,
                laxbreak: 
true,
                globals: {
                    jQuery: 
true
                
}
            },
            src: [
                
"gruntfile.js",
                
"js/**/*.js",
                
"!js/libs/*.js"
            
]
        },
        htmllint: {
            options: {
                path: 
false,
                force: 
true,
                reportpath: 
false,
                ignore: [
                    /^Empty heading.*/,
                    /^Start tag seen without seeing a doctype first*/,
                    /is missing a required instance of child element/
                ]
            },
            src: [
                
"js/**/*.html"
            
]
        },
        requirejs: {
            release: {
                options: {
                    appDir: 
"./wwwroot",
                    skipDirOptimize: 
true,
                    writeBuildTxt: 
false,
                    baseUrl: 
"./js",
                    dir: 
"./wwwroot",
                    keepBuildDir: 
true,
                    allowSourceOverwrites: 
true,
                    removeCombined: 
true,
                    preserveLicenseComments: 
false,
                    optimize: 
"uglify",
                    inlineText: 
true,
                    optimizeCss: 
"none",
                    skipModuleInsertion: 
false,
                    paths: {
                        
"jquery""./libs/jquery",
                        
"knockout""./libs/knockout",
                        
"text""./libs/require.text"
                    
},
                    stubModules: [
"text"],
                    modules: [{
                        name: 
"main",
                        create: 
true,
                        stubModules: [
"text"],
                        include: [
                            
"main",
                            
"components/app/app"
                        
]
                    }]
                }
            }
        },
        uglify: {
            options: {
                stripBanners: 
false,
                sourceMap: 
false
            
},
            release: {
                files: [{
                    expand: 
true,
                    cwd: 
"wwwroot/js",
                    src: [
                        
"**/*.js",
                        
"!*.min.js"
                    
],
                    dest: 
"wwwroot/js"
                
}]
            }
        }
    })
;

    
// Nacítanie grunt modulov
    // ...
    
grunt.loadNpmTasks("grunt-contrib-jshint");
    
grunt.loadNpmTasks("grunt-html");
    
grunt.loadNpmTasks("grunt-contrib-requirejs");
    
grunt.loadNpmTasks("grunt-contrib-uglify");

    
// Build task
    
function buildTask() {
        
// ...
        
switch (cnf.toUpperCase()) {
            
case "DEBUG":
                tasks.push(
"copy:css");
                
tasks.push("less");
                
tasks.push("csslint");
                
tasks.push("jshint");
                
tasks.push("htmllint");
                
tasks.push("copy:js");
                break;
            case 
"RELEASE":
                grunt.config(
"jshint.options.debug"false);

                
tasks.push("copy:css");
                
tasks.push("less");
                
tasks.push("csslint");
                
tasks.push("jshint");
                
tasks.push("htmllint");
                
tasks.push("cssmin");
                
tasks.push("concat:css");
                
tasks.push("clean:cssmin");
                
tasks.push("copy:js");
                
tasks.push("requirejs:release");
                
tasks.push("clean:html");
                
tasks.push("clean:config");
                
tasks.push("uglify:release");
                break;
            default
:
                grunt.fail.fatal(
"Unknown configuration '" + cnf + "'");
                break;
        
}
        
// ...
    
}
}
;
gruntifle.js

A toť vše. Kompletné vzorové riešenie je možné nájsť aj na mojom github-e.

Publikované Wednesday, April 25, 2018 7:42 AM xxxmatko

Komentáre

Bez komentárov