rollup-plugin-postcss icon indicating copy to clipboard operation
rollup-plugin-postcss copied to clipboard

Extract CSS separately for every file of the array of rollup entry points

Open toli444 opened this issue 6 years ago • 25 comments

Summary

When an array of entry points is provided to Rollup, it turns every entry point to separate output chunks. It would be great if there was a possibility to have the same for CSS files with this plugin. As for now the plugin just generates one CSS file which contains all the styles. Extracting CSS into a single file makes tree-shaking no to work, in case I want to ship only critical styles in the bundle.

Current behaviour

Bundle structure:

.
└───components
│   └─── Input
│       │   index.js
│   └─── Button
│       │   index.js
└───folder2
│   index.js
│   chunk.js
│   styles.css

Proposed behaviour

Bundle structure:

.
└───components
│   └─── Input
│       │   index.js
│       │   styles.css
│   └─── Button
│       │   index.js
│       │   styles.css
└───folder2
│   index.js
│   chunk.js
│   styles.css

To reproduce

This is the rollup config that I have to reproduce the issue with this plugin:

rollupConfig = {
    input: ['./src/components/Button/index.js', './src/components/Input/index.js'],
    output: [
        {
            dir: lib,
            format: 'cjs',
            sourcemap: true,
            exports: 'named'
        },
    ],
    plugins: [
        postcss({
                modules: true,
                extract: true,
                sourceMap: true,
                minimize: true
            })
    ]
}

toli444 avatar Mar 26 '19 08:03 toli444

has any progress for this feature ?

tianyingchun avatar Jun 26 '19 04:06 tianyingchun

This is what I am doing


const entryPoints = {
  entry1: 'src/entry1.js',
  entry2: 'src/entry2.js',
}

// this needs to be a different instance every time
function getPlugins(){
	return [postcss()]
}

const configs = Object.keys(entryPoints).reduce((configs, entry) => {
  const input = entryPoints[entry]

  const config = {
    input,
    output: {
      file: `build/${entry}.js`,
      format: 'esm',
      name: entry,
      globals,
    },
    plugins: getPlugins(),
    external,
  }
  configs.push(config)
  return configs
}, [])

module.exports = configs;

krvajal avatar Aug 06 '19 08:08 krvajal

@krvajal This is a bad workaround as it repeats the bundle process for each entry + produces code duplication...

Is there anything planned for this matter anytime soon ? @egoist

mlnor27 avatar Dec 22 '19 21:12 mlnor27

This is particularly important if you're bundling multiple apps that each contain their own styles for html, body, etc.

whatisaphone avatar Feb 21 '20 17:02 whatisaphone

Here's a use case:

You have a large react-rollup component library that is consumed by a create-react-app application. They only need one component, and also need to run postcss on that component's css to ensure it's properly scoped. The component library already ships each component as a separate entry point, but can't get the per-component css extracted, and are unable to support postcss in the consuming application.

frattaro avatar May 27 '20 19:05 frattaro

Could we do not extract css for our component library, but extract them in our final build website?, i mean somehow mark the css injection codes for later extraction?

SasanFarrokh avatar Dec 28 '20 09:12 SasanFarrokh

Same problem here, I would like to break in small chunks to expose a components package which will be imported later using NextJS.

wedneyyuri avatar Feb 26 '21 23:02 wedneyyuri

I also have this requirement. I would like my app to be able to import the library css separately for every component.

hnrchrdl avatar May 14 '21 12:05 hnrchrdl

well so far this is my workaround:

prerequisites:

yarn add -D glob or npm install --dev glob
// rollup.config.js

const glob = require('glob')
const path = require('path')
const postcss = require('rollup-plugin-postcss')

const bundleCss = () => {
  var config = []
  var files = glob.sync(path.resolve(__dirname, '**/*.css'))
  files.forEach(file => {
    var filename = file.substr(file.lastIndexOf('/') + 1, file.length).toLowerCase()
    config.push(
      postcss({
        include: file,
        extract: path.resolve(`dist/${filename}`),
        minimize: true
      })
    )
  })
  return config
}

modules.exports = {
  plugins: [
    ...bundleCss()
  ]
}

basically I am looping over all css files in my project, and returning an array of postcss plugin for each file

kamaladenalhomsi avatar Jun 12 '21 04:06 kamaladenalhomsi

has any progress for this feature ?

3lang3 avatar Mar 10 '22 07:03 3lang3

I have this requirement to.

laizp avatar Jun 02 '22 02:06 laizp

has any progress for this feature?

Brandonitas avatar Sep 21 '22 22:09 Brandonitas

+1, this would be very handy

iyinchao avatar Oct 12 '22 13:10 iyinchao

I created a plugin - rollup-plugin-lib-style that generates CSS separately for every file and imports these generated files, so the consumer of the package will not need to import each CSS file separately. You can give it a try

DanielAmenou avatar Oct 28 '22 12:10 DanielAmenou

Anything new about that ?

gde-pass avatar Jan 11 '23 14:01 gde-pass

has any progress for this feature?

uditalias avatar Jan 31 '23 16:01 uditalias

i pareparing create simular plugin to generates css modular support less, sass, postcss for rollup multi entries bundle at one time.

tianyingchun avatar Feb 01 '23 08:02 tianyingchun

@uditalias try @flatjs/forge-plugin-styling https://www.npmjs.com/package/@flatjs/forge-plugin-styling

image image image image image image image image

tianyingchun avatar Feb 02 '23 09:02 tianyingchun

BTW: rollup entries:

 'src/module1/module1.ts',
          'src/module2/module2.ts',
          'src/module0/index.ts',
          'src/module-no-style/index.ts',

tianyingchun avatar Feb 02 '23 10:02 tianyingchun

Hoping we can keep this issue open. My use case is that I am using rollup for a React Component Library. I want each js module to have it's own css sidecar.

cherylcarpenter avatar May 22 '23 20:05 cherylcarpenter

I'm looking to migrate a project out of webpack which should output one css file for each entry point. Output files are used in separate contexts, and styles should apply to each individually.

Here's a simplified example of what should happen:

// main.js
import "main.scss";

// main.scss
body { color: red }

// admin.js
import "admin.scss"

// admin.scss
body { color: blue }

Output should look the same as above, except the scss files would be compiled and output as css.

Instead, I get two js files and a single css file, with a filename based on the first entrypoint in rollup.config:

// main.css
body { color: blue } 
body { color: red }

(concatenation order appears to be bottom-up, but I'm not certain about that)

joemaller avatar Oct 17 '23 22:10 joemaller

Hoping we can keep this issue open. My use case is that I am using rollup for a React Component Library. I want each js module to have it's own css sidecar.

Cannot agree more! My case is when using preserveModules: true, I expect it can keep the CSS references for each module(file) so that only the necessary CSS can be included in the final bundle when the end user builds with webpack.

SunHuawei avatar Nov 08 '23 03:11 SunHuawei