10

I try to learn gulp. I have a task which concat all js lib into one lib.min.js

gulp.task("lib-js:build", function () {
    return gulp.src(templates[template].src.libsJs)
        .pipe(concat("libs.min.js"))
        .pipe(uglify())
        .pipe(gulp.dest(templates[template].dist.js));
});

variable templates[template].src.libsJs is a array with following values:

var templates = {
    balmy: {
        dist: {
            default: "templates/balmy/dist",
            html: "templates/balmy/dist/",
            js: "templates/balmy/dist/resources/js/",
            css: "templates/balmy/dist/resources/css/",
            fonts: "templates/balmy/dist/resources/fonts/",
            img: "templates/balmy/dist/resources/img/"
        },
        src: {
            html: "templates/balmy/*.html",
            js: "templates/balmy/resources/js/*.js",
            css: "templates/balmy/resources/css/balmy.css",
            fonts: "templates/balmy/resources/fonts/**/*.*",
            fontsCss: "templates/balmy/resources/css/fonts.css",
            img: "templates/balmy/resources/img/**/*.*",
            libsJs: [
                "lib/jquery/v3.1.1/jquery-3.1.1.min.js",
                "lib/jquery-easing/v1.3/jquery.easing.min.js",
                "lib/bootstrap/v4.0.0-alpha.6/bootstrap.min.js",
                "lib/magnific-popup/v1.1.0/magnific-popup.js",
                "lib/owl-carousel/v2.2.1/owl.carousel.min.js",
                "lib/bootstrap-multiselect/bootstrap-multiselect.min.js",
                "lib/bootstrap-multiselect/bootstrap-multiselect-collapsible-groups.min.js",
                "lib/viewportchecker/v1.8.7/viewportchecker.min.js"
            ],
            libsCss: [
                "lib/owl-carousel/v2.2.1/owl.carousel.min.css",
                "lib/owl-carousel/v2.2.1/owl.theme.default.min.css",
                "lib/animation/v3.5.1/animate.min.css",
                "lib/magnific-popup/v1.1.0/magnific-popup.css",
                "lib/bootstrap-multiselect/bootstrap-multiselect.min.css"
            ]
        },
        needBootstrap: true
    }
}

Where templates is variable which describe all possible site template. When I excecute:

gulp build --template balmy

I also set parametr with name of template which I would like build.

After that I include this js file into my html and try to use a owl carousel function:

<script src="resources/js/libs.min.js"></script>

<script>
    $(document).ready(function () {

        $(".all-events-carousel").owlCarousel({
            loop: true,
            margin: 10,
            items: 1,
            animateOut: 'slideOutDown',
            animateIn: 'flipInX',
            autoplay: true
        })
    });
</script>

This code close to bottom of body. In browser console I see next exception:

stacke trace

But if delete from html a concat js and add all concated js files it will work fine.

This is the result libs.min.js which only concatenated and didn't minified (without call uglify)

Maybe anybody know why does it happen?

