Webpack DllPlugin with gulp: cannot find module '... vendor-manifest.json'

I have a fairly large React application built with webpack 2. The application is embedded in a Drupal site as a SPA on an existing site. The Drupal site has a complex gulp build setup and I can't replicate it with webpack, so I decided to keep it.

I split my React application into several parts using the DllPlugin / DllReferencePlugin compiler which is dumped out of the box in webpack 2. This works great and I get a nice set of providers when building with webpack.

The problem is that when I try to run my webpack config in gulp, I get an error. I may be wrong as I haven't been able to find much documentation on this approach, but still it doesn't work for me.

It looks like it is trying to include the manifest file from my vendor package before building it.

Whenever I run one of my specific gulp tasks, for example gulp react-vendor

, I get an error saying that it cannot resolve the vendor-manifest.json file.

If I, on the other hand, run webpack --config=webpack.dll.js

in my terminal, webpack compiles just fine and no error.

I have included what I believe are the relevant files. Any help on this is appreciated.

webpack.config.js

// Use node.js built-in path module to avoid path issues across platforms.
const path = require('path');
const webpack = require('webpack');
// Set environment variable.
const production = process.env.NODE_ENV === "production";

const appSource = path.join(__dirname, 'react/src/');
const buildPath = path.join(__dirname, 'react/build/');

const ReactConfig = {
  entry: [
    './react/src/index.jsx'
  ],

  output: {
    path: buildPath,
    publicPath: buildPath,
    filename: 'app.js'
  },

  module: {
    rules: [
      {
        exclude: /(node_modules)/,
        use: {
          loader: "babel-loader?cacheDirectory=true",
          options: {
            presets: ["react", "es2015", "stage-0"]
          },
        },
      },
    ],
  },

  resolve: {
    modules: [
      path.join(__dirname, 'node_modules'),
      './react/src/'
    ],
    extensions: ['.js', '.jsx', '.es6'],
  },

  context: __dirname,
  devServer: {
    historyApiFallback: true,
    contentBase: appSource
  },
  // TODO: Split plugins based on prod and dev builds.
  plugins: [

    new webpack.DllReferencePlugin({
      context: path.join(__dirname, "react", "src"),
      manifest: require(path.join(__dirname, "react", "vendors", "vendor-manifest.json"))
    }),

    new webpack.optimize.CommonsChunkPlugin({
      name: 'manifest',
      filename: 'webpack-loader.js'
    }),
  ]
};
// Add environment specific configuration.
if (production) {
  ReactConfig.plugins.push(
    new webpack.optimize.UglifyJsPlugin()
  );
}

module.exports = [ReactConfig];

      

webpack.dll.js

const path = require("path");
const webpack = require("webpack");
const production = process.env.NODE_ENV === "production";

const DllConfig = {
  entry: {
    vendor: [path.join(__dirname, "react", "vendors", "vendors.js")]
  },
  output: {
    path: path.join(__dirname, "react", "vendors"),
    filename: "dll.[name].js",
    library: "[name]"
  },
  plugins: [
    new webpack.DllPlugin({
      path: path.join(__dirname, "react", "vendors", "[name]-manifest.json"),
      name: "[name]",
      context: path.resolve(__dirname, "react", "src")
    }),
    // Resolve warning message related to the 'fetch' node_module.
    new webpack.IgnorePlugin(/\/iconv-loader$/),
  ],
  resolve: {
    modules: [
      path.join(__dirname, 'node_modules'),
    ],
    extensions: ['.js', '.jsx', '.es6'],
  },
  // Added to resolve a dependency issue in this build #https://github.com/hapijs/joi/issues/665
  node: {
    net: 'empty',
    tls: 'empty',
    dns: 'empty'
  }
};

if (production) {
  DllConfig.plugins.push(
    new webpack.optimize.UglifyJsPlugin()
  );
}

module.exports = [DllConfig];

      

vendors.js (to determine what to add to the Dll)

require("react");
require("react-bootstrap");
require("react-dom");
require("react-redux");
require("react-router-dom");
require("redux");
require("redux-form");
require("redux-promise");
require("redux-thunk");
require("classnames");
require("whatwg-fetch");
require("fetch");
require("prop-types");
require("url");
require("validator");

      

gulpfile.js

'use strict';

const gulp = require('gulp');
const webpack = require ('webpack');
const reactConfig = require('./webpack.config.js');
const vendorConfig = require('./webpack.dll.js');

// React webpack source build.
gulp.task('react-src', function (callback) {
  webpack(reactConfig, function (err, stats) {
    callback();
  })
});

// React webpack vendor build.
gulp.task('react-vendor', function (callback) {
  webpack(vendorConfig, function (err, stats) {
    callback();
  })
});

// Full webpack react build.
gulp.task('react-full', ['react-vendor', 'react-src']);

      

Note: If I first create a vendor package with a terminal with webpack --config=webpack.dll.js

and it creates a vendor-manifest.json file, I can run my gulp tasks successfully afterwards without issue.

This is not very useful as it still prevents me from using webpack with gulp as I intend to clean up the build before starting new builds.

+3


source to share


1 answer


I ended up using the solution mentioned at the end of my question. First I create my DLL file and then I can run gulp webpack tasks successfully.

One change to make the problem easier to debug is to use the gulp utility module ( gulp-util ) to show any webpack errors that might appear during webpack build using gulp.

My final gulp setup ended up like this:



gulpfile.js

'use strict';

const gulp = require('gulp');
const gutil = require('gulp-util');
const webpack = require('webpack');
const reactConfig = require('./webpack.config.js');
const vendorConfig = require('./webpack.dll.js');

// React webpack source build.
gulp.task('react', function (callback) {
  webpack(reactConfig, function (err, stats) {
    if (err) {
      throw new gutil.PluginError('webpack', err);
    }
    else {
      gutil.log('[webpack]', stats.toString());
    }
    callback();
  });
});

// React webpack vendor build.
gulp.task('react-vendor', function (callback) {
  webpack(vendorConfig, function (err, stats) {
    if (err) {
      throw new gutil.PluginError('webpack', err);
    }
    else {
      gutil.log('[webpack]', stats.toString());
    }
    callback();
  });
});

// React: Rebuilds both source and vendor in the right order.
gulp.task('react-full', ['react-vendor'], function () {
  gulp.start('react');
});

      

I hope this can help someone in a similar situation.

+1


source







All Articles