webpack-contrib / istanbul-instrumenter-loader

Istanbul Instrumenter Loader
MIT License
273 stars 65 forks source link

Webpack: Coverage shows in production build #18

Closed misantronic closed 8 years ago

misantronic commented 8 years ago

I generate my build with grunt. The task look like this:

grunt.registerTask('build', [
  'karma:unit',
  'webpack:build'
]);

So what happens is that all tests run and for coverage-support I add the instrumenter as a preLoader:

webpackConfig.module.preLoaders = [
    {
        test: /\.js$/,
        include: path.resolve('app/'),
        loader: 'istanbul-instrumenter'
    }
];

This works fine for me. So far, so good. After this task finished and webpack:build is running, in which the preLoader is not even preset, the compiled source still shows the coverage like

var t = Function("return this")();
        t.__coverage__ || (t.__coverage__ = {}), t = t.__coverage__, t["/Users/name/src/project/app/entry.js"] || (t["/Users/name/src/project/app/entry.js"] = {
            path: "/Users/name/src/project/app/entry.js",
            s: { 1: 0, 2: 0, 3: 0, 4: 0, 5: 0, 6: 0, 7: 0, 8: 0, 9: 0, 10: 0, 11: 0, 12: 0, 13: 0 },
            b: {
                1: [
                    0,
                    0
                ]
            },
            f: { 1: 0, 2: 0 },
            fnMap: { 1: { name: "(anonymous_1)", line: 5, loc: { start: { line: 5, column: 34 }, end: { line: 5, column: 53 } } }, 2: { name: "(anonymous_2)", line: 13, loc: { start: { line: 13, column: 54 }, end: { line: 13, column: 73 } } } },
            statementMap: { 1: { start: { line: 1, column: 0 }, end: { line: 1, column: 26 } }, 2: { start: { line: 3, column: 0 }, end: { line: 3, column: 25 } }, 3: { start: { line: 5, column: 0 }, end: { line: 23, column: 18 } }, 4: { start: { line: 6, column: 4 }, end: { line: 6, column: 44 } }, 5: { start: { line: 7, column: 4 }, end: { line: 7, column: 50 } }, 6: { start: { line: 8, column: 4 }, end: { line: 8, column: 52 } }, 7: { start: { line: 10, column: 4 }, end: { line: 10, column: 50 } }, 8: { start: { line: 13, column: 4 }, end: { line: 22, column: 30 } }, 9: { start: { line: 14, column: 8 }, end: { line: 14, column: 49 } }, 10: { start: { line: 16, column: 8 }, end: { line: 18, column: 9 } }, 11: { start: { line: 17, column: 12 }, end: { line: 17, column: 24 } }, 12: { start: { line: 20, column: 8 }, end: { line: 20, column: 27 } }, 13: { start: { line: 25, column: 0 }, end: { line: 25, column: 33 } } },
            branchMap: {
                1: {
                    line: 16,
                    type: "if",
                    locations: [
                        { start: { line: 16, column: 8 }, end: { line: 16, column: 8 } },
                        { start: { line: 16, column: 8 }, end: { line: 16, column: 8 } }
                    ]
                }
            },
            code: [
                "var $ = require('jquery');",
                "",
                "var defer = $.Deferred();",
....etc

This will not happen if I never add the instrumenter as a preLoader. Why is it still present in my build task even though the webpack.config does not contain it?

deepsweet commented 8 years ago

Looks like you are sharing your webpack config between karma:unit and 'webpack:build' grunt tasks, but I can't tell how without seeing the whole setup. Just make sure that your build config doesn't contain isparta in preLoaders section.

misantronic commented 8 years ago

Thanks for your reply. I took care of not sharing the webpack-config in the task but cloning them:

So in my karma setup I do

var webpackConfig = _.extend(
    {},
    require('./webpack.config'),
    {
        plugins: [
            ...
        ]
    }
);

// instrument only testing sources with Istanbul
webpackConfig.module.preLoaders = [
    {
        test: /\.js$/,
        include: path.resolve('app/'),
        loader: 'istanbul-instrumenter'
    }
];

Is it possible, that the preloader caches something for later use?

deepsweet commented 8 years ago

istanbul-instrumenter uses only internal webpack cache within one run... very strange.

misantronic commented 8 years ago

It actually did share the preLoader between the tasks - although I did clone it. Quite strange.

I fixed it by adding a task before webpack:build which removes the instrumenter from the preLoaders:

grunt.task.registerTask('removeInstrumenter', 'Removes instanbul-instrumenter from webpack preloaders', function () {
    webpackConfig.module.preLoaders = _.filter(webpackConfig.module.preLoaders, function (loaderObj) {
        return loaderObj.loader !== 'istanbul-instrumenter'
    });
});