egoist / rollup-plugin-postcss

Seamless integration between Rollup and PostCSS.
MIT License
676 stars 217 forks source link

Keep "import css" line to the output file? #204

Open yuyic opened 4 years ago

yuyic commented 4 years ago

Rollup Config

export default {
  input: "src/index.js",
  output: {
    file: "dist/index.js",
    format: "cjs"
  },
  plugins: [
    postcss({
      extract: true
    })
  ]
};

src/index.js

import "./index.less";

Expected bundle

require("./index.css") 
issue-label-bot[bot] commented 4 years ago

Issue Label Bot is not confident enough to auto-label this issue. See dashboard for more details.

whodoeshua commented 4 years ago

same issue for me! Is there any solution to realize that? Please tell me if you find that!!! thanks!

ShanonJackson commented 4 years ago

Same issue for me too

himself65 commented 4 years ago

I'm working on this. Related code:

https://github.com/egoist/rollup-plugin-postcss/blob/34811b79aa048b6895cd9a187470168e6c40e5e9/src/postcss-loader.js#L179-L186

himself65 commented 4 years ago

I have done this except for the last step. But I wonder that require("./index.css") which index.css is a really css file or js wrapped css file

himself65 commented 4 years ago

anyone can tell me the really production use? I have no idea now

ShanonJackson commented 4 years ago

The production use is this @Himself65

At the moment most library authors bundle an entire styles.css file which is all the styles needed for all their components; This is not ideal as it imports styles for components the consumer isn't using into their project.

If the requires(".css") statements are left in the output library consumers will automatically import only the critical css that they need as they import the components they want.

To get around this i issue iv'e created a hack work around which works for me in the meantime.

jackmellis commented 4 years ago

@ShanonJackson would you care to share your hack workaround?

We have a similar issue with this too. We have many small packages and having to manually import the css files at app level will be a real headache. I'd rather leave the import in the rolled-up package and then the app can just handle css imports.

ShanonJackson commented 4 years ago

We leave the actual .module.scss files in the output in our usecase but it looks something like this as our own rollup plugin and we turned off rollup-plugin-postcss

export function scss() {
    var styles = {};
    var filter = createFilter(["**/*.scss"]);
    return {
        transform(code, path) {
            if (!filter(path)) {
                return;
            } else {
                /* is scss */
                                // just replaces "@import "src/styles/variables" with the library name reference "@import "~qubic-lib/src/styles/variables"
                if (styles[path] !== code && (styles[path] || code)) {
                    styles[path] = code.replace(/src/g, "~qubic-lib/src").replace(/-legacy/g, "");
                }
                return '';
            }
        },
        generateBundle() {
            /* Outputs css files doesn't touch js files */
            return Promise.all(Object.keys(styles).map((key) => {
              /* Output the files to their directory in dist */
        /* basically fileName.replace("src", "dist")
           writeFileSync Each File
         */
            }))
        },
    }
}
Flcwl commented 3 years ago

Any new?

juenanfeng commented 2 years ago

we choose add 'import css' line to the dist file after build finish with fs.writefile

SunHuawei commented 8 months ago

It's not only about keeping the import statement, but also keeping the .css extension, and the CSS format.

As I mentioned here, I've drafted a plugin for this.

Here is the original comment, I appreciate any idea to improve this.

I'm in the same situation. I have source files in this structure

- src
    - components
        - button
            - index.js
            - index.scss
    - index.js
    - index.scss

I expected the dist files structure

- dist
    - components
        - button
            - index.js
            - index.css
    - index.js
    - index.css

And in dist/components/button/index.js, the CSS file import statement should be kept.

import './index.css';

And the name should be rather than import './index.scss.js';

I drafted a plugin to explain my idea, here is the codesandbox.

The file name is index.css rather than index.scss.js.

image

The content is plain CSS rather than JS.

image

Here is the main code

function scss() {
  return {
    name: "rollup-scss-to-css-plugin",
    transform(code, id) {
      if (id.endsWith(".scss")) {
        return new Promise((resolve, reject) => {
          const opts = {
            data: code,
            file: id,
            includePaths: [path.dirname(id)],
          };

          sass.render(opts, (error, obj) => {
            if (error) {
              reject(error);
              return;
            }

            this.getModuleInfo(id).meta.targetCSS = obj.css.toString();

            resolve({
              moduleSideEffects: "no-treeshake", // I have to use this to keep the chunk
              code: "export default {}", // fake code to keep chunk
              map: null,
            });
          });
        });
      } else {
        return Promise.resolve({ code, map: null });
      }
    },
    renderChunk(code, chunk, options, meta) {
      if (code.includes(".scss.js")) {
        return code.replace(".scss.js", ".css"); // dirty way to replace the code in consumer files
      } else if (chunk.fileName.endsWith(".scss.js")) {
        options.sourcemap = false; // the sourcemap is not able to be fixed, just sacrifice it
        chunk.fileName = chunk.fileName.replace(".scss.js", ".css"); // mutate this to fix the file name
        return this.getModuleInfo(chunk.facadeModuleId).meta.targetCSS; // replace the content with the plain css
      }
    },
  };
}

I'm not familiar with Rollup's mechanism, but I believe there must be a better way to achieve this. Anyone who has an idea, please let me know.

andrei9669 commented 5 months ago

hey, was looking into the same thing when the size of our css bundle started exceeding the size of the html. is there any chance for this to make work or are there any known alternatives?