Output CSS to different directory with ExtractTextPlugin

I’m using the ExtractTextPlugin to build a separate CSS file. It works great but I’d really like to output the CSS into a different directory than the JS:

module.exports = {
  entry: {
    module: "./source/javascripts/app.js",
  },
  output: {
    path: './source/built/',
    filename: 'app.js'
  },
  module: {
    loaders:[
      {
        test: /\.js$/, exclude: /node_modules/, loader: 'babel-loader'
      },
      {
        test: /\.css$/,
        loader: ExtractTextPlugin.extract('style-loader', 'css-loader!postcss-loader')
      }
    ]
  },
  plugins: [
    new ExtractTextPlugin('app.css')
  ]
};

Currently both files go into ./source/built, is there a way to change this?

Author: Fantashit

8 thoughts on “Output CSS to different directory with ExtractTextPlugin

  1. This actually was a similar problem I was facing and andreypopp’s answer solved it for me. Specifically, what worked for me was:

    plugins: [
        new ExtractTextPlugin("./css/[name].css"),
      ],
    
  2. Ah nice, in my example I was able to use new ExtractTextPlugin("../css/[name].css") to solve moving it to a different dir.

    Thanks

  3. This worked for me..

    webpack: { // grunt-webpack
      options: {
        module: {
          loaders: [
            { test: /\.jsx?$/, exclude: /(node_modules|bower_components)/, loader: 'babel' }, // REACTJS FILES
            { test: /\.json?$/, exclude: /(node_modules|bower_components)/, loader: 'json' }, // JSON FILES
            { test: /\.scss$/, loader: ExtractTextPlugin.extract('css!sass?includePaths[]=' + bourbon, { publicPath: '../'}) }, // SASS & CSS FILES
            { test: /\.(jpe?g|png|gif|svg)$/i, exclude: /(node_modules|bower_components)/, loader: 'url?limit=1000&name=images/[hash].[ext]' } // IMAGES
          ]
        } 
      },
      dev: {
        entry: './<%%= project.path.voter.assets %%>/app/app.js',
        output: {
          path: './<%%= project.path.voter.dist %%>/',
          filename: 'js/voter.bundle.js'
        },
        plugins: [
          new ExtractTextPlugin('css/voter.bundle.css', {
            allChunks: true
          })
        ]
      }
    }
  4. @iDVB maybe cause you’re using url loader to extract images and as they are ‘small’ they are embedded in base64.

    If I use file-loader or if I have big images the css’ url(...) are pointing to the wrong directory (I’ve got everything under assets/ and the css is rewritten with url(assets/example.png) instead of url(example.png)

  5. @ulfryk I don’t know how @iDVB‘s solution solves this and also don’t know how late it is for you but I was able to get this working by doing the following.

    module.exports = {
      entry: {
        './bundle.js': './index.js'
      },
      output: {
        filename: '[name]',
        publicPath: 'assets/'
      },
      module: {
        loaders: [{
          test: /\.scss$/,
          loader: ExtractTextPlugin.extract('style', 'css!sass'),
        }, {
          test: /\.png$/,
          loader: 'file',
          query: {
            name: 'assets/image/[hash].[ext]', // note this line still uses `assets` in path to create the right public directory
            publicPath: '/' // this overwrites the `publicPath` that's mentioned at the top or else you'd have `assets/assets/image/slkfdjskldf.png` in your css url(..)
          }
        }]
      },
      plugins: [new ExtractTextPlugin("./style/styleBundle.css")]
    };

    If the above is not as clear then basically you’d need to add publicPath in your file-loader query to override publicPath that’s at the parent level while still putting the public path, or in my case assets, in the name query of file-loader so that it extracts to the right public directory while keeping the right url in the css.
    Hope that clarifies a little and helps others as well cause it took me almost a day to figure this out.

Comments are closed.