Skip to content
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

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

Open
yuyic opened this issue Nov 15, 2019 · 13 comments
Open

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

yuyic opened this issue Nov 15, 2019 · 13 comments

Comments

@yuyic
Copy link

yuyic commented Nov 15, 2019

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") 
  • But the actual result is an empty bundle
@issue-label-bot

This comment has been minimized.

@whodoeshua
Copy link

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

@ShanonJackson
Copy link

Same issue for me too

@himself65
Copy link
Collaborator

I'm working on this. Related code:

if (shouldExtract) {
output += `export default ${JSON.stringify(modulesExported[this.id])};`
extracted = {
id: this.id,
code: res.css,
map: outputMap
}
} else {

@himself65
Copy link
Collaborator

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
Copy link
Collaborator

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

@himself65 himself65 changed the title How to keep "import css" line to the output file? Keep "import css" line to the output file? Mar 8, 2020
@ShanonJackson
Copy link

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
Copy link

@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
Copy link

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
Copy link

Flcwl commented May 17, 2021

Any new?

@juenanfeng
Copy link

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

@SunHuawei
Copy link

SunHuawei commented Feb 29, 2024

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
Copy link

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?

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

Successfully merging a pull request may close this issue.

9 participants