Webpack: ExtractTextPlugin: Not to generate separate empty JS file when have several css entry points?
Asked Answered
G

3

8

I have several CSS entry points:

entry: {
  ...
  styles: [
    ...
  ],
  fonts: [
    ...
  ]
},

and I'm using ExtractTextPlugin to bundle CSS separately:

  new ExtractTextPlugin({
    filename: `[name].bundle.css`
  }),

So like output I have 2 CSS files: styles.css and fonts.css that is correct but also empty styles.js and fonts.js. Is there a way to not generate empty JS files?

Golconda answered 9/3, 2017 at 9:27 Comment(0)
S
3

I put together a webpack plugin to remove extra files based on their final output size as I had the same issue - given these files tend to be very small, it seems to just be a case of checking how large they are and removing the small, useless ones.

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

Sorrento answered 16/6, 2017 at 16:51 Comment(0)
R
1

Only add the main javascript files as entries and require all fonts and style via require('./style.css')

webpack.config.js:

entry: {
  'main': 'app/main',
},
output: {
  path: 'static',
  publicPath: '/static/',
  filename: '[name].bundle.js',
  chunkFilename: '[chunkhash].bundle.js',
},
module: {
  rules: [
    {
      test: /\.css$/,
      use: ExtractTextPlugin.extract({
        fallback: 'style-loader',
        use: 'css-loader'
      }),
    }]
},
plugins: [
  new ExtractTextPlugin('[name].bundle.css'),
],

That would give you a /static/main.bundle.css with all css (transitively) included from your app/main.js.

Same for fonts, but you would need a second ExtractTextPlugin instance like:

const extractCSS = new ExtractTextPlugin('stylesheets/[name].bundle.css');
const extractFonts = new ExtractTextPlugin('stylesheets/[name].bundle.woff');

module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/,
        use: extractCSS.extract([ 'css-loader', 'postcss-loader' ])
      },
      {
        test: /\.woff$/i,
        use: extractFonts.extract([ 'url-loader' ])
      },
    ]
  },
  plugins: [
    extractCSS,
    extractFonts
  ]
};

See the Documentation - Multiple Instances for more info about that.

Ruthven answered 13/3, 2017 at 18:24 Comment(2)
But I would like to make the spit not based on rules. I have fonts.scss and styles.scss like an entry points.Golconda
Avoiding rules entirely won't work. If it's just about those two entry points and only one Javascript entry point, you will just have to rename those css and font links, remove their entry points and add those extractors. Give it a try, it works like a charm for us 😊Ruthven
S
1

I don't think there's any way to do what you are trying to do, the same question has been asked on the github issue tracker, without any solution. If the problem is with the html-webpack-plugin adding the empty js files, you should be able to fix that by explicitly specifying what chunks to include or exclude.

Skylar answered 20/3, 2017 at 13:48 Comment(1)
yes, I tried this approach, but unfortunately if you put fonts into exclude there is no CSS file as well :(Golconda

© 2022 - 2024 — McMap. All rights reserved.