how to prevent mini-css-extract-plugin from creating a js entrypint
Asked Answered
G

4

7

I am relatively new to express + webpack, so i am unclear wether this is intended or not, and if not, how to properly configure it. the question is around the additional asset & entry point created when using the mini-css-extract-plugin.

webpack config:

Extract = require('mini-css-extract-plugin');
path = require('path');
Write = require('write-file-webpack-plugin');

module.exports = {
  mode: 'development',
  entry: {
    demo_scripts: path.resolve('server', 'scripts', 'demo.js'),
    demo_styles: path.resolve('server', 'styles', 'demo.css')
  },
  output: {
    path: path.resolve('.tmp'),
    filename: '[name].js'
  },
  plugins: [new Write(), new Extract()],
  module: {
    rules: [
      {
        test: /\.js$/,
        use: [
          {
            loader: 'babel-loader',
            options: {
              presets: ['babel-preset-env']
            }
          }
        ]
      },
      {
        test: /\.css/,
        use: [
          {
            loader: Extract.loader
          },
          {
            loader: 'css-loader'
          }
        ]
      }
    ]
  }
};

webpack output

          Asset      Size        Chunks             Chunk Names
demo_scripts.js  3.91 KiB  demo_scripts  [emitted]  demo_scripts
demo_styles.css  36 bytes   demo_styles  [emitted]  demo_styles
 demo_styles.js  3.89 KiB   demo_styles  [emitted]  demo_styles
Entrypoint demo_scripts = demo_scripts.js
Entrypoint demo_styles = demo_styles.css demo_styles.js

my question is, why is demo_styles.js being created? although the css is being extracted, it almost seems like webpack is still creating a bundled js with css, but when i view that file, the only line in it is

eval("// extracted by mini-css-extract-plugin\n\n//# sourceURL=webpack:///./server/styles/demo.css?");

can anyone help explain what is going on here?

UPDATE

if i remove the demo_styles entry point, and configure it via the plugin init, no css asset is built.

({
  plugins: [
    new Write(),
    new Extract({
      filename: 'demo_styles.css'
    })
  ]
});

Asset      Size        Chunks             Chunk Names
demo_scripts.js  3.91 KiB  demo_scripts  [emitted]  demo_scripts
Entrypoint demo_scripts = demo_scripts.js

the repo for this is here (note the express branch) https://github.com/brewster1134/bumper/tree/express

Georgettegeorgi answered 29/8, 2018 at 8:6 Comment(1)
webpack understands dependencies analysing the AST from your entrypoint. Your css has to be included in your dependency tree, this is, demo.css has to be included inside demo.jsMatthiew
N
1

After fidgeting with the same problem for a while, I cooked up a solution that leverages the afterEmit hook in Webpack and removes unwanted JS blanks after they are emitted.

Here's what you can do:

Step 1

Add a custom plugin that hooks to afterEmit and removes the unwanted files. The list of the files should be provided to the plugin constructor. You can add the plugin to webpack.config.js directly, but I found it more convenient to author in a separate module – in my case I created it under webpack-custom-plugins/remove-unwanted-files.js:

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

class RemoveUnwantedFilesPlugin {
  constructor(filesToRemove) {
    this.filesToRemove = filesToRemove;
  }

  apply(compiler) {
    compiler.hooks.afterEmit.tap('RemoveUnwantedFilesPlugin', (compilation) => {
      this.filesToRemove.forEach((file) => {
        const filePath = path.join(compilation.outputOptions.path, file);

        if (fs.existsSync(filePath)) {
          fs.unlinkSync(filePath);
        }
      });
    });
  }
}

module.exports = RemoveUnwantedFilesPlugin

Step 2 Import the plugin into webpack.config.js...

const RemoveUnwantedFilesPlugin = require('./webpack-custom-plugins/remove-unwanted-files');

...and register it:

   plugins: [
        // ...
        new RemoveUnwantedFilesPlugin(['demo_styles.js']),
   ],

This should solve your problem for a single CSS input. If you need to remove blank JS files from all standalone SCSS/CSS entries, I'd suggest authoring a snippet that filters your list of inputs and retains the ones that only contain stylesheet files. You can then pass the filtered list to the RemoveUnwantedFilesPlugin constructor to get rid of all blanks at once.

Nauseating answered 4/7, 2023 at 0:6 Comment(0)
K
0

There are two workarounds for your problem. For both of them, you need to change the entry point of the Webpack configuration file. I, personally, prefer the first option.

Option 1:

Change the entry to the following:

entry: {
    demo: [
        path.resolve('server', 'scripts', 'demo.js'),
        path.resolve('server', 'styles', 'demo.css'),
    ]
}

This will generate the following outputs (based on the filename you provided for Extract class and output section:

  • demo.js
  • demo_styles.css

Option 2:

For this option, you need to remove the CSS file from the entry point and import it inside the JS file:

webpack.config.js

...
entry: path.resolve('server', 'scripts', 'demo.js'),
...

demo.js

import './../styles.demo.css'
//rest of your JS codes

This solution will generate the same output as Option1

Karmakarmadharaya answered 7/2, 2020 at 11:17 Comment(0)
I
0

Webpack pulls everything into a js file, then MiniCssExtractPlugin takes it out of that file, leaving a blank js file with // extracted by mini-css-extract-plugin.

My solution is to group your css and js in the entry section of webpack.config.js

entry: {
    demo: {
        import: [ path.join("server", "scripts", "demo.js"), path.join("server", "styles", "demo.css") ],
        filename: "demo.js", // outputs demo.js, demo.css to your output directory
    },
    main: {
        import: [ path.join("server", "scripts", "main.js"), path.join("server", "styles", "main.css") ],
        filename: "main.js", // outputs main.js, main.css to your output directory
    },
}

Also, so naming works well, use this for your plugins section:

plugins: [
    new MiniCssExtractPlugin({
        filename: "[name].css"
    }),
],

Adjust the bundles "demo" and "main", as well as paths accordingly.

Ian answered 3/2, 2022 at 15:30 Comment(0)
H
-1

Please remove demo_styles from your entry point this is creating demo_styles.js.

instead you can inject css file like this:

plugins: [
      new MiniCssExtractPlugin({
        filename: 'demo_styles.css',
      }),

Let me know if the issue still persists, Happy to help

Humanist answered 29/8, 2018 at 8:27 Comment(3)
i had tried that based on the docs for that plugin, but without the entry point, no css is built at all. i added an update with those resultsGeorgettegeorgi
Can your share it via github ?Humanist
added the repo link to the bottom of the OP :)Georgettegeorgi

© 2022 - 2024 — McMap. All rights reserved.