HAYMbl4
  • 1,450
  • 2
  • 15
  • 29
  • What is `template` in `templates[template]`? – Phil Aug 25 '17 at 05:33
  • Also, if all those "lib" files are already minified, you're just wasting CPU cycles running them through `uglify` – Phil Aug 25 '17 at 05:34
  • @Phil, I changed my question and added information about templates variable. – HAYMbl4 Aug 25 '17 at 05:41
  • Is that a typo `/magnific-pupup.js` ? – Denis L Aug 25 '17 at 05:42
  • @Deliaz, yes, you are right – HAYMbl4 Aug 25 '17 at 05:45
  • Can you upload the minified result file into somewhere to let us examine it? – Zoltán Tamási Aug 31 '17 at 05:08
  • @ZoltánTamási, I added the result minified file several days ago and wrote about this upder your answer. Can you download it [here](https://yadi.sk/d/ZWh6pAun3MJvWx)? – HAYMbl4 Aug 31 '17 at 05:19
  • Sorry I missed that completely. I was having a look at it but couldn't see any issue at first glance unfortunately. I would place some debug logs in the minified file where owlCarousel adds itself to $.fn for example, also I would log $.fn at several places to see if any plugin reinitializes it in some way, etc. – Zoltán Tamási Aug 31 '17 at 08:41

4 Answers4

4

It's not a good practice usually to run the uglify plugin on already minified files. I can see that most of your referred JavaScript files are already minified.

Minification in general can potentially remove exposed functionality.

Please try to remove the uglify call from the chain and see if that works.

Zoltán Tamási
  • 12,249
  • 8
  • 65
  • 93
  • I already tried this several days ago and it didn't resolve the problem – HAYMbl4 Aug 25 '17 at 05:42
  • I attached the result `libs.min.js` to the question – HAYMbl4 Aug 25 '17 at 06:04
  • Can you provide an example of when this would happen? – Our_Benefactors Aug 30 '17 at 14:03
  • @Our_Benefactors I saw this scenario only when one tries to rely on variable, function or class names at runtime and those get renamed at minification. For example see this https://stackoverflow.com/questions/11264109/microsoft-ajax-minifier-renames-my-function-names I could tell a more natural real-life example as well, for example when using TypeScript you're almost always stuck whenever you'd want to rely on `myclass.constructor.name` as it will likely be something like `"a"` because TS first introduces the class and then exposes it in an explicit export or namespace property assignment. – Zoltán Tamási Aug 31 '17 at 04:52
1

I checked your attached libs.min.js file and you are missing Tether for bootstrap 4. See this question to resolve it: How to fix the error; 'Error: Bootstrap tooltips require Tether . I quickly tried to put together your libs.min.js together with Tether from CDN and the owlCarousel CSS in an index.html file and it works:

<!DOCTYPE html>
<html>
    <head>
        <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/OwlCarousel2/2.2.1/assets/owl.carousel.min.css">
        <script src="https://npmcdn.com/tether@1.2.4/dist/js/tether.min.js"></script>
        <script src="libs.min.js" type="text/javascript"></script>
    </head>
    <body>
        <div class="owl-carousel owl-theme">
            <div class="item"><h4>1</h4></div>
            <div class="item"><h4>2</h4></div>
            <div class="item"><h4>3</h4></div>
            <div class="item"><h4>4</h4></div>
            <div class="item"><h4>5</h4></div>
            <div class="item"><h4>6</h4></div>
            <div class="item"><h4>7</h4></div>
            <div class="item"><h4>8</h4></div>
            <div class="item"><h4>9</h4></div>
            <div class="item"><h4>10</h4></div>
            <div class="item"><h4>11</h4></div>
            <div class="item"><h4>12</h4></div>
        </div>
        <script>
            $('.owl-carousel').owlCarousel({
                loop:true,
                margin:10,
                nav:true,
                responsive:{
                    0:{
                        items:1
                    },
                    600:{
                        items:3
                    },
                    1000:{
                        items:5
                    }
                }
            });
        </script>
    </body>
</html>
vl4d1m1r4
  • 1,688
  • 12
  • 21
  • hm.. thank you.. I will check this. But it is not clear to me. When I included all libs without concatenation them into one file I also didn't add the thecher lib. Yes I saw the exception in the browser about this but all worked fine. Are you realy think that missing the thecher lib it is the main problem? – HAYMbl4 Aug 31 '17 at 16:36
  • 2
    Yes, since all libraries are included in one file the execution of the javascript ends when the error occurs and the OwlCarousel is placed afterwards so it never gets a chance to execute. When you included them separately the browser tried to execute bootstrap script and failed. Then it went on to execute the other scripts included. That is why it worked. – vl4d1m1r4 Aug 31 '17 at 16:57
  • I didn't read links that you attached yet. But I tried to add `techer.js` to libs (before the `bootstrap.min.js`) which I concatenate into one file. And all worked. Thank you very much for your time. I suppose this is stupid mistake but it cool to resolved it! – HAYMbl4 Aug 31 '17 at 17:42
  • Can you give one more advise? Is it possible that after concatenation several libs into one file they will be conflict and I get incorrect work of their functions? How can I be sure that all fine and I can work with this file and will not afraid bugs? Is it enought to validate files by the `gulp js-validation` plugin (look to the answer from @lofihelsinki)? Can you give more detail answer for this theme and I will mark the answer like correct and give to you the bounty. – HAYMbl4 Aug 31 '17 at 17:42
  • When concatenating multiple libraries there is definitely a possibility for conflicts, especially when libraries pollute the global scope. Usually all libraries expose a single global namespace by default. (like jQuery exposes `$` and/or `jQuery`) and you only have to worry that there are no conflicts between them. They provide some mechanism for controlling this with `noConflict` methods which remove the global namespaces but then you must take care of correctly passing around the reference to the libraries in your code,see https://en.wikipedia.org/wiki/Immediately-invoked_function_expression – vl4d1m1r4 Aug 31 '17 at 18:09
  • Also have a look at [Webpack](https://webpack.js.org/) or [RequireJS](http://requirejs.org/) for advanced topics on bundling resources in order not to worry when creating a single file that contains all libraries and resources. – vl4d1m1r4 Aug 31 '17 at 18:12
  • Thank you one more time, I will learn these resources tomorrow – HAYMbl4 Aug 31 '17 at 18:24
0

I would add JS syntax checking before and after concat() and leave out uglify() for the time being. That might help to narrow down the problem.

const jsValidate = require('gulp-jsvalidate');

gulp.task("lib-js:build", function () {
    return gulp.src(templates[template].src.libsJs)
       .pipe(jsValidate())
       .pipe(concat("libs.min.js"))
       .pipe(jsValidate())
       .pipe(gulp.dest(templates[template].dist.js));
});
lofihelsinki
  • 2,491
  • 2
  • 23
  • 35
  • Thank you. I tried now but the js validate plugin didn't find any errors. Task worked clearly and outputted to the log only information abount starting and finishing. – HAYMbl4 Aug 30 '17 at 17:20
0

Maybe there is a naming conflict in those js files, there are two file both has a variable named $ and the latter is not a jQuery obj, and when you add files separately the jQuery load latter exactly. You can do a search in those files.

sinbar
  • 933
  • 2
  • 7
  • 25