welldone-software / gulp-durandal

Gulp plugin for building durandaljs projects
MIT License
13 stars 19 forks source link

Doesn't bundle files when references included in excluded modules #20

Open AStoker opened 9 years ago

AStoker commented 9 years ago

I have a project where there are test files in the same directory as source files (this keeps our code modular so we can move things around and tests follow). However, when we bundle our code, we don't want to be distributing our tests, so we use the moduleFilter property to exclude files that have the suffix 'Test' (this is general enough for our purposes). And FYI, we use Jasmine/Karma to run our tests.

So, in our durandal application, we use a few widgets. Therefore, in our main.js we require the widget plugin and register our widgets. However, in our test for one of the widgets, we also include the widget plugin. Since that test file is excluded, what seems to be happening is that it is rippling those excluded file's dependencies up. This means that the widget plugin doesn't actually get bundled, along with a handful of other dependencies (that are required by included files) such as jquery, knockout, bootstrap, and so on.

This happens on any module that is required in an excluded file. For instance, if you require knockout on a file that is in the moduleFilter, then knockout will not be bundled. If you require a module that has multiple dependencies in one of the files in the moduleFilter, then that module and all it's dependencies won't be bundled either.

Some Code

config.js

define(function(){
    var config = {
        "baseUrl": "./",//src
        "map": {
        },
        "paths": {              
            "bower_components" : "../bower_components",

            "durandal": "../bower_components/durandal/js",
            "plugins": "../bower_components/durandal/js/plugins",

            "jquery": "../bower_components/jquery/dist/jquery",

            "knockout": "../bower_components/knockout/dist/knockout.debug",    

            "text": "../bower_components/requirejs-text/text",

            "css": "../bower_components/require-css/css",           
            "css-builder": "../bower_components/require-css/css-builder",
            "normalize": "../bower_components/require-css/normalize",

          },    
        "shim": {
        }
    }
    return config;  
})

build.js

gulp.task('clean', function (finished) {
    del(['build/**/*'], finished);
});

gulp.task('index', ['clean'], function () {
    return gulp.src('./src/index.html')
       .pipe(htmlreplace({
           'js': 'main.js',
       }))
       .pipe(gulp.dest('./build'));
});

gulp.task('durandal', ['index'], function(){
    var gulpConfig = {//Some defaults
        verbose: true,
        baseDir: 'src',
        main: 'main.js',
        output: 'main.js',
        minify: false,
        moduleFilter: function (mn) {
            var including = (mn).indexOf('foo') == -1
            return including;
        },

        extraModules: ['bower_components/requirejs/require'],
        rjsConfigAdapter: function (rjs) {
            extend(rjs, config);
            rjs.baseUrl = 'src';

            rjs.findNestedDependencies = true; //Needs to be true as some durandal modules have nested deps for plugins

            return rjs;
        }
    };

    return durandal(gulpConfig)
        .pipe(gulp.dest('build/'))
});

main.js

require(['config'], function(config){
    requirejs.config(config);

    require([
        'jquery', 
        'knockout',
        'durandal/system',
        'durandal/app',
        'plugins/widget',
        ], function(
                $, 
                ko,
                system,
                app,
                widget
        ){   

        system.debug(true);     
        window.ko = ko;     

        app.title ='Gulp Tests';

        app.configurePlugins({
            router: true,
            widget: true,
        });

        widget.registerKind('sideNav');
        widget.mapKind('sideNav', 'widgets/sideNav/view', 'widgets/sideNav/viewmodel');

        app.start().then(function(){
            app.setRoot('shell/shell');
        });

    });
});

foo.js

define(['plugins/widget'], function(){
    //this should cause breaking things;

    return {
        foo: 'bar'
    }
})

Result

This because we exclude foo.js, we also end up excluding all it's dependencies, despite main.js requiring plugins/widget

Let me know if I need to make a repo where you can see this happen

aradjdi commented 8 years ago

+1