Open mnlbox opened 4 years ago
I want to test the code splitting and multi entry with your package. After switching to your library rollup didn't create any output file at all without any error message but when I mix your plugin with rollup-plugin-sass
like bellow it's working:
import sass from "rollup-plugin-sass";
import nodeSass from 'node-sass'
import postcssSmartAsset from "postcss-smart-asset"
import styles from "rollup-plugin-styles"
const postcssSmartAssetOpts = {
url: 'inline'
}
plugins: [
sass({
runtime: nodeSass,
insert: true
}),
styles({
plugins: [postcssSmartAsset(postcssSmartAssetOpts)]
}),
]
...
Any idea about this?
Hi @mnlbox,
Is it supporting now or it's in your roadmap?
Yes, it is fully supported. And works just like Rollup's code splitting does, based on dynamic imports and preserveModules
/manualChunks
options. Also, you need to use extract
mode, otherwise CSS is stored inside JS and code splitting occurs on JS side:
styles({
mode: "extract",
// other stuff...
})
If yes I think some examples and docs about this can be useful.
Yes, probably should do that.
As for your example:
rollup-plugin-sass
just takes all the work and this plugin is not even used. postcss-smart-asset
plugin is not used in this case, or even might hurt the result, but if you really want to use it, disable the internal asset handler using url: false
:styles({
mode: "extract",
url: false,
plugins: [postcssSmartAsset(postcssSmartAssetOpts)]
})
As for the code splitting itself, just tested it to be sure nothing broke over time, and it works just fine, the simplest test is:
index.js
:
import("./style1.scss");
import("./style2.scss");
style1.scss
:
.style1 {
color: red;
}
style2.scss
:
.style2 {
color: blue;
}
If you think something is broken after reading/trying the above, please make a minimal reproduction repo using rollup's REPL, REPL.it, or just a simple GitHub repo.
@Anidetrix
Oh, thanks, everything is working fine. I also completely remove postcss-smart-asset
and using your plugin for asset handling. Just one question. Now I'm using bellow setting and I'm imported scss
files in my component but when my component build my CSS import was removed.
I also don't want to use inject
mode. I won't to use extract
but keep my @import url.
styles({
minimize: true,
mode: 'extract',
url: {
inline: true
}
}),
I have this line in my js source file:
import './index.scss'
and want to convert this to something like this after build:
t=require("./index-09905e20.css")
but now it's removed and because of this my component redreded without any styles. Is it normal to remove scss import from js file?
Is it normal to remove scss import from js file?
In extract
mode - this is intentional, since there's no require
in the browser. I'd imagine you would use it with something like @rollup/plugin-html, or just include the resulting CSS file yourself in your own HTML file. If you need to use CSS as a string inside JS, you can use named css
export, as it is described in the docs:
// Using named export of CSS string
import { css } from "./style.css";
If there's a real use case for keeping the require
statement in the final bundle, please tell me and we'll go from there.
@Anidetrix I don't understand your guide :thinking: I didn't use plugin-html
now and I think it's not helpful for my project.
Look this is my source structure:
├── FirstComponent
│  ├── index.scss
│ └── index.tsx
├── SecondComponent
│  ├── index.scss
│ └── index.tsx
So each component has its own style and imported like as I told for example in /FirstComponent/index.tsx
I have this line:
import './index.scss'
and this is the style related to this specific component But now because your plugin will remove this import, then my component styles gone and component breaks. :thinking: In code splitting output I need this structure:
├── FirstComponent
│ ├── index.css
│ └── index.js
├── SecondComponent
│ ├── index.css
│ └── index.js
Now the structure is OK but relation between css and js files removed.
@Anidetrix I think it's not documentation :thinking: Maybe we need a fix to prevent remove import.
@mnlbox imports are not kept since they are not JS, thus rollup cannot understand and process them properly. I guess this is not that clear, so this needs documentation and separate feature addition to add require
without breaking rollup. So this is labeled as both documentation
and enhancement
accordingly.
@Anidetrix But I didn't have a similar issue before when I used rollup-plugin-postcss
and my CSS import line not removed from my js files before. So I think it's not related to rollup :thinking:
@Anidetrix I still think it's a bug. Maybe related to these two issues: https://github.com/Anidetrix/rollup-plugin-styles/issues/120 https://github.com/Anidetrix/rollup-plugin-styles/issues/117
I also tried to change import './index.scss'
to require("./index.scss")
in my index.tsx
file. Now this line not removed from final files but the issue is that rollup-plugin-styles plugin didn't create any .css
files at all and it seems broken.
I don't know it's a bug or something missed in documentation especially in preserveModules: true
and extract
mode.
I also don't want to use
inject
mode. I won't to useextract
but keep my @import url.
I'm also running into this issue.
In
extract
mode - this is intentional, since there's norequire
in the browser.
@Anidetrix There is a use-case here, when using downstream bundlers. I'm using Rollup as an intermediate step for an UI library (which I think @mnlbox is also doing, judging from his filenames). While the browser can't recognize import statements, downstream bundlers can. It would be very useful if the import can stay in the bundle, so the end user of my library won't have to import the CSS separately.
You can view my project here, if you want to view for yourself. Run yarn && yarn build
in the main directory, and yarn && yarn serve
in the example
directory. Then go to http://127.0.0.1:1234/ to view the components without styling.
I understand this is not always useful to have. So I propose to add an setting like preserveImports
which, when true, keeps the imports in the bundle.
I took a shot at fixing it myself, but got stuck when actually writing the import statement. @Anidetrix can you help out here? I did find the output JS files, but the CSS files (and more importantly, their paths) were nowhere to be found.
@dsluijk Returning to work after a long break, will look into it.
That's great to hear! If you need any help let me know!
@dsluijk Returning to work after a long break, will look into it.
It's been a long time since you look into it.
Any updates on this?
Great to see that I'm not alone.
I left a comment here, and then found this page. It seems like the same topic, and since here are more people, so I just copied the comment here.
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
.
The content is plain CSS rather than JS.
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.
Hi @Anidetrix and thanks for starting this plugin. You told in ReadMe file that one of the reasons for this plugin is supporting code-splitting:
Is it supporting now or it's in your roadmap? If yes I think some examples and docs about this can be useful.