inspectpack: [BUG] Could not analyze bundle problems. Error: Unable to find project root package.json

Whenever I try to start webpack-dashboard the following error occurs:

Could not analyze bundle problems.                                                                          ││                                   │
│ Error: Unable to find project root package.json                                                             ││                                   │
│     at Versions.getData (/Users/ignitestudio1/Sites/bluerock/web/app/themes/theme/node_modules/inspect   ││ Success                           │
│ pack/lib/actions/versions.js:308:14)                                                                        ││                                   │
│     at Bundle.create (/Users/ignitestudio1/Sites/bluerock/web/app/themes/theme/node_modules/inspectpac   ││                                   │
│ k/lib/actions/base.js:97:16)                                                                                │└───────────────────────────────────┘
│     at Immediate.setImmediate (/Users/ignitestudio1/Sites/bluerock/web/app/themes/theme/node_modules/i   │┌─Operation─────────────────────────┐
│ nspectpack/lib/models/bundle.js:278:7)                                                                      ││                                   │
│     at runCallback (timers.js:672:20)                                                                       ││                                   │
│     at tryOnImmediate (timers.js:645:5)                                                                     ││                                   │
│     at processImmediate [as _immediateCallback] (timers.js:617:5)                                           ││ idle (3s)                         │
│ Could not analyze bundle problems.                                                                          ││                                   │
│ Error: Unable to find project root package.json                                                             ││                                   │
│     at Versions.getData (/Users/ignitestudio1/Sites/bluerock/web/app/themes/theme/node_modules/inspect   │└───────────────────────────────────┘
│ pack/lib/actions/versions.js:308:14)                                                                        │┌─Progress──────────────────────────┐
│     at Bundle.create (/Users/ignitestudio1/Sites/bluerock/web/app/themes/theme/node_modules/inspectpac   ││                                   │
│ k/lib/actions/base.js:97:16)                                                                                ││                                   │
│     at Immediate.setImmediate (/Users/ignitestudio1/Sites/bluerock/web/app/themes/theme/node_modules/i   ││                                   │
│ nspectpack/lib/models/bundle.js:278:7)                                                                      ││ 0%                                │
│     at runCallback (timers.js:672:20)                                                                       ││                                   │
│     at tryOnImmediate (timers.js:645:5)                                                                     ││                                   │
│     at processImmediate [as _immediateCallback] (timers.js:617:5)  

The project I’m working on is a WordPress project. Webpack is started from the theme folder which lives in /web/app/themes/theme/package.json.

My webpack.config.js is as follows:

'use strict'; // eslint-disable-line

