bootstrap-loader: "Error: Path must be a string. Received undefined" updating to webpack 2.1.0-beta.25

Thought my issue was related to another thread, but it seems they are separate, so I’m opening up this ticket. Still actively trying to figure out what exactly is happening here. There were some breaking changes between webpack 2.1.0-beta.23-25, and upgrading is producing an error from bootstrap-loader…

69% building modules 1174/1175 modules 1 active ...ode_modules/bootstrap-loader/no-op.jsTypeError: Path must be a string. Received undefined
    at assertPath (path.js:8:11)
    at Object.posix.relative (path.js:495:3)
    at Object.onRender (/home/p3pt/dev/java/projects/spring-boot-angular2/frontend/node_modules/sass-loader/index.js:282:42)
    at Object.<anonymous> (/home/p3pt/dev/java/projects/spring-boot-angular2/frontend/node_modules/sass-loader/node_modules/async/dist/async.js:2414:31)
    at apply (/home/p3pt/dev/java/projects/spring-boot-angular2/frontend/node_modules/sass-loader/node_modules/async/dist/async.js:40:25)
    at Object.<anonymous> (/home/p3pt/dev/java/projects/spring-boot-angular2/frontend/node_modules/sass-loader/node_modules/async/dist/async.js:76:12)
    at Object.callback (/home/p3pt/dev/java/projects/spring-boot-angular2/frontend/node_modules/sass-loader/node_modules/async/dist/async.js:988:16)
    at options.success (/home/p3pt/dev/java/projects/spring-boot-angular2/frontend/node_modules/node-sass/lib/index.js:309:32)

I am not completely sure that the issue is bootstrap-loader, I feel as though it may just be a configuration problem, or even possibly an issue with sass-loader (given the error trace)

I pulled the basic example and tried to reproduce the issue, but could not, even updating the webpack version to 2.1.0-beta.25 did not break the build. Scratching my head here on this one a bit.

I’m still debugging, and searching around for a solution. I will definitely submit a PR if I find the fix is related to bootstrap-loader.

For reference… webpack.common.js

const webpack = require('webpack');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const helpers = require('./helpers');
const autoprefixer = require('autoprefixer');

