New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Don't output empty JS files #151

Open
TomS- opened this Issue May 17, 2018 · 31 comments

Comments

Projects
None yet
@TomS-
Copy link

TomS- commented May 17, 2018

I have seen people use the Extract plugin and name the file the same to prevent a useless .js file, however, naming the file the same in this instance gives the error:
Conflict: Multiple assets emit to the same filename main.js

I only want to take a CSS file and run it though autoprefix and minify, I don't need it to output a JS file.

@evilebottnawi

This comment has been minimized.

Copy link
Member

evilebottnawi commented May 17, 2018

@TomS- can you create minimum reproducible test repo?

@TomS-

This comment has been minimized.

Copy link

TomS- commented May 17, 2018

@evilebottnawi Yup, I'll set it up this evening

@TomS-

This comment has been minimized.

Copy link

TomS- commented May 18, 2018

https://github.com/TomS-/minicss Sorry for the delay

@tiendq

This comment has been minimized.

Copy link
Contributor

tiendq commented May 21, 2018

@TomS- I'm not sure I understand your issue. Do you want to not output tailwind.js from importing tailwind.css because there is already a tailwind.js in your source?

@TomS-

This comment has been minimized.

Copy link

TomS- commented May 21, 2018

@tiendq I don't want Webpack to output a JS file for CSS. It seems strange to me for it to do that. At the moment I'm getting the CSS file and a JS file. I'm coming from Gulp so maybe it's just I don't understand Webpack.

@tiendq

This comment has been minimized.

Copy link
Contributor

tiendq commented May 22, 2018

@TomS- I don't want it too :)

@paulmasek

This comment has been minimized.

Copy link

paulmasek commented Jun 7, 2018

+1 Mainly because it'll probably fix Va1/browser-sync-webpack-plugin#69

@GiancarlosIO

This comment has been minimized.

Copy link

GiancarlosIO commented Jun 13, 2018

+1

@evilebottnawi

This comment has been minimized.

Copy link
Member

evilebottnawi commented Jun 15, 2018

Weppack is js bundle, i can not imagine why this might be necessary, please provide use case

@thewebsitedev

This comment has been minimized.

Copy link

thewebsitedev commented Jun 16, 2018

Same issue. I have a PHP application but I am managing assets with Webpack. With Webpack 4 & MiniCssExtractPlugin, generating CSS files is a pain at the moment. I need to directly load CSS file.

Part of my config:

{
    mode: "development",
    entry: {
        "admin": "./assets/admin/src/scss/theme.scss"
    },
    module: {
        rules: [
            {
                test: /\.(sa|sc|c)ss$/,
                use: [
	            MiniCssExtractPlugin.loader,
                    'css-loader',
                    'sass-loader'
                ],
            },
        ]
    },
    plugins: [
        new MiniCssExtractPlugin({
            filename: "[name].css",
            chunkFilename: "[id].css"
        })
    ],
    output: {
        path: path.resolve(__dirname, 'assets/admin/dist/css')
    }
},

Files generated are: admin.css & admin.js.

I don't need admin.js file. It's useless in my case.

@bregenspan

This comment has been minimized.

Copy link

bregenspan commented Jun 18, 2018

The cause of this is probably webpack/webpack#7300, which has been added to the Webpack 4.x milestone.

@jpdesigndev

This comment has been minimized.

Copy link

jpdesigndev commented Jun 21, 2018

This issue is biting me as well. Feel free to close this if this plugin can't offer an alternative. Btw, webpack/webpack#7300 has been retagged with Webpack 5.x, so we won't likely see a fix in webpack until then.

@evilebottnawi

This comment has been minimized.

Copy link
Member

evilebottnawi commented Jun 22, 2018

We search way to fix it inside plugin

@danechitoaie

This comment has been minimized.

Copy link

danechitoaie commented Jun 30, 2018

Having same issue. I'm using webpack to compile both JS and SCSS and different entries (i.e. not requiring the css inside JS) and for each .css file generated I also get a .js file.

@Igloczek

This comment has been minimized.

Copy link

Igloczek commented Jul 4, 2018

@Igloczek

This comment has been minimized.

Copy link

Igloczek commented Jul 4, 2018

My temporary solution is to use this plugin - https://github.com/medfreeman/ignore-assets-webpack-plugin
Works with v4, but use deprecated methods.

@danechitoaie