const webpack = require('webpack');
const path = require('path');
const merge = require('webpack-merge');
const CleanPlugin = require('clean-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
var DashboardPlugin = require('webpack-dashboard/plugin');
const StyleLintPlugin = require('stylelint-webpack-plugin');

const CopyGlobsPlugin = require('copy-globs-webpack-plugin');
const config = require('./config');

const assetsFilenames = (config.enabled.cacheBusting) ? config.cacheBusting : '[name]';
const sourceMapQueryStr = (config.enabled.sourceMaps) ? '+sourceMap' : '-sourceMap';

let webpackConfig = {
  context: config.paths.assets,
  entry: config.entry,
  devtool: (config.enabled.sourceMaps ? '#source-map' : undefined),
  output: {
    path: config.paths.dist,
    publicPath: config.publicPath,
    filename: `scripts/${assetsFilenames}.js`,
  },
  stats: {
    hash: false,
    version: false,
    timings: false,
    children: false,
    errors: false,
    errorDetails: false,
    warnings: false,
    chunks: false,
    modules: false,
    reasons: false,
    source: false,
    publicPath: false,
  },
  module: {
    noParse: [
      /node_modules[\\/]video\.js/,
    ],
    rules: [
      {
        enforce: 'pre',
        test: /\.js?$/,
        include: config.paths.assets,
        use: 'eslint',
      },
      {
        enforce: 'pre',
        test: /\.vue$/,
        use: 'eslint',
        exclude: /node_modules/,
      },
      {
        test: /\.js$/,
        exclude: [/(node_modules|bower_components)(?![/|\\](bootstrap|foundation-sites))/],
        include: [config.paths.assets, path.join(process.cwd(), 'vendor/igniteonline')],
        use: [
          {loader: 'cache'},
          {
            loader: 'babel',
            query: {
              presets: [[path.resolve('./node_modules/babel-preset-es2015'), { modules: false }]],
              cacheDirectory: true,
            },
          }],
      },
      {
        test: /\.css$/,
        include: config.paths.assets,
        use: ExtractTextPlugin.extract({
          fallback: 'style',
          use: [
            {loader: 'cache'},
            `css?${sourceMapQueryStr}`,
            {
              loader: 'postcss',
              options: {
                sourceMap: true,
                config: {
                  path: path.join(process.cwd(), 'resources/assets/build'),
                },
              },
            },
          ],
        }),
      },
      {
        test: /\.scss$/,
        include: config.paths.assets,
        use: ExtractTextPlugin.extract({
          fallback: 'style',
          use: [
            {loader: 'cache'},
            `css?${sourceMapQueryStr}`,
            {
              loader: 'postcss',
              options: {
                sourceMap: true,
                config: {
                  path: path.join(process.cwd(), 'resources/assets/build'),
                },
              },
            },
            `resolve-url?${sourceMapQueryStr}`,
            `sass?${sourceMapQueryStr}`,
          ],
        }),
      },
      {
        test: /\.(png|jpe?g|gif|svg|ico)$/,
        include: config.paths.assets,
        exclude: path.join(config.paths.assets, 'images/admin'),
        loader: 'file',
        options: {
          name: `[path]${assetsFilenames}.[ext]`,
        },
      },
      {
        test: /\.(png|jpe?g|gif|svg|ico)$/,
        include: path.join(config.paths.assets, 'images/admin'),
        loader: 'file',
        options: {
          name: '[path][name].[ext]',
        },
      },
      {
        test: /\.(ttf|eot|otf)$/,
        include: config.paths.assets,
        loader: 'file',
        options: {
          name: `[path]${assetsFilenames}.[ext]`,
        },
      },
      {
        test: /\.woff2?$/,
        include: config.paths.assets,
        loader: 'url',
        options: {
          limit: 10000,
          mimetype: 'application/font-woff',
          name: `[path]${assetsFilenames}.[ext]`,
        },
      },
      {
        test: /\.(ttf|eot|otf|woff2?|png|jpe?g|gif|svg)$/,
        include: /node_modules|bower_components/,
        loader: 'file',
        options: {
          name: `vendor/${config.cacheBusting}.[ext]`,
        },
      },
      {
        test: /modernizr\.js$/,
        use: 'exports?window.Modernizr',
      },
      {
        test: /\.vue$/,
        use: 'vue',
      },
    ],
  },
  resolve: {
    modules: [
      config.paths.assets,
      'node_modules',
      'bower_components',
      'vendor/igniteonline',
    ],
    enforceExtension: false,
    alias: {
      vue: config.enabled.optimize ? 'vue/dist/vue.min.js' : 'vue/dist/vue.js',
      'video.js': 'video.js/dist/video.js',
      "TweenLite": path.resolve('node_modules', 'gsap/src/uncompressed/TweenLite.js'),
      "TweenMax": path.resolve('node_modules', 'gsap/src/uncompressed/TweenMax.js'),
      "TimelineLite": path.resolve('node_modules', 'gsap/src/uncompressed/TimelineLite.js'),
      "TimelineMax": path.resolve('node_modules', 'gsap/src/uncompressed/TimelineMax.js'),
      "ScrollMagic": path.resolve('node_modules', 'scrollmagic/scrollmagic/uncompressed/ScrollMagic.js'),
      "animation.gsap": path.resolve('node_modules', 'scrollmagic/scrollmagic/uncompressed/plugins/animation.gsap.js'),
      "debug.addIndicators": path.resolve('node_modules', 'scrollmagic/scrollmagic/uncompressed/plugins/debug.addIndicators.js'),
    },
  },
  resolveLoader: {
    moduleExtensions: ['-loader'],
  },
  externals: {
    jquery: 'jQuery',
    'window.jsParams': 'jsParams',
    jsParams: 'jsParams',
    'window.google': 'google',
    google: 'google',
  },
  plugins: [
    new CleanPlugin([config.paths.dist], {
      root: config.paths.root,
      verbose: false,
    }),
    /**
     * It would be nice to switch to copy-webpack-plugin, but
     * unfortunately it doesn't provide a reliable way of
     * tracking the before/after file names
     */
    new CopyGlobsPlugin({
      pattern: config.copy,
      output: `[path]${assetsFilenames}.[ext]`,
      manifest: config.manifest,
    }),
    new ExtractTextPlugin({
      filename: `styles/${assetsFilenames}.css`,
      allChunks: false,
      disable: (config.enabled.watcher),
    }),
    new webpack.ProvidePlugin({
      $: 'jquery',
      jQuery: 'jquery',
      'window.jQuery': 'jquery',
      Tether: 'tether',
      'window.Tether': 'tether',
      'window.jsParams': 'jsParams',
      jsParams: 'jsParams',
      'window.google': 'google',
      google: 'google',
      videojs: 'video.js',
      'window.videojs': 'video.js',
    }),
    new webpack.LoaderOptionsPlugin({
      minimize: config.enabled.optimize,
      debug: config.enabled.watcher,
      stats: { colors: true },
    }),
    new webpack.LoaderOptionsPlugin({
      test: /\.js$/,
      options: {
        eslint: { failOnWarning: false, failOnError: true },
      },
    }),
    new webpack.optimize.CommonsChunkPlugin({
      name: 'node-static',
      filename: config.env.production ? `vendor/node-static-[hash:8].js` : `vendor/node-static.js`,
      minChunks(module) {
        const context = module.context;
        return context && context.indexOf('node_modules') >= 0;
      },
    }),
    new StyleLintPlugin({
      failOnError: ! config.enabled.watcher,
      syntax: 'scss',
    }),
  ],
};

/* eslint-disable global-require */ /** Let's only load dependencies as needed */

if (config.enabled.optimize) {
  webpackConfig = merge(webpackConfig, require('./webpack.config.optimize'));
}

if (!config.env.production && !config.enabled.watcher) {
  webpackConfig.plugins.push(new BundleAnalyzerPlugin({
    analyzerMode: 'static',
  }));
}
if (config.env.production) {
  webpackConfig.plugins.push(new webpack.NoEmitOnErrorsPlugin());
  webpackConfig.plugins.push(new webpack.optimize.ModuleConcatenationPlugin());
  // webpackConfig.plugins.push(new webpack.DefinePlugin({
  //   'process.env': {
  //     NODE_ENV: 'production',
  //   },
  // }));
}

if (config.enabled.cacheBusting) {
  const WebpackAssetsManifest = require('webpack-assets-manifest');

  webpackConfig.plugins.push(
    new WebpackAssetsManifest({
      output: 'assets.json',
      space: 2,
      writeToDisk: false,
      assets: config.manifest,
      replacer: require('./util/assetManifestsFormatter'),
    })
  );
}

if (config.enabled.watcher) {
  webpackConfig.entry = require('./util/addHotMiddleware')(webpackConfig.entry);
  webpackConfig = merge(webpackConfig, require('./webpack.config.watch'));
  webpackConfig.plugins.push(new DashboardPlugin());
}

module.exports = webpackConfig;

For your reference, the project is based on sage which reflects the structure of the theme folder in my project.

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Reactions: 2
  • Comments: 15 (6 by maintainers)

Commits related to this issue

Most upvoted comments

I had this issue and got around it by unsetting context in my webpack configuration. That means the entry points etc need to be adjusted accordingly, of course.

Repro’ed and confirmed it’s a webpack-dashboard bug and not an inspectpack one. I’ll keep this bug open and I’m working on a PR for webpack-dashboard. As suspected, problem is use of context outside of where the project root package.json and node_modules are.

Seems like the problem is that, as pointed out by @tremby, package.json file is being resolved searching in the context folder specified in the webpack configuration.

@derkjn @gartz – Can one of you give me a reproduction? If your projects aren’t open source, then maybe a quick public repo with the minimum amount of code to cause the issue? I think it may be in the webpack aliases…

Also, as a totally unrelated side note, for code like:

"TweenLite": path.resolve('node_modules', 'gsap/src/uncompressed/TweenLite.js'),

I usually prefer the pattern of:

"TweenLite": require.resolve("gsap/src/uncompressed/TweenLite"),

In this way, you immediately get rid of any potential node_modules tree structure flattening issues (not a problem for top-level dependencies) and you’re basically just letting Node do what it does with resolving (giving extensions searching and other things that path.resolve doesn’t)