module.exports = {
    entry: {
        'polyfills': './src/polyfills.ts',
        'vendor': './src/vendor.ts',
        'app': './src/main.ts'
    },

    context: helpers.root(),

    resolve: {
        modules: [helpers.root('src'), "node_modules"],
        descriptionFiles: ['package.json'],
        extensions: ['.js', '.ts', '.css', '.scss', '.json', '.html']
    },

    module: {
      rules: [
          {
            enforce: 'pre',
            test: /\.js$/,
            loader: 'source-map-loader',
            exclude: [helpers.root('node_modules')]
          },

          {
            test: /\.ts$/,
            loaders: ['awesome-typescript-loader', 'angular2-template-loader'],
            exclude: [/\.(spec|e2e)\.ts$/]
          },

          {
            test: /\.html$/,
            loader: 'raw-loader',
            exclude: [helpers.root('src/index.html')]
          },

          {
            test: /\.css$/,
            loader: 'raw-loader!style-loader!css-loader!postcss-loader'
          },

          {
            test: /initial\.scss$/,
            loader: ExtractTextPlugin.extract({ fallbackLoader: 'style-loader', loader: 'css-loader!sass-loader'})
          },

          {
            test: /\.scss$/,
            loaders: ['raw-loader', 'sass-loader'],
            exclude: [helpers.root('node_modules')]
          },

          {
            test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/,
            loader: "url-loader?limit=10000&mimetype=application/font-woff"
          },

          {
              test: /\.(ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
              loader: "file-loader"
          },

          {
            test: /\.json$/,
            loader: 'json-loader'
          },

          {
            test: /bootstrap\/dist\/js\/umd\//,
            loader: 'imports?jQuery=jquery'
          }
      ]
    },

    plugins: [
        new webpack.ContextReplacementPlugin(
            /angular(\\|\/)core(\\|\/)(esm(\\|\/)src|src)(\\|\/)linker/,
            __dirname
        ),
        new ExtractTextPlugin({
            filename: 'css/[name].css',
            disable: false, allChunks: true
        }),

        new webpack.optimize.CommonsChunkPlugin({
            name: ['app', 'vendor', 'polyfills']
        }),

        new CopyWebpackPlugin([{
          from: 'src/assets',
          to: 'assets'
        }]),

        new HtmlWebpackPlugin({
            template: 'src/index.html',
            chunksSortMode: 'dependency'
        }),

        new webpack.ProvidePlugin({
            jQuery: 'jquery',
            $: 'jquery',
            jquery: 'jquery',
            "window.moment": "moment",
            'Tether': 'tether',
            'window.Tether': 'tether',
            Tooltip: "exports?Tooltip!bootstrap/js/dist/tooltip",
            Alert: "exports?Alert!bootstrap/js/dist/alert",
            Button: "exports?Button!bootstrap/js/dist/button",
            Carousel: "exports?Carousel!bootstrap/js/dist/carousel",
            Collapse: "exports?Collapse!bootstrap/js/dist/collapse",
            Dropdown: "exports?Dropdown!bootstrap/js/dist/dropdown",
            Modal: "exports?Modal!bootstrap/js/dist/modal",
            Popover: "exports?Popover!bootstrap/js/dist/popover",
            Scrollspy: "exports?Scrollspy!bootstrap/js/dist/scrollspy",
            Tab: "exports?Tab!bootstrap/js/dist/tab",
            Util: "exports?Util!bootstrap/js/dist/util"
        }),

        new webpack.LoaderOptionsPlugin({
          options: {
            postcss: [autoprefixer]
          }
        })
    ],

    node: {
        fs: 'empty',
        global: true,
        crypto: 'empty',
        module: false,
        clearImmediate: false,
        setImmediate: false
    }
};

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Comments: 27 (4 by maintainers)

Commits related to this issue

Most upvoted comments

@sasidhar : This is not an issue and you don’t need disable SassSourceMap and ResolveUrl Loaders… Since you are using the Angular2-webpack-starter, you need to add the following in webpack.dev.config, webpack.prod.config and other environment files. Remember, changing in webpack.common.config won’t resolve the issue…

It’s all about passing the right context to webpack.

new LoaderOptionsPlugin({
        debug: true,
        options: {
          context: __dirname,  
          output: { path :  './' }, //This has to be './' and not your output folder.
          postcss: [autoprefixer],
          sassLoader: {
            includePaths: [path.resolve(__dirname, 'src', 'scss')]
          }
        }
      }),

Ok. I’ve fixed it for https://github.com/AngularClass/angular2-webpack-starter.

Frequently errors:

  • resolve-url-loader, ‘path’ of undefined
  • Path must be a string. Received undefined

You need to add next rows to LoaderOptionPlugin context: helpers.root(), output: { path: helpers.root(‘dist’) },

  /**
       * Plugin LoaderOptionsPlugin (experimental)
       *
       * See: https://gist.github.com/sokra/27b24881210b56bbaff7
       */
      new LoaderOptionsPlugin({
        debug: true,
        options: {
           context: helpers.root(),
          output: {
              path: helpers.root('dist')
          },
          /**
           * Static analysis linter for TypeScript advanced options configuration
           * Description: An extensible linter for the TypeScript language.
           *
           * See: https://github.com/wbuchwalter/tslint-loader
           */
          tslint: {
            emitErrors: false,
            failOnHint: false,
            resourcePath: 'src'
          }
        }
      })
    ],

Spend 6 hours to resolve that 2 issues. 😦

I had the same issue. I fixed it adding this to my webpack.common.js:

plugins: [
(...)
new LoaderOptionsPlugin({
      debug: true,
      options: {
        context: __dirname,
        output: { path :  "./" },
        postcss: [autoprefixer],
        tslint: {
          emitErrors: false,
          failOnHint: false,
          resourcePath: 'src',
          formattersDirectory: "node_modules/tslint-loader/formatters/"
        }
      }
    })
(...)
]

I don’t understand what it means “output” inside LoaderOptionsPlugin, but it works. Obviously, in my webpack.dev.js I have always these lines (the real output):

output: {
    path    : './',
    filename: '[name].js',
    chunkFilename: '[name].js',
    publicPath: './'
  },

This probably has nothing to do with bootstrap-loader, other than we were the first loader in this chain. (I honestly am not sure why we listed in the stack trace, because path is throwing the error, and the path function throwing the error is the path.relative below)

Based off the stack trace, the fact that ...sass-loader/index.js:282:42 is path.relative(self.options.context, resourcePath);, and jtangelder/sass-loader#290, I think that your problem is that the loadOptions plugin is wiping this.options.context.

The sassOptions you provided proves this because that sourceMap url is based off of self.options.context [0] and var self = this [1].

0: https://github.com/jtangelder/sass-loader/blob/master/index.js#L228 1: https://github.com/jtangelder/sass-loader/blob/master/index.js#L40

@regenrek This problem was due to a regression in stylus-loader when upgrading to webpack 2. The fix has been merged in as follows: https://github.com/shama/stylus-loader/pull/104.

sorry I’ve been mia on this guys, I should be able to make some time to continue looking at this during the weekend. I recall trying the output fix, and not having that resolve the issue, but I still have to take another look at it.