javascriptnode.jsnpmgulpgulp-babel

Connecting files via import does not work


For a day now, I can not understand why babel for gulp does not work for me, or I incorrectly connect the modules ...
The error in the browser is like this:

Uncaught ReferenceError: require is not defined
  at main.min.js:1

I connect the modules like this:

import focusVisible from "focus-visible";

Code in main.min.js file:

"use strict";var e;(e=require("focus-visible"))&&e.__esModule;

Gulp task:

const { src, dest, series, watch, parallel } = require('gulp'),
      fileinclude = require('gulp-file-include'),
      rename = require("gulp-rename"),
      uglify = require('gulp-uglify-es').default,
      babel = require("gulp-babel"),
      notify = require("gulp-notify"),
      browserSync = require("browser-sync").create()

const changingScripts = () => {
  return src(['src/js/main.js', 'src/js/pages/**/*.js'])
    .pipe(babel())
    .pipe(fileinclude())
    .pipe(dest('dist/js'))
    .pipe(uglify({
      toplevel: true
    }).on('error', notify.onError()))
    .pipe(rename({
      extname: '.min.js'
    }))
    .pipe(dest('dist/js'))
    .pipe(browserSync.stream())
}

The package.json file is like this:

{
  "name": "project_name",
  "version": "1.0.0",
  "description": "some description of the project",
  "scripts": {},
  "keywords": ["keyword_1", "keyword_2", "keyword_3"],
  "author": "project_author",
  "license": "ISC",
  "devDependencies": {
    "@babel/core": "^7.16.0",
    "@babel/eslint-parser": "^7.16.3",
    "@babel/preset-env": "^7.16.4",
    "@babel/register": "^7.16.0",
    "browser-sync": "^2.27.7",
    "eslint": "^8.2.0",
    "eslint-config-airbnb-base": "^15.0.0",
    "eslint-plugin-import": "^2.25.3",
    "gulp": "^4.0.2",
    "gulp-babel": "^8.0.0",
    "gulp-file-include": "^2.3.0",
    "gulp-notify": "^4.0.0",
    "gulp-rename": "^2.0.0",
    "gulp-uglify-es": "^3.0.0"
  }
}

The .babelrc file looks like this:

{
  "presets": ["@babel/preset-env"]
}

It seems like everything has applied what is needed.
If you can help, I will be grateful.
The whole project got stuck because of this error ...
It is advisable to solve the problem without using Webpack :)


Solution

  • It seems like you could be missing a build step where you transform your code to be browser compatible. The require method is not available in the browser.

    You have to use a tool which transforms your code so that it can be ran in the browser. One such tool is Browserify, another is rollup, and there may be more. These tools, generally speaking, bundle dependency sources in conjunction with your application code, which allows require statements to be transformed into some other pattern the browser does understand.

    You can think of it like this (example is simplified):

    Code written by you

    // main.js
    const stringify = require('stringify')
    
    alert(stringify({ error: "No authorization" })
    

    Dependency source in node_modules

    // node_modules/stringify/index.js
    function stringify(obj) {
      return JSON.stringify(obj);
    }
    
    expost.default = stringify
    

    Bundle result

    // dist/main.js
    function stringify(obj) {
      return JSON.stringify(obj);
    }
    
    alert(stringify({ error: "No authorization" })
    

    Gulp hosts an official example of usage in their repository for browserify:

    'use strict';
    
    var browserify = require('browserify');
    var gulp = require('gulp');
    var source = require('vinyl-source-stream');
    var buffer = require('vinyl-buffer');
    var log = require('gulplog');
    var uglify = require('gulp-uglify');
    var reactify = require('reactify');
    
    gulp.task('javascript', function () {
      // set up the browserify instance on a task basis
      var b = browserify({
        entries: './entry.js',
        debug: true,
        // defining transforms here will avoid crashing your stream
        transform: [reactify]
      });
    
      return b.bundle()
        .pipe(source('app.js', { sourcemaps: true }))
        .pipe(buffer())
            // Add transformation tasks to the pipeline here.
            .pipe(uglify())
            .on('error', log.error)
        .pipe(gulp.dest('./dist/js/', { sourcemaps: '../sourcemaps/' }));
    });
    

    Gulp Version control: Browserify + Transforms

    I attempted to create an example for you, but it's difficult to say what the most usable gulp script would be for your project. I'll add an example, but please don't consider it as a fix that's ready for general use. It attempts to mimic the behaviour your current gulp script has. You may want other behaviour in the long run for instance because the bundling this script creates may not be as optimized as other configurations or tooling would allow.

    const { dest } = require("gulp"),
      browserify = require("browserify"),
      babelify = require("babelify"),
      glob = require("glob"),
      source = require("vinyl-source-stream"),
      fileinclude = require("gulp-file-include"),
      rename = require("gulp-rename"),
      uglify = require("gulp-uglify-es").default,
      notify = require("gulp-notify"),
      browserSync = require("browser-sync").create(),
      es = require("event-stream");
    
    const changingScripts = (done) => {
      // Define files you want to have as inputs
      var files = ["src/js/main.js", ...glob.sync("src/js/pages/**/*.js")];
      // Bundle each file separately so that file structure is preserved in
      // dist
      var tasks = files.map((file) => {
        return (
          browserify({
            entries: [file],
            debug: true,
            transform: [
              // Apply babel transforms here so that browserify knows how to bundle
              // the files
              babelify.configure({
                presets: ["@babel/preset-env"],
              }),
            ],
          })
            .bundle()
            // Transform the stream content bable bundling returns into a gulp
            // friendly format
            .pipe(source(file))
            // Not sure how fileinclude is used in your project. May be that it
            // doesn't work when it's configured in this way.
            .pipe(fileinclude())
            .pipe(dest("dist/js"))
            .pipe(
              uglify({
                toplevel: true,
              }).on("error", notify.onError())
            )
            .pipe(
              rename({
                extname: ".min.js",
              })
            )
            .pipe(dest("dist/js"))
            .pipe(browserSync.stream())
        );
      });
    
      return es.merge(tasks).on("end", done);
    };
    
    exports.default = changingScripts;
    

    Gulp: Creating multiple bundles with Browserify