V
V
Vlad2021-05-06 23:55:35
gulp.js
Vlad, 2021-05-06 23:55:35

Gulp + webpack-stream. How to create multiple entry points with the creation of files of the same name on the output?

There is a Gulp + Webpack build for building js files through the webpack-stream plugin.
There was a necessity to have several several entry points.
Here are the paths:

/* source paths, production paths and paths for files we need to watch */
const path = {
    build: {
        /* ... */
        js: 'assets/build/js/',
        css: 'assets/build/css/',
        /* ... */
    },
    src: {
        /* ... */
        js: ['assets/src/js/main.js', 'assets/src/js/main-01-test.js'], // js entry points, string when one, array when several
        style: ['assets/src/style/main.scss', 'assets/src/style/main-01-test.scss'], // scss entry points, string when one, array when several
        /* ... */
    },
    watch: {
        /* ... */
        js: 'assets/src/**/*.js',
        css: 'assets/src/**/*.scss',
        /* ... */
    },
    clean: './assets/build/*'
};


When I build scss, then there are no problems, webpack is not used there.
And it looks like this:

// style build
async function css_build() {
    let stylePath = path.src.style;
    if (stylePath.isArray) {
        stylePath.map( file => css_build_file(file) );
    } else {
        css_build_file(stylePath);
    }
}
// inner function to a current scss entry point file
function css_build_file(file) {
    return gulp.src(file) // get only main.scss in which we have some imports
        .pipe(plumber()) // gulp plugins bug tracking
        .pipe(gulpif(devMode, sourcemaps.init())) // initialize source maps
        .pipe(sass()) // scss -> css
        .pipe(autoprefixer({ // add vendor prefixes to CSS
            overrideBrowserslist: ['last 2 versions'], // last two versions recommended
            cascade: false
        }))
        .pipe(gulp.dest(path.build.css)) // build temporary css
        .pipe(rename({ suffix: '.min' })) // add prefixes to the built file
        .pipe(cleanCSS({ level: { 1: { specialComments: 0 } } })) // minify CSS and disable even special comments
        .pipe(gulpif(devMode, sourcemaps.write('./')))  // write source maps
        .pipe(gulp.dest(path.build.css)) // build final css
        .pipe(browserSync.reload({ stream: true })); // browser-sync reload
}


js I do like this:
// js build
async function js_build() {
    let jsPath = path.src.js;
    if (jsPath.isArray) {
        jsPath.map( file => js_build_file(file) );
    } else {
        js_build_file(jsPath);
    }
}
// inner function to a current js entry point file
function js_build_file(file) {
    return gulp.src(file)
        .pipe(webpackStream({
            mode: `${(devMode === true) ? 'development' : 'production'}`, // pass the current mode for webpack
            output: {
                filename: `[name].js`,  // specify just one output file, same name as source
            },
            module: {
                rules: [
                    {
                        test: /\.(js)$/,    // get all js-files
                        exclude: /(node_modules)/, // exclude development modules folder
                        loader: 'babel-loader', // convert ES6 into a backwards compatible version of JS
                        query: {
                            presets: ['@babel/env'] // use babel preset
                        }
                    },
                ]
            },
            optimization: {
                minimize: true,
                minimizer: [new TerserPlugin()],
            },
        })).on('error', function handleError() {
            this.emit('end')
        })
        .pipe(gulp.dest(path.build.js))  // build temporary js
        .pipe(rename({ suffix: '.min' })) // add suffix to the filename
        .pipe(gulp.dest(path.build.js)) // build final js
        .pipe(browserSync.reload({ stream: true })); // browser-sync reload
}


The main-01-test.js file is not created on the build, for some reason everything flies to main.js.
After all, I go through the array, and in the js_build_file (file) function I specify:
output: {
        filename: `[name].js`, 
},


A new output file should be created and named main-01-test.js,
but for some reason everything flies to main.js
Why? Multiple webpack-streams not possible? How to fix?

Thank you.

Answer the question

In order to leave comments, you need to log in

1 answer(s)
V
Vlad, 2021-05-08
@Vextor-ltd

Understood.
1) It is not necessary to sort through the array with files. gulp.src() handles this. You just need to pass an array there.
2) Well, since I prescribe all the files and paths to them at the beginning of the whale starter to work with the gulp.src () method, in this case the Entrypoint files are placed in an array:

const path = {
    build: {
        /* ... */
        js: 'assets/build/js/',
        /* ... */
    },
    src: {
        /* ... */
        js: ['assets/src/js/main.js', 'assets/src/js/main-01-test.js']
/* ... */

..then inside the js-task function, you just need to convert this array into an object with properties that are the names of these files without permissions, and add this property to the Webpack config object.
Here is that function:
function js_build() {

    let webpackConf = {
        mode: `${(devMode === true) ? 'development' : 'production'}`, // current mode for webpack
        output: {
            filename: `[name].js`,  // the same name as the source
            sourceMapFilename: '[name].map'
        },
        module: {
            rules: [
                {
                    test: /\.(js)$/,    // get all js-files
                    exclude: /(node_modules)/, // exclude development modules folder
                    loader: 'babel-loader', // convert ES6 into a backwards compatible version of JS in older browsers
                    query: {
                        presets: ['@babel/env'] // use babel preset
                    }
                },
            ]
        },
        optimization: {
            minimize: true,
            minimizer: [new TerserPlugin()],
        },
    };

    // convert Gulp array into entry property for Webpack
    let fileName = null;
    let entryObj = {};
    path.src.js.map((filePath) => {
      fileName = filePath.split('/').pop().split('.').slice(0, -1).join('.');
      entryObj[fileName] = filePath;
    });

    // add converted entry property to Webpack    
    webpackConf.entry = entryObj;

    return gulp.src(path.src.js)
        .pipe(webpackStream(webpackConf)).on('error', function handleError() {
            this.emit('end')
        })
        .pipe(gulp.dest(path.build.js))  // build js
        .pipe(rename({ suffix: '.min' })) // add suffix to the filename
        .pipe(gulp.dest(path.build.js)) // build final min js
        .pipe(browserSync.reload({ stream: true })); // browser-sync reload
}

exports.js_build = js_build;

In short, here is such a topic for Galp using Webpack to build js files with several entry points. Maybe someone will come in handy :)

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question