[HN Gopher] Parcel CSS: A new CSS parser, compiler, and minifier
___________________________________________________________________
Parcel CSS: A new CSS parser, compiler, and minifier
Author : Lapz
Score : 211 points
Date : 2022-01-12 17:05 UTC (5 hours ago)
(HTM) web link (parceljs.org)
(TXT) w3m dump (parceljs.org)
| systemvoltage wrote:
| Unrelated but regarding SCSS/SASS: I am curious, why did we
| invent a new syntax for scss instead of writing a library in
| Python or Go that maps data-objects to CSS classes? You have full
| access to a proper programming language instead of this new DSL
| we need to learn. I tried searching for it but no luck, any
| reason why we don't do this?
| eatonphil wrote:
| It's called interoperable css [0] or css modules [1].
|
| [0] https://github.com/css-modules/icss
|
| [1] https://github.com/css-modules/css-modules
| iaml wrote:
| > I am curious, why did we invent a new syntax for scss instead
| of writing a library in Python or Go that maps data-objects to
| CSS classes?
|
| I mean, if using js/ts is not beneath you I'm pretty sure any
| css-in-js solution fits the bill.
| assemblylang wrote:
| no_wizard wrote:
| This is amazing! Seen a lot of work around Rust and JS / JSX / TS
| / TSX (notably SWC[0] is moving to be a Rust based version of
| Babel) not so much around CSS.
|
| My genunine hope is this will replace PostCSS sooner rather than
| later. PostCSS isn't the most performant thing I've worked with,
| and a lot of plugins for PostCSS rely on doing multiple passes at
| the AST, they can slow down significantly as a result
|
| For that however, we will need some kind of plugin system. I know
| the SWC[0] project has had some struggles with this as their
| current JS API relies on serializing the AST back and forth. I
| wonder if this forgoes a JS API entirely or if that is something
| planned for say 1.5?
|
| [0]: https://swc.rs/
| devongovett wrote:
| Hi, author of Parcel CSS here.
|
| I have been thinking about implementing the CSS OM spec as the
| JS API. This is the same API that browsers expose for
| manipulating stylesheets. The advantage of this is that we
| don't need to invent something custom. Still thinking through
| options. https://github.com/parcel-bundler/parcel-css/issues/5
|
| That said, I think I'd want to keep the use cases for JS
| plugins limited, because it will affect performance
| significantly. So, if it's something that exists in an official
| CSS spec somewhere (even if draft), or a really common
| transformation, it should be implemented in Rust. An example of
| this is the support for the CSS nesting spec. Ideally, we'd try
| to keep the amount of custom syntax being invented around CSS
| to a minimum and stick to standard CSS syntax wherever possible
| though.
| jafitc wrote:
| Is this something that can run in browser Workers via wasm or
| other means?
|
| Most of CSS OM is already implemented in Javascript which can
| come in handy for this project:
|
| https://github.com/NV/CSSOM
|
| https://github.com/jsdom/cssstyle
|
| (both of which jsdom use internally. cssstyle is a kind of
| updated version for some parts of CSSOM)
| devongovett wrote:
| Yes, there is a WASM build used by the demo:
| https://parcel-css.vercel.app
|
| Not sure if we could reuse these packages though, since
| we'd need to expose an API from Rust to JS anyway.
| no_wizard wrote:
| Separate question, that may be seemingly unrelated however
| I'm curious.
|
| How did you kinda "learn" how to read these specs
| effectively? I can read them, and I think I can _reasonably_
| understand them, however I feel like I have little confidence
| in saying _yes I get this_.
|
| Is there anything you point to that helps? Tips or
| recommendations?
|
| I'm trying to learn how to parse these standards docs better
| myself.
| andrei_says_ wrote:
| Does this include dart scss processing?
| TameAntelope wrote:
| I was just looking at Parcel a week or so ago to replace the
| stagnated Snowpack project for our frontend.
|
| Should I just stop trying to avoid it and just use Webpack 5, or
| can I actually rely on Parcel in a way I couldn't Snowpack?
|
| I just want to bundle my React app, I'm not trying to do anything
| special...
| annoyingmous wrote:
| 01acheru wrote:
| Parcel is becoming my go-to choice most of the time now. I've
| migrated some apps out of CRA, pure Webpack and Snowpack to it
| and I need to say it was incredible.
|
| Some minor issues with HMR on one of those projects I still
| can't figure out. Anyway having something that works, with JSX,
| with TS, really fast, in just 2/3 really simple steps is
| amazing! You don't even need to turn your brain on.
|
| My two cents.
| ReleaseCandidat wrote:
| I used Parcel for about a week a month ago. Couldn't get the
| HTTPS server to use my certificate and key and would have
| needed to write a plugin so that it wouldn't rename favicons
| and delete files not mentioned in the HTML file.
|
| So, Esbuild for 'no configuration' as it is significantly
| faster than Parcel and Webpack for more complex stuff.
| CognitiveLens wrote:
| Parcel has been around for awhile, and the project currently
| has a lot of activity - I've made the call to migrate an old
| create-react-app project to Parcel 2 and in general it is going
| well.
|
| The nice thing about Parcel is that it is intentionally low-
| config with relatively intuitive defaults, which tells me that
| it wouldn't be terribly difficult to move to a different
| bundler in the future. Webpack has gotten better, but you can
| quickly end up with a _lot_ of Webpack-specific config that
| makes future migrations hard.
|
| That said, optimizing for future migrations shouldn't generally
| be your #1 priority - I also like Parcel's speed, and new
| things like ParcelCSS just validate that further.
| nawgz wrote:
| Snowpack, ESBuild, ..., all promised us nice frontend compiles,
| yet I still turn to Webpack every time I actually want
| everything to work - you always hit roadblocks you can't solve
| in these other tools.
|
| That'd be my recommendation to you, still, sadly.
| armchairhacker wrote:
| I recommend Vite. I use ESBuild in some libraries but it has
| a learning curve. Vite's experience is similar to Webpack.
| omnimus wrote:
| Not my experience. Both esbuild and vite have been great for
| my usecases.
| no_way wrote:
| Use Vite instead, it has very nice developer experience.
| Webpack is a "legacy" bundler, while it is supported, is
| shouldn't really be used in new projects if you really value
| your sanity.
| nicoburns wrote:
| I'd argue that Vite's still pretty immature. It's great if
| you can stick within what works with it, but webpack is still
| the gold standard in terms of compatibility and features, and
| I suspect that will be the case for another couple of years
| while the native code bundlers (esbuild, swc, etc) catch up
| with their JS counterparts.
| krono wrote:
| Webpack is under active development though, nothing legacy
| about it as far as I'm aware. Are you referring to abandoned
| third-party plugins maybe?
|
| Vite and all the other bundlers are really awesome, but
| Webpack's strenght - and I think this may also be the root of
| the issues you seem to be having with the tool - is that
| there's almost no magic and barely any handholding. Freedom
| and reliability at the cost of having to build your own
| configuration (it's just dumping plugin config objects in an
| array, really not difficult).
| 01acheru wrote:
| > it's just dumping plugin config objects in an array,
| really not difficult
|
| Until you eject a CRA :)
| krono wrote:
| Which is the cherry on top for those types of self-
| chastisement fetishists who willingly put themselves at
| the mercy of CRA ;-)
| no_way wrote:
| I have done manual configs from scratch in Rollup, even
| wrote bunch of plugins for stuff like custom css class
| minifying and web worker support, so no I don't need
| handholding :) Setting it all up was even fun, everything
| was well documented and clear, with Webpack on the other
| hand, you only have fun if you like pain.
| tiborsaas wrote:
| > Webpack is a "legacy" bundler
|
| How did you end up with this assessment? I'm not a fan
| either, but it's still very popular, I doubt it will go away
| in the next 5 years.
| no_way wrote:
| It won't go away, it will still be supported and used for
| many years, but majority of new projects today won't use
| it. Brief history: Rollup dramatically improved bundler
| plugin and ES modules situation, then came new super fast
| bundlers like Esbuild and finally solutions combining both
| like Vite. Webpack is still playing catch up with that.
| There is literally zero reasons to choose clunky, slow
| Webpack configs, while alternatives exist, unless you have
| a legacy codebase and migrating is not an option.
| pferdone wrote:
| I seriously don't get the hatred Webpack receives. Calling it
| legacy when it introduced stuff like module federation is
| unfair to say the least. Just because a lot of people use CRA
| or some "zero config" bundler, or because esbuild etc are
| picking up momentum, doesn't mean it's bad. The documentation
| is actually really good IMO.
| samhuk wrote:
| I have been using esbuild for a while, and I can say that it's
| looking like a huge improvement over webpack, snowpack, vite,
| etc.
|
| I made a web app starter that uses esbuild to bundle a react-
| redux app [0] and my experience was very positive of the
| bundler.
|
| [0] https://github.com/samhuk/tree-starter
| dgellow wrote:
| That's awesome, great job!
| Semiapies wrote:
| The syntax lowering and modules handling might be really nice.
| Maybe even the tree-shaking. Minification, thought, especially
| with this level of parsing, just seems like an elaborate waste of
| effort if the web server is set to gzip the final CSS file,
| anyway.
| throw10920 wrote:
| After I saw the title, I thought "oh, it seems to kind of occupy
| the same space as esbuild, but for CSS. I wonder if the devs gave
| any thought to performance?" Then I clicked the link and saw that
| there a _direct comparison_ with esbuild, with Parcel being 3x
| faster on a large real-world benchmark (Bootstrap 4).
|
| This is really impressive. Although Rust tooling is rather
| suboptimal, Rust _programs_ seems to have quite the performance
| edge. I 'll take the RESF any day as long as it means getting
| away from ultra-heavy webtech everywhere.
| chronogram wrote:
| In the playground, why does 'yellow' get converted to '#ff0' but
| 'green' remains 'green'?
| pastelsky wrote:
| Because the hex for green (#00ff00) needs more letters than
| using the named color.
| dymk wrote:
| That's an... interesting optimization, and one that might
| make sense if you only care about byte size, but intuition
| (which might be wrong!) tells me that this will be more
| expensive (especially if it saves only one or two bytes).
|
| I'd bet that browsers can more quickly parse a string like
| '0x00ff00' into its internal color representation than it can
| parse the string 'green'. It's probably faster to check for a
| '0x' prefix and convert hex-encoded ASCII to u8 values, than
| it is to normalize the string & do a lookup in a dictionary
| of 147 CSS3 color names, when taking into account the extra
| two bytes that need to be transferred.
| assemblylang wrote:
| pawelmurias wrote:
| I doubt that difference it takes to parse green vs a
| 0x00ff00 is at all significant. It only should happen once
| per page load.
| gampleman wrote:
| Don't know, but I wouldn't be surprised if the browser
| first tried a dict lookup (which is super fast) and only
| then tried to actually parse hex the string.
| CognitiveLens wrote:
| I don't get the sense that runtime CSS parsing is really
| much of a concern - it's more about build speed and asset
| size - since 'green' might be used hundreds of times in a
| large CSS bundle, the optimization might make sense even
| with an imperceptible speed cost in the browser.
| rattray wrote:
| I don't have intuition here, but perhaps transferring two
| bytes over a slow network takes longer than the string
| normalization and dictionary lookup?
| marcosdumay wrote:
| > one that might make sense if you only care about byte
| size
|
| A minimizer should care a lot abut size. I'm not sure what
| would be faster, but the difference must be minimal anyway,
| so it's safe to focus on your default concern.
| robocat wrote:
| More importantly, I would expect #00ff00 to compress better
| than green, because it would usually make the CSS file more
| predictably repetitive. Reducing network bytes is usually
| very important for speeding up loading (at least it is in
| the boondocks of the internet - out at the rim of the
| world).
| ry4nolson wrote:
| Someone else mentioned this already but "green" is not
| #00ff00. Tt's #008000.
| [deleted]
| rawling wrote:
| Wouldn't that shorten to #0f0? But "green" is #008000, which
| doesn't shorten?
| chronogram wrote:
| Ah thanks, I assumed '#0f0' as well. I guess it is length
| based then.
| zamadatix wrote:
| Hmm I wonder which approach is actually better overall when
| it comes to content-encoding like their own site uses
| (brotli compression) or client side parsing performance.
| It's all probably a bit off into the weeds over something
| like 0.05% performance though.
| davidhariri wrote:
| Parcel is a great project that has made it much quicker to
| develop a SPA. This only furthers my sense of joy for it.
| sfvisser wrote:
| What does it mean to compile CSS? Pack multiple files into one?
| Resolve and inline variables? Convert nested rules into flat CSS?
| Something else?
|
| I'm really not sure.
| [deleted]
| eatonphil wrote:
| Elitism about the term "compiler" aside, I've been reading
| through The History of the FORTRAN Programming Language and
| funnily enough compile in those historic CS contexts just meant
| what "to compile" means in English: merging things together.
| It's an interesting read whatever the case.
|
| [0] https://www.goodreads.com/book/show/52320048-abstracting-
| awa...
| sfvisser wrote:
| This is not about elitism about terminology, but about
| sloppiness in using well established words in a specific
| context to mean something new. It happens rather frequently
| in the frontend world - which I'm sometimes a part of - and
| it's incredibly confusing to all of us.
| eatonphil wrote:
| I write frontend code and backend code and do compiler
| stuff for fun and I don't find it confusing. "Compiler"
| means completely separate things in so many contexts that I
| get the general picture and always need to look deeper to
| truly understand. Just because it's a generic term doesn't
| mean anyone should not be allowed to use it IMO.
| JonathonW wrote:
| > In addition to minification, Parcel CSS handles compiling CSS
| modules, tree shaking, automatically adding and removing vendor
| prefixes for your browser targets, and transpiling modern CSS
| features like nesting, logical properties, level 4 color
| syntax, and much more.
| [deleted]
| codebeaker wrote:
| Had you taken the time to open the link, the 2nd paragraph
| states their capabilities succinctly:
|
| > Parcel CSS has significantly better performance than existing
| tools, while also improving minification quality. In addition
| to minification, Parcel CSS handles compiling CSS modules, tree
| shaking, automatically adding and removing vendor prefixes for
| your browser targets, and transpiling modern CSS features like
| nesting, logical properties, level 4 color syntax, and much
| more.
| sfvisser wrote:
| I've obviously read that. Most of those features are what we
| used to call CSS pre-processors, but I'll happily call that
| compilation if that's a thing now.
| rattray wrote:
| It wasn't obvious to me that you had read that paragraph.
| have_faith wrote:
| It's in the first couple paragraphs
|
| > Parcel CSS handles compiling CSS modules, tree shaking,
| automatically adding and removing vendor prefixes for your
| browser targets, and transpiling modern CSS features like
| nesting, logical properties, level 4 color syntax, and much
| more.
| emrah wrote:
| Its GitHub repo calls it a "transformer" rather than a
| compiler.
|
| https://parceljs.org/features/plugins/#transformers
| aarchi wrote:
| > Parcel CSS is based on the cssparser[0] Rust crate, a browser-
| grade CSS tokenizer created by Mozilla and used in Firefox. This
| provides a solid foundation, including tokenization and basic
| parsing. However, it does not interpret any CSS properties or at
| rules. That's where Parcel CSS comes in. It handles parsing each
| individual rule and property value, as well as minification,
| compilation, and printing back to CSS.
|
| https://github.com/servo/rust-cssparser
| [deleted]
| kevincox wrote:
| It's really nice to see browser components being able to be
| reused easily rather than a bunch of half-assed parsers.
| mikepurvis wrote:
| Nice too that it's a compiled language, so you get the end
| tool in a nice static binary. As a non-Node dev, I hate the
| experience of hacking on some project and having to install a
| giant pool of NPM stuff just to run some minifier or linter.
| Hound is an example of this-- the guts of the project are
| golang, but it has a frontend that uses webpack, jest, etc:
| https://github.com/hound-search/hound
|
| Which is fine, I guess; definitely use the right tool for the
| job. And maybe Node developers hate finding my Python
| projects and needing to set up a virtualenv to run them in.
| But all the same, I approve a direction where more of this
| kind of tooling is available without a build-time Node
| dependency.
| hinkley wrote:
| Agreed. If cssparser blows chunks on your css then at least
| you know that will probably break some of your user agents
| too, rather than the game of "is my tool broken or am I?"
| tiffanyh wrote:
| Why is a product written in Rust have "JS" (javascript) in its
| URL name?
|
| I nearly didn't look at this because I didn't want another
| javascript dependance in my pipeline.
| hbn wrote:
| It seems Parcel CSS is a project from the creators of Parcel
| JS, which is a build tool. The URL isn't linking to the top-
| level page on the domain
| habitue wrote:
| For some reason I trust minifier / compiler benchmarks way more
| than I trust DB benchmarks. I wonder why that is?
|
| Maybe I expect DB workloads to be much more varied so benchmarks
| are less representative. Whereas with minifying you can run it
| against some large project and expect it'll reflect your real
| world experience
| swagatkonchada wrote:
| I feel stupid asking this question, but isn't the browser that
| parses css? i understand minifying css, but what does parcel's
| css parsing refer to?
| mbb70 wrote:
| It parses the css so it can improve the minification, for
| example converting 'margin: 4px 4px 4px 4px' into 'margin:4px'
| yosamino wrote:
| To do the job of minifying, this minifyer first reads the CSS
| file into an internal datastructure. That process is called
| parsing.
|
| All the minifying operations are done on that internal
| datastructure.
|
| Then it writes it out again into a textfile, ready for the
| browser to parse it again - hopefully the minifying step made
| it a bit easier for the browser to parse this minified CSS.
___________________________________________________________________
(page generated 2022-01-12 23:00 UTC)