Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Delete or not create a file for each entry in webpack

Tags:

webpack

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

like image 889
kfir124 Avatar asked May 24 '16 09:05

kfir124


People also ask

Can webpack have multiple entry points?

webpack.config.jsWe can also pass an array of file paths to the entry property which creates what is known as a "multi-main entry". This is useful when you would like to inject multiple dependent files together and graph their dependencies into one "chunk".

Is it mandatory to use a configuration file when setting up a webpack project?

Out of the box, webpack won't require you to use a configuration file. However, it will assume the entry point of your project is src/index. js and will output the result in dist/main.

What is libraryTarget in webpack?

This is according to their documentation: "libraryTarget: "umd" - This exposes your library under all the module definitions, allowing it to work with CommonJS, AMD and as global variable." Also, I built the exact same code with Webpack 3 and it produced a proper bundle.

Does webpack automatically minify?

In webpack 4, the bundle-level minification is enabled automatically – both in the production mode and without one. It uses the UglifyJS minifier under the hood. (If you ever need to disable minification, just use the development mode or pass false to the optimization. minimize option.)


1 Answers

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?)

like image 127
medmunds Avatar answered Sep 16 '22 23:09

medmunds