webpack-contrib / extract-text-webpack-plugin

[DEPRECATED] Please use https://github.com/webpack-contrib/mini-css-extract-plugin Extracts text from a bundle into a separate file

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Entry chunks for .css files also creating .js files

AnalogMemory opened this issue · comments

My config file is working fine. But I've just noticed it's generating extraneous files based on the entry points. The entry for login generates the correct .css file from the .scss file but also creates a login.js file (it essentially has an empty function inside it). Is there a way to prevent this?

Currently using Webpack 2.6.0 and Extract Text Webpack Plugin 2.1.0

const path = require('path');
const webpack = require('webpack');

const ExtractTextPlugin = require('extract-text-webpack-plugin');

module.exports = {
  context: path.resolve(__dirname, './.'),
  entry: {
    'main': [
      './js/main.js',
      './sass/main.scss',
    ],
    'login': './sass/admin/login.scss',
  },
  output: {
    path: path.resolve(__dirname, '../public'),
    publicPath: '/public/',
    filename: 'scripts/[name].js'
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: [/(node_modules|bower_components)/],
        use: [
          {
            loader: 'buble-loader',
            options: {
              objectAssign: 'Object.assign'
            },
          }
        ],
      },
      {
        test: /\.(sass|scss)$/,
        use: ExtractTextPlugin.extract({
          use: [
            'css-loader',
            'sass-loader'
          ]
        })
      },
    ]
  },
  resolve: {
    modules: [
      "node_modules"
    ],
  },
  plugins: [
    new ExtractTextPlugin({
      filename: 'styles/[name].css',
      allChunks: true,
    }),
  ]
}

Here's what the extraneous login.js file contains:

!function(e){function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};
return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}var t={};
n.m=e,n.c=t,n.i=function(e){return e},n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{configurable:!1,enumerable:!0,get:r})},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};
return n.d(t,"a",t),t},n.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},n.p="/public/",n(n.s=5)}({5:function(e,n){}});

Sadly not with the current implementation, webpack 'natively' only understands JS and will emit a JS file with the code that gets added to the chunk by webpack into a separate .js file, I don't recommend to use any non JS file as an entry point in general, require/import in a JS entry is the better solution for non-JS resources atm. This may change in the intermediate future https://medium.com/webpack/the-new-css-workflow-step-1-79583bd107d7

This issue is unfortunate.

@AnalogMemory @hackingbeauty I was able to get around this problem by using https://github.com/AnujRNair/webpack-extraneous-file-cleanup-plugin. I have a pull request in to clean up files specified only in particular files.

To add to the conversation, I was able to successfully remove the redundant JS via these 2 Webpack plugins:

...
new HtmlWebpackPlugin({
  excludeAssets: [/index.js/]
}),
new HtmlWebpackExcludeAssetsPlugin()
...

Check out the HtmlWebpackExcludeAssetsPlugin here:
https://www.npmjs.com/package/html-webpack-exclude-assets-plugin

@hackingbeauty sadly this solution doesn't remove unwanted js files, just exclude them from generated html. And won't work without HtmlWebpackPlugin plugin.

@sscaff1 why do we want to stick to a size of a file? Why don't use a filename instead?

@hyzhak the size seemed weird to me too. I submitted a PR (which was accepted and published) to eliminate files from a particular path. That satisfied my use case. For example if I had webpack outputting the following directories
project/css/ <~~~ The plugin helps me eliminate all js files from this directory.
project/js/

If using the HtmlWebpackPlugin and HtmlWebpackExcludeAssetsPlugin solution above you can use rimraf as part of your build script to delete the files you don't want, something like -

"build": "NODE_ENV=production yarn run clean && webpack -p && rimraf dist/js/style.*.js"

Works for me...

Are there plans to support this in the future/milestone?

commented

I would like to see this as well.

Aaaa I see I am in the extract-text-webpack-plugin repo.
Btw. will there be any further support for extract-text-webpack-plugin in wp4/5/... ?

For those who work with mono repo this is an issue, because we don't want to important the styles in every application because it duplicates the css reference, that is why importing the common styles in the entry point is important and relevant IMO...

For example:

module.exports = {
  entry: {
    "assets-app": "./assets-app/src/index.js",
    "pages-app": "./pages-app/src/index.js",
    "styles": ["./common/styles.less", "./common/styles.scss"]
  },

assets-app and pages-app share the same styles...

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

@fqborges Your package seems to do the trick!

@fqborges Well done!