This comment has been minimized.

Copy link

danechitoaie commented Jul 4, 2018

I had to make my own plugin:

class MiniCssExtractPluginCleanup {
    apply(compiler) {
        compiler.hooks.emit.tapAsync("MiniCssExtractPluginCleanup", (compilation, callback) => {
            Object.keys(compilation.assets)
                .filter(asset => {
                    return ["*/scss/**/*.js", "*/scss/**/*.js.map"].some(pattern => {
                        return minimatch(asset, pattern);
                    });
                })
                .forEach(asset => {
                    delete compilation.assets[asset];
                });

            callback();
        });
    }
}

It's very specific for my use case and has things hardcoded and I even have just put it directly in the webpack.config.js file (so not published on npm) but maybe it can be integrated somehow in some version directly into mini-css-extract-plugin? And made configurable with some additional options.

@riccardomessineo

This comment has been minimized.

Copy link

riccardomessineo commented Jul 10, 2018

To give you another "solution", I'm currently just excluding the useless .js on the bundled index.html:

        plugins: [
            new HtmlWebpackPlugin({
                template: './app/index_webpack.html',
                excludeAssets: [/partials.*.js/],
            }),
            new HtmlWebpackExcludeAssetsPlugin()
        ],
@Igloczek

This comment has been minimized.

Copy link

Igloczek commented Jul 10, 2018

@riccardomessineo correct me if I'm wrong, but it still generates those files, but don't add them to the html file, right?

@riccardomessineo

This comment has been minimized.

Copy link

riccardomessineo commented Jul 10, 2018

@Igloczek you're perfectly right.
It does not resolve the issue, I just wanted to provide another workaround.

@fqborges

This comment has been minimized.

Copy link

fqborges commented Aug 21, 2018

I faced the same issue of having a style only entry (css/sass/less) generating an extra .js file, and ended up creating a webpack plugin to remove the js file from the compilation.

I published it on npm as webpack-fix-style-only-entries. You can find the source code on https://github.com/fqborges/webpack-fix-style-only-entries.

:-) shamelessly promoting my package :-)

@michael-ciniawsky

This comment has been minimized.

Copy link
Member

michael-ciniawsky commented Aug 24, 2018

I have seen people use the Extract plugin and name the file the same to prevent a useless .js file, however, naming the file the same in this instance gives the error:
Conflict: Multiple assets emit to the same filename main.js

Use { filename: '[name].css' }. The empty JS File is going away (in webpack >= v5.0.0), but this needs to be fixed in webpack core itself

@michael-ciniawsky michael-ciniawsky changed the title Feature Request: Don't output JS file Don't output empty JS files Aug 24, 2018

@evilebottnawi

This comment has been minimized.

Copy link
Member

evilebottnawi commented Aug 24, 2018

@michael-ciniawsky bug, still open before it was fixed in webpack

@evilebottnawi evilebottnawi reopened this Aug 24, 2018

@artemkochnev

This comment has been minimized.

Copy link

artemkochnev commented Aug 27, 2018

@fqborges I'm trying to use your plugin, but I'm running into a problem where the file is getting passed as * instead of the actual file path.

For example, if I add a console.log(resources, file), I get a bunch of results like this: [ '<redacted>/src/app/css/pages/Home.scss' ] '*'

Do you know why this might be happening? The webpack docs on what gets passed for the chunkAsset hook are fairly light...

@fqborges

This comment has been minimized.

Copy link

fqborges commented Aug 27, 2018

@artemkochnev would you mind to open an issue here to provide me more info? Relevant parts of your webpack.config, webpack version, etc.

@chrisckc

This comment has been minimized.

Copy link

chrisckc commented Nov 14, 2018

To remove these redundant js files from my test project, I tried the HtmlWebpackExcludeAssetsPlugin as suggested by @riccardomessineo and found that it broke the app. The app no longer loaded correctly, even though all of the js files (except the almost empty ones which are generated due to the css splitting) are downloaded by the browser, the js doesn't seem to be executed.

I also tried , in addition to the above, removing the files from the compilation using the plugin method provided by @danechitoaie

When using the plugin method, i still needed to use HtmlWebpackExcludeAssetsPlugin because the redundant js files were still being added to index.html despite not being outputted.

Maybe these redundant files are still required by the runtime?
I am not going to spend any more time on this as its not a major issue, it's just not clean. I guess i will have to wait for webpack v5?

