webpack-remove-empty-scripts icon indicating copy to clipboard operation
webpack-remove-empty-scripts copied to clipboard

Webpack plugin to remove empty scripts generated by usage only a style without JS in entry.

webpack-remove-empty-scripts

The plugin removes empty JavaScript files generated when using only styles in Webpack entry.

npm node node codecov node

Webpack generates a js file for each resource defined in Webpack entry.
The mini-css-extract-plugin extract CSS, but not eliminate a generated empty js file.
See the mini-css-extract-plugin issue.

module.exports = {
  entry: {
    styles: './styles.scss', // generates expected `styles.css` and unexpected `styles.js`
  },
}

This plugin remove unexpected empty js file.

Note

This is improved fork of the plugin webpack-fix-style-only-entries v0.6.0.
The plugin support Webpack 5 only. For Webpack 4 use original plugin.

Warning

The new version 1.0.0 has probable BRAKING CHANGE.
In this version was reverted defaults behavior as in v0.8.1 - remove empty scripts before processing other plugins.

Migration to v1.0.0

When update from <= v0.8.1, nothing needs to be done.
When update from v0.8.2 - v0.8.4, if you have an issue, try to use new stage option with RemoveEmptyScriptsPlugin.STAGE_AFTER_PROCESS_PLUGINS value.


Usage with Pug

If you use Pug with this plugin, then you should use the pug-plugin.
Pug plugin enable to define Pug files in Webpack entry, extract JS and CSS from their sources used in Pug.

Define Pug files in Webpack entry:

const PugPlugin = require('pug-plugin');
module.exports = {
  entry: {
    // all script and style sources can be defined directly in Pug
    index: './src/views/index.pug',      // => dist/index.html
  },
  plugins: [
    // enable using Pug files in Webpack entry
    new PugPlugin({
      // extract CSS from style sources defined in Pug
      extractCss: {
        filename: 'assets/css/[name].[contenthash:8].css',
      },
    }),
  ],
};

Use source files of styles and scripts directly in Pug:

link(href=require('./styles.scss') rel='stylesheet')
script(src=require('./main.js'))

Generated HTML contains hashed CSS and JS output filenames:

<link href="/assets/css/styles.05e4dd86.css" rel="stylesheet">
<script src="/assets/js/main.f4b855d8.js"></script>

The single pug-plugin replaces the functionality of html-webpack-plugin mini-css-extract-plugin webpack-remove-empty-scripts and pug-loader.


Install

npm install webpack-remove-empty-scripts --save-dev

Usage

The example of webpack.config.js:

const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const RemoveEmptyScriptsPlugin = require('webpack-remove-empty-scripts');

module.exports = {
    entry: {
        'main' : './app/main.js',
        'styles': ['./common/styles.css', './app/styles.css']
    },
    module: {
        rules: [
            {
                test: /\.css$/,
                use: [
                    MiniCssExtractPlugin.loader,
                    'css-loader',
                ]
            },
        ]
    },
    plugins: [
        new RemoveEmptyScriptsPlugin(),
        new MiniCssExtractPlugin({
            filename: '[name].[chunkhash:8].css',
        }),
    ],
};

Options

enabled

Type: boolean Default: true
Enable / disable the plugin. Tip: Use disable for development to improve performance.

stage

Type: number
Values:

  • RemoveEmptyScriptsPlugin.STAGE_BEFORE_PROCESS_PLUGINS (default)
    Remove empty scripts before processing other plugins.
    For example, exact this stage needs for properly work of the webpack-manifest-plugin.
  • RemoveEmptyScriptsPlugin.STAGE_AFTER_PROCESS_PLUGINS
    Remove empty scripts after processing all other plugins.
    For example, exact this stage needs for properly work of the @wordpress/dependency-extraction-webpack-plugin.

Webpack plugins use different stages for their functionality. For properly work other plugins can be specified the stage when should be removed empty scripts: before or after processing of other Webpack plugins.

See usage example.

Warning

Because webpack-manifest-plugin and @wordpress/dependency-extraction-webpack-plugin needs different stages both plugins can't be used together with RemoveEmptyScriptsPlugin at one configuration.

extensions

Type: RegExp Default: /\.(css|scss|sass|less|styl)([?].*)?$/ Note: the Regexp should have the query part at end ([?].*)?$ to match assets like style.css?key=val
Type: string[] Default: ['css', 'scss', 'sass', 'less', 'styl']. It is automatically converted to type RegExp.
Search for empty js files in source files only with these extensions.

ignore

Type: string | RegExp | string[] | RegExp[] Default: null
Ignore source files.

remove

Type: RegExp Default: /\.(js|mjs)$/
Remove generated scripts.

verbose

Type: boolean Default: false
Show process information.

Recipes

Show logs to console by development

const isProduction = process.env.NODE_ENV === 'production';
new RemoveEmptyScriptsPlugin({ verbose: isProduction !== true })

Disable plugin by development to improve performance

const isProduction = process.env.NODE_ENV === 'production';
new RemoveEmptyScriptsPlugin({ enabled: isProduction === true })

Specify stage for properly work some plugins

For example, using @wordpress/dependency-extraction-webpack-plugin the empty scripts must be removed after processing all plugins.

const path = require('path');
const DependencyExtractionWebpackPlugin = require('@wordpress/dependency-extraction-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const RemoveEmptyScriptsPlugin = require('webpack-remove-empty-scripts');

module.exports = {
  output: {
    path: path.join(__dirname, 'public'),
  },
  entry: {
    'main': './src/sass/main.scss',
  },
  module: {
    rules: [
      {
        test: /\.scss$/,
        use: [MiniCssExtractPlugin.loader, 'css-loader', 'sass-loader'],
      },
    ],
  },
  plugins: [
    new MiniCssExtractPlugin(),
    new DependencyExtractionWebpackPlugin(),
    new RemoveEmptyScriptsPlugin({
      stage: RemoveEmptyScriptsPlugin.STAGE_AFTER_PROCESS_PLUGINS, // <- use this option
    }),
  ],
};

Identify only .foo and .bar extensions as styles

new RemoveEmptyScriptsPlugin({ extensions: /\.(foo|bar)$/ })

Usage a javascript entry to styles

Give an especial extension to your file, for example .css.js:

new RemoveEmptyScriptsPlugin({ extensions: /\.(css.js)$/ })

Remove generated scripts *.js *.mjs except *.rem.js *.rem.mjs

new RemoveEmptyScriptsPlugin({ remove: /(?<!\.rem)\.(js|mjs)$/ })

Recursive ignore all js files from directory, for example my-workers/

new RemoveEmptyScriptsPlugin({
  ignore: [
    /my-workers\/.+\.js$/,
  ]
})

Usage webpack-hot-middleware

new RemoveEmptyScriptsPlugin({
  ignore: [
    'webpack-hot-middleware',
  ]
})

See the test case.

Testing

npm run test will run the unit and integration tests.
npm run test:coverage will run the tests with coverage.

Who use this plugin

Also See

  • more examples of usages see in test cases
  • ansis - Formatting text in terminal with ANSI colors & styles.
  • pug-plugin - plugin for Webpack compiles Pug files to HTML, extracts CSS and JS from their sources specified in Pug.
  • pug-loader - loader for Webpack renders Pug to HTML or template function. Optimized for using with Vue.

License

ISC