Skip to content

robojones/gulp-webrequire

Repository files navigation

gulp-webrequire

Use require in the browser with this gulp plugin.

CircleCI License: MIT

Installation

npm install --save gulp-webrequire

Key features

  • Use require in you client side javascript.
  • Require NPM modules.
  • Full sourcemap support with gulp-sourcemaps.
  • Dynamic package creation with smart packing.
  • Script tag generator.

Table of contents

How it works

The difference between this plugin and other solution like webpack is, that it does not create a single .js file containing all of your code. Instead it detects the references between your modules and builds packages out of them using a smart packing algorithm.

Smart packing?

The most important facts are:

  • Every module that is not required by any other module is considered an entry point. You can generate script tags for these entry points later on by using the api.
  • No module will be included multiple packs. → All files can be cached by the browser and no module will be loaded twice.

So why should I use this?

The advantage of not packing all your code into one big .js file is, that you can decide when a resource is loaded. So instead of downloading a whole bunch of JavaScript, where you only need a fraction of it, you can load only what's needed. This lets you take advantage of the browser cache and improves your website performance.

How is this better than adding script-tags the old-fashioned way?

gulp-webrequire generates script tags with the async attribute. This will allow your JavaScript files to be loaded parallely. You don't need to worry about the order in which your scripts are executed - If one of your scripts requires another one, gulp-webrequire will make sure that the required file is executed first. It is also guaranteed that your scripts will be executed after the "DOMContentLoaded" event was emitted.

Setup with gulp

Example with gulp-webrequire and gulp-minify

In your gulpfile.json:

const gulp = require('gulp')
const minify = require('gulp-minify')
const sourcemaps = require('gulp-sourcemaps')
const { webrequire } = require('gulp-webrequire')

const project = webrequire()

gulp.task('javascript', function () {
  return gulp.src('src/**/*.js')
    .pipe(sourcemaps.init())
    .pipe(project.through())
    .pipe(minify())
    .pipe(sourcemaps.write())
    .pipe(gulp.dest('public/'))
})

gulp.task('default', ['javascript'])

Project

You can create a project using the factory:

const { webrequire } = require('gulp-webrequire')
const project = webrequire(options)

Or by using the class directly:

const { Project } = require('gulp-webrequire')
const project = new Project(options)
  • options
    • entryPoints <string[]> - Manually add entry points if they are not automatically detected. (In theory you will never have to use this)
    • modulesDir_ <string> - Will be used in the sourcemaps as the directory that contains NPM modules that you use in your code. This is purely aesthetic. (Default: modues/)

Project#through()

This method returns a stream that you can use in your gulp task to pipe files through. You must create a new stream for each gulp task.

const gulp = require('gulp')
const { webrequire } = require('gulp-webrequire')

// Create a project
const project = webrequire()

gulp.task('javascript', function () {
  return gulp.src('src/**/*.js')
    .pipe(project.through()) // This is where the magic happens.
    .pipe(gulp.dest('public/'))
})

How to find out what script tags need to be added to your HTML

Gulp-webrequire comes with an extremely nice api that you can use in your code (e.g. directly in your view engine).

const { generateTags, setup } = require('gulp-webrequire')

setup({ base: 'public/js' })
generateTags(['login.js', 'menu.js'])

The generateTags method will find all js files that are being imported in the login.js and menu.js file. It will then return HTML script tags for these files as one big string. Your can use the returned string to render it into your website's HTML.

generateTags()

This method allows you to generate scripttags for all files that are related to an entry point.

const { generateTags } = require('gulp-webrequire')
generateTags(entryPoint, options)
  • entryPoints <string|string[]> - Entry points to your code relative to the base directory. (The file extension should be set.)
  • options
    • base <string> - The directory that contains your public javascript files.
    • tagGenerator <function> - A function that receives a path and generates a script-tag for it. The path is relative to the base directory and does not begin with a /.
    • cache <boolean> - Gulp-webrequire will cache which files are in which packs. To disable this behaviour you can set this option to false. (default: true)

setup()

With this method you can change default options for the generateTags method.

const { setup } = require('gulp-webrequire')
setup(options)
  • options - The same ones that your can set in the generateTags method.

Examples

Express & EJS

Your nodejs app:

const app = require('express')()
const { generateTags, setup } = require('gulp-webrequire')

setup({
  base: 'public/js'
})

app.get('/login', function(req, res){ 
  const tags = generateTags('login.js')
  res.render('index', {
    scriptTags: tags
  })
})

app.listen(80)

In your EJS view:

<html>
  <head>
    <title>Login</title>
    <%- scriptTags %>
  </head>
  <body>
    ...your html...
  </body>
</html>

Marko view engine

$ var webrequire = require('gulp-webrequire').generateTags;
html
  head
    title -- Login
    -- $!{webrequire('login.js', { base: 'public/js' })}
  body
    ...your website...