babel / gulp-babel

Gulp plugin for Babel
https://babeljs.io
MIT License
1.32k stars 120 forks source link

When used with gulp-source-maps build fails with error "Path must be a string. Received undefined" #154

Open MarkiyanPyts opened 6 years ago

MarkiyanPyts commented 6 years ago

After updating my node to "v8.11.1" and npm to "5.6.0" gulp build gets broken if used with "gulp-source-maps"

Here is my gulpfile:

"use strict";

let tabReloaderInstance,
    gulp = require("gulp"),
    gulpSourcemaps = require("gulp-sourcemaps"),
    mergeStream = require("merge-stream"),
    yargs = require("yargs"),

    argv = yargs.argv,
    rootPath = argv.JenkinsCartridgesPath || __dirname,

    // Babel
    babel = require("gulp-babel"),
    gulpBrowserify = require("gulp-browserify"),
    es2015 = require("babel-preset-es2015");

/* JavaScript paths */
var JS_PATHS = [
        {
            "wtc" : "int_acf_core/cartridge/js/**/*.js",
            "src" : "int_acf_core/cartridge/js/modules_system.js",
            "dst" : "int_acf_core/cartridge/static/default/js"
        }
    ];

// generate js
gulp.task("js", () => {
    var streams = mergeStream();
    var optBrfy = {"debug" : true}

    // Needed when task is run from Jenkins so that Browserify can resolve the modules installed with NPM
    if (argv.JenkinsBuild) {
        optBrfy = xtend(optBrfy, {"paths" : [argv.JenkinsNodeModulesPath]});
    }

    JS_PATHS.forEach(function(p) {
        var srcPath = path.join(rootPath, p.src),
            dstPath = path.join(rootPath, p.dst);

        streams.add(gulp.src(srcPath)
            .pipe(gulpBrowserify(optBrfy))
            .pipe(gulpSourcemaps.init())
            .pipe(babel({
                presets: [es2015]
            }))
            .pipe(gulpSourcemaps.write('./'))
            .pipe(gulp.dest(dstPath)));
    });

    return streams;
});

js task fails with error "Path must be a string. Received undefined"

I traced the error to "node_modules/gulp-babel/index.js" line 39

where you gulp-babel has following code as this point:

if (file.sourceMap && res.map) {
    res.map.file = replaceExtension(res.map.file);
    applySourceMap(file, res.map);
}

Problem is that res.map.file here is undefined even though file.sourceMap and res.map has big JSON objects returned.

this breaks the build. Before update this setup was working properly.

MarkiyanPyts commented 6 years ago

Attaching example project with an issue, issue.zip

I have also discovered that browserify can be a problem here as well, if it's removed from the pipeline it works.

robbietjuh commented 6 years ago

Just wanted to add in my two cents. It seems this issue is related to babel-core merging source maps. If multiple files have been processed by babel-core, it will merge their source maps. This causes the file attribute to be lost (instead, the sources attribute is created, containing all relevant files that have been merged).

gulp-babel however, expects the file attribute to still be there. It will pass res.map.file into replaceExtension, which will evaluate to null because the file attribute was removed. replaceExtension will in turn throw an error because it does not know how to handle file=null.

By further digging it seems this issue may indeed also be related to browserify. The source maps all contain the file node_modules/browser-pack/_prelude.js - which seems to be related to browserify. Removing browserify will fix the issue as the source map won't have to be merged for the extra browserify file.

Not sure yet on how to fix this (except for dropping browserify, if that's part of your options), but still wanted to put this up here in case others search for this issue.