8

Hi I have a webpack config with these entry points:

  entry: {
    'polyfills': './src/polyfills.ts',
    'vendor':    './src/vendor.ts',
    'app':       './src/app.ts',
    'css': './src/css/main.unique.scss',
    'index': './src/index.unique.html',
  },

My webpack is creating a [name].bundle.js and a [name].map for each entry.
It makes sense for the first 3 javascript entries but the CSS and the INDEX entries are just for processing my main CSS file and my main html file which get treated later by the ExtractTextPlugin

So after a build I'm stuck with some garbage like css.bundle.js and css.map which only contains:

webpackJsonp([1],[
/* 0 */
/***/ function(module, exports) {

    // removed by extract-text-webpack-plugin

/***/ }
]);
//# sourceMappingURL=css.map

How can I tell webpack to NOT build files for some entries? (like css/index)
Or alternatively to delete those useless files after the compile?

Thanks in advance

kfir124
  • 1,286
  • 4
  • 14
  • 27

3 Answers3

10

I hacked together a SuppressEntryChunksPlugin (code below) that skips output of these useless bundles, if you tell it which bundles will be useless. Use it in your webpack.config.js like this:

var SuppressEntryChunksPlugin = require('./SuppressEntryChunksPlugin');
...
  entry: {
    'app': './src/app.ts',
    'css': './src/css/main.unique.scss',
    'index': './src/index.unique.html',
  },
  plugins: [
    // don't output the css.js and index.js bundles
    new SuppressEntryChunksPlugin(['css', 'index'])
  ]

Disclaimers: It works for me together with extract-loader and file-loader to extract the css/html from the entries and write the files into the output. I haven't tested it with ExtractTextPlugin. (It does work with webpack-dev-server. And it seems to successfully suppress external sourcemaps if you're using them. I've used it with both Webpack 1.13 and 2.2.1.)

// SuppressEntryChunksPlugin.js

function SuppressEntryChunksPlugin(options) {
  if (typeof options === 'string') {
    this.options = {skip: [options]};
  } else if (Array.isArray(options)) {
    this.options = {skip: options};
  } else {
    throw new Error("SuppressEntryChunksPlugin requires an array of entry names to strip");
  }
}

SuppressEntryChunksPlugin.prototype.apply = function(compiler) {
  var options = this.options;

  // just before webpack is about to emit the chunks,
  // strip out primary file assets (but not additional assets)
  // for entry chunks we've been asked to suppress
  compiler.plugin('emit', function(compilation, callback) {
    compilation.chunks.forEach(function(chunk) {
      if (options.skip.indexOf(chunk.name) >= 0) {
        chunk.files.forEach(function(file) {
          // delete only js files.
          if (file.match(/.*\.js$/)) {
            delete compilation.assets[file];
          }
        });
      }
    });
    callback();
  });
};

module.exports = SuppressEntryChunksPlugin;

Also, I'm whatever the opposite of "webpack expert" is, so there's almost certainly a better way to do this. (Perhaps someone would like to turn this into a real, published webpack plugin, with tests and whatnot?)

bgreater
  • 1,937
  • 3
  • 17
  • 16
medmunds
  • 5,950
  • 3
  • 28
  • 51
  • Oh, you're a hell of webpack hacker, dude:) Thank you for sharing! You saved me a decent bunch of hairs:) – Diligent Key Presser Sep 16 '16 at 17:00
  • @medmunds In order to get `ExtractTextPlugin` to output css files without their .js counterpart you just need to update your delete operation with a conditional ```if (file.match(/.*\.js$/)) { delete compilation.assets[file]; } ``` – bgreater Aug 05 '17 at 16:13
  • @bgreater thanks for the fix for use with ExtractTextPlugin. Do you know if that also drops the .map file for the unused JS bundle as requested by OP? (You'd presumably want to keep any css map files, though, so not just indiscriminately drop *.map from the compilation assets.) – medmunds Aug 30 '17 at 18:11
0

I put together a webpack plugin to remove extra files based on their output size, rather than basing it on their name - it's been a little more future proof for me as I continue to add extra entry points to my webpack config.

Install using npm or yarn

npm install webpack-extraneous-file-cleanup-plugin --save-dev
yarn add webpack-extraneous-file-cleanup-plugin --dev

In your webpack.config.js file:

const ExtraneousFileCleanupPlugin = require('webpack-extraneous-file-cleanup-plugin');

module.exports = {
  ...
  plugins: [
    new ExtraneousFileCleanupPlugin({
      extensions: ['.js']
    })
  ]
}

You can see the full list of options on the Webpack Extraneous File Cleanup Plugin Github Page

Anuj
  • 1,474
  • 12
  • 23
0

You can delete any files or folders after compilation by using remove-files-webpack-plugin.

Use this plugin like this:

plugins: [
  new RemovePlugin({
    after: {
      // expects what your output folder is `dist`.
      include: [
        './dist/css.bundle.js',
        './dist/css.map'
      ]
    }
  })
]

Note: i'm the creator of this plugin.

Amaimersion
  • 787
  • 15
  • 28