@mojilla

This comment has been minimized.

Copy link

mojilla commented Nov 19, 2018

@riccardomessineo
HtmlWebpackExcludeAssetsPlugin broke the app.

@riccardomessineo

This comment has been minimized.

Copy link

riccardomessineo commented Nov 19, 2018

Sorry to hear that...
As I pointed before, it was just a workaround and not a viable clean final solution.

@tflori

This comment has been minimized.

Copy link

tflori commented Dec 25, 2018

@danechitoaie thx for the tip!

I've just created a more abstract class to do this:

class Without {
    constructor(patterns) {
        this.patterns = patterns;
    }

    apply(compiler) {
        compiler.hooks.emit.tapAsync("MiniCssExtractPluginCleanup", (compilation, callback) => {
            Object.keys(compilation.assets)
                .filter(asset => {
                    let match = false,
                        i = this.patterns.length
                    ;
                    while (i--) {
                        if (this.patterns[i].test(asset)) {
                            match = true;
                        }
                    }
                    return match;
                }).forEach(asset => {
                    delete compilation.assets[asset];
                });

            callback();
        });
    }
}

module.exports = {
    mode: process.env.NODE_ENV || 'development',
    resolve: {
        extensions: ['.scss', '.css']
    },
    module: {
        rules: [
            {
                test: /\.scss$/,
                use: [
                    MiniCssExtractPlugin.loader,
                    'css-loader',
                    'sass-loader',
                ],
            },
        ],
    },
    plugins: [
        new MiniCssExtractPlugin({
            filename: '[name]',
        }),
        new Without([/\.css\.js(\.map)?$/]), // just give a list with regex patterns that should be excluded
    ],
};
@Jorenm

This comment has been minimized.

Copy link

Jorenm commented Jan 11, 2019

I forked disable-output-webpack-plugin to allow me to conditionally remove the outputs (https://github.com/Jorenm/disable-output-webpack-plugin/tree/options)

I use it with this config, which works like a charm:

var stylusCompiler = {
	name: 'stylus',
	entry: {
		above_fold: './src/css/above_fold.styl',
		site: './src/css/site.styl'
	},
	output: {
		path: path.resolve(__dirname, 'dist/css'),
	},
	module: {
		rules: [
			{
				test: /\.styl$/,
				use: [
					{
						loader: MiniCssExtractPlugin.loader,
						options: {
							// you can specify a publicPath here
							// by default it use publicPath in webpackOptions.output
							publicPath: '../'
						}
					},
					{
						loader: "css-loader" // translates CSS into CommonJS
					},
					{
						loader: "stylus-loader", // compiles Stylus to CSS
						options: {
							use: [
								require('nib')(),
								require('rupture')()
							]
						}
					},
				]
			},
		]
	},
	plugins: [
		new MiniCssExtractPlugin({
			filename: '[name].bundled.css',
		}),
		new DisableOutputWebpackPlugin({
			test: /\.js$/
		})
	],
	optimization: {
		minimizer: [new OptimizeCSSAssetsPlugin({})],
	}
};
@wzc0x0

This comment has been minimized.

Copy link

wzc0x0 commented Jan 14, 2019

@danechitoaie thx for the tip!

I've just created a more abstract class to do this:

class Without {
constructor(patterns) {
this.patterns = patterns;
}

apply(compiler) {
    compiler.hooks.emit.tapAsync("MiniCssExtractPluginCleanup", (compilation, callback) => {
        Object.keys(compilation.assets)
            .filter(asset => {
                let match = false,
                    i = this.patterns.length
                ;
                while (i--) {
                    if (this.patterns[i].test(asset)) {
                        match = true;
                    }
                }
                return match;
            }).forEach(asset => {
                delete compilation.assets[asset];
            });

        callback();
    });
}

}

module.exports = {
mode: process.env.NODE_ENV || 'development',
resolve: {
extensions: ['.scss', '.css']
},
module: {
rules: [
{
test: /.scss$/,
use: [
MiniCssExtractPlugin.loader,
'css-loader',
'sass-loader',
],
},
],
},
plugins: [
new MiniCssExtractPlugin({
filename: '[name]',
}),
new Without([/.css.js(.map)?$/]), // just give a list with regex patterns that should be excluded
],
};

very well ! Thanks !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment