-
-
Notifications
You must be signed in to change notification settings - Fork 2.3k
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
Can I inline css to js file #1370
Comments
You can use fs.readFileSync to get the filecontents of a css file inlined |
Sorry for piggybacking @xbl question - I'm not sure my use case justifies opening another one: I am developing a widget. To use it a website will include a @DeMoorJasper, what in your opinion is the best way to have just the JS generated, but with code similar to this at its bottom:
(Simplified. Should probably do this inside an IIFE and also set an 'id' for style so it's easier to remove it if needed.) |
@targumon , @DeMoorJasper thank you for commented,I already use thank you again! |
Well it should work like this, parcel should inline any fs calls inside js var css = fs.readFileSync('./style.css'); // <-- The css reader
var style = document.createElement('style')
style.type = 'text/css'
style.appendChild(document.createTextNode(css))
document.head.appendChild(style) Will compile to... var css = 'div{border:1px solid tan}'; // <-- Parcel got this from the file
var style = document.createElement('style')
style.type = 'text/css'
style.appendChild(document.createTextNode(css))
document.head.appendChild(style) This however wouldn't work with any non pure css files. But i'm not sure how to achieve this in a clean way (with that I mean having a way to support both inlining and url without creating something parcel specific) |
This pushes me in the right direction. var css = fs.readFileSync(__dirname + '/../../dist/widget.3c2281aa.css', 'utf8') But as you can see now I have a problem with the name of the file which I can't control so this will break soon (unless I create a Packager as suggested in another issue) |
If you use multiple entrypoints it should keep a consistent (non-hashed) filename. For example running |
@DeMoorJasper how do you disable Parcel from creating a separate file when bundling though? Like I'd like this to be a single JS file so I do not have to import the styles again. import React from 'react';
import {manInTheMirror} from './ManInTheMirror.scss';
const ManInTheMirror = () => {
return (
<div className={manInTheMirror}>
{'Man in the mirror.'}
</div>
)
};
export default ManInTheMirror; I'm transpiling this before I publish the package. However, if I need to use the component again, I have to import two files instead of one. import ManInTheMirror from 'man-in-the-mirror';
import 'man-in-the-mirror/dist/ManInTheMirror.css'; Unless there's a way for Parcel to transpile packages in |
It would be very nice to have the option of bundling the css and other assets into a single js file. I'm running into this issue with vue components. I'm writing a vue library and I want to use parcel rather than vue-cli to build the npm package. I want to bundle the css and fonts with my npm package without the need to the end user needing to require these separately. Currently, I can't see a way to do this. The above workarounds don't work because most of my css is defined in vue components. |
I'm putting together a PR for this functionality. So far I've added a flag |
@RobertWHurst what about the PR? Is it still implemented? Want to have the CSS inside a JS file too. I do an import in my TS file, as I did it for webpack. |
@Chris2011 Decided to make a proper RFC since it requires new behavior. Nearly done, but I've been busy with work. Additionally, I want to make sure it's implemented cleanly and "with the grain" so to speak, as this is a big feature. |
I'm finding this problem interesting, but confused about the current status. The Given that we have a straightforward html and css setup, what's the inline css pattern which does not involve loading any javascript files? |
@dawsbot without js I think you can hack it with using a <style type="scss">
@import "./main.css";
</style> |
@DeMoorJasper I've attempted that method and no luck. The build html file still contains the untranspiled <style type="scss">
import "./index.css";
</style> This shows at the bottom of our |
@dawsbot I'll experiment a bit and get back to you |
@dawsbot This appears to work. <style type="text/styl">
@import "./main.css";
</style> This is however a hack and should not be considered safe from breaking in incremental builds. In Parcel 2 this should work out of the box without any hacks |
With the advent of Parcel 2 in the future, I've decided to hold off on my RFC and PR. The Parcel got this in the bag anyways 💯 |
I'm not really sure what the usecase is for inlining css into javascript instead of producing a separate file. If you use HTML as an entry point, Parcel will even insert the css file into your HTML for you automatically. This will lead to a much faster app as well since you don't have to wait for all of the JavaScript to be loaded, parsed, and executed in order to get styles on the page. For the library usecase, I don't think you necessarily want to determine in your library how users want to include your css. They might want to import them into their own css build rather than have them inline in JS. I think you should leave this up to users, or build systems of applications rather than only allowing inlined styles. |
That being said it will be possible to override and extend the JS and CSS transformers in parcel 2, so I think we can potentially solve this narrow usecase in plugins. |
The real use case is to have only one JS file at the end, nothing else. With HTTP2 of course you don't need it anymore but for HTTP1 you should avoid round trips. That a use case exists, you can see in this ticket here. Afaik, with webpack this is normal behaviour to have only one file at the end and there is a plugin to generate the css into an external file. So we have both use cases. Everything in one, single file and everything separeted. I'm fine with closing the issue too, if there is an easy possibility to change this behaviour in parcel2. My 2 cents. |
@devongovett A use case for inlining CSS is webcomponents with a shadow root, which can't inherit styles from the non-shadow DOM. |
@jhpratt
And for example usecase is: import { html, define } from "hybrids";
import styles from "./simple-counter.css";
export function increaseCount(host) {
host.count += 1;
}
export const SimpleCounter = {
count: 0,
render: ({ count }) => html`
<button onclick="${increaseCount}" class="button">
Counter: ${count}
</button>
`.style(styles)
};
define("simple-counter", SimpleCounter);
|
Also it should be possible to use But I did't succeeded |
As you noted in your edit, that doesn't work with preprocessors, which is a major limitation. @devongovett any updates on this? My previous comment has 16 +1's, so it certainly seems like there's interest in that specific use case. |
I also need this for the userscript use case. Userscripts are a single *.user.js file installed locally by Tampermonkey, Violentmonkey, etc. Ideally I would use Parcel to combine various JS and CSS files into a single JS file like these extensions expect. Right now I’m treating my CSS as a string in a JS file that gets bundled in. |
I need this to style my shadow dom element since styles won't be applied unless inlined with the shadow root |
(Parcel 2 supports this natively: import style from "bundle-text:./style.css";
class MyTest extends HTMLElement {
constructor() {
super();
let shadow = this.attachShadow({ mode: "open" });
let style = document.createElement("style");
style.textContent = style;
shadow.appendChild(style);
let info = document.createElement("span");
info.textContent = this.getAttribute("label");
shadow.appendChild(info);
}
}
customElements.define("my-test", MyTest); ) |
thank you so much for the snippet, I am using parcel-plugin-web-extension which doesn't support Parcel 2 for now is there a workaround to inline styles using parcel 1.12.4 ? |
@mischnic with parcel 2 I get
any clue? |
@mrassili did you tried? #1370 (comment) |
nah I ended up processing the styles using |
I tried that for the use case of web components and it works as expected. |
Yes |
Inspired by that comment I just released a Parcel V1 plugin, which inlines the css into the JS bundle and injects a https://github.com/AndyOGo/parcel-plugin-inject-style-tag |
Google Apps Script does not support css files, so inlinning makes sense... |
❔ Question
Can I inline css to js file,like webpack?
I want dist 1 js file
The text was updated successfully, but these errors were encountered: