You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
While CSS is technically considered a side effect, I would like a way to explicitly state that my CSS Modules are not side effects.
Background
I am building a library that stores a bunch of CSS Module files. The library will be consumed by my component library. The advantage of separating the CSS from the components is that I can write component libraries using multiple frameworks (e.g. React, Angular, and Vue) that all use the same exact styles. Since I am guaranteeing that my styles in any given file are locally scoped to only one component, I can guarantee that my CSS files are not side effects.
Currently, the output from this plugin looks something like the following:
Now, let's assume that I have 10 CSS files that I want to inject using CSS Modules. I essentially get 10 styleInject function calls and 10 named exports. Once I consume the build file, I'll want to do something like the following in my component file:
importReactfrom"react";// Assuming React just as an exampleimport{ButtonStyles}from"./index.es.js";// "index.es.js" is the build fileconstButton=({ title })=>{return<buttonclassName={ButtonStyles.button}>{title}</button>}
This works as expected, meaning that the button styles will be injected into the <head> element via styleInject. The problem is that I have 9 other style files that resulted in 9 other styleInject(..) function calls in the build file (i.e. index.es.js). Because these styleInject calls are not wrapped in a function with a /*#__PURE__*/ annotation, just one import will cause all 10 CSS files to be injected into the <head> element. This is not what I want because the other 9 CSS files (other than the one that I import) are not actually being used. This results in a larger build file for my component library, and thus a larger download for consumers of the component library.
The /*#__PURE__*/ annotation tells the bundler "don't call this function unless it is used somewhere else." In the case of this Rollup plugin, we don't want styleInject(..) to be called unless the styles are actually imported somewhere.
Here is what I changed in the second code snippet:
Wrap the styleInject(..) function call in an IIFE
Use the /*#__PURE__*/ annotation
Instead of exporting var modules = {"button":".random_hash"};, we need to return mapping from the IIFE. Since we are introducing a third variable to the mix, I set the mapping {"button":".random_hash"}; to a variable called styleMapping instead of modules. Now, I can set the result of the IIFE call to the variable modules. Note that modules is still the variable being exported from the file.
We'll also need an option name to tell this plugin to use the /*#__PURE__*/ annotation and IIFE. Some ideas are pure, noSideEffects, and treeShakable (assuming the value would be a boolean).
The text was updated successfully, but these errors were encountered:
Feature Request
While CSS is technically considered a side effect, I would like a way to explicitly state that my CSS Modules are not side effects.
Background
I am building a library that stores a bunch of CSS Module files. The library will be consumed by my component library. The advantage of separating the CSS from the components is that I can write component libraries using multiple frameworks (e.g.
React
,Angular
, andVue
) that all use the same exact styles. Since I am guaranteeing that my styles in any given file are locally scoped to only one component, I can guarantee that my CSS files are not side effects.Currently, the output from this plugin looks something like the following:
Now, let's assume that I have 10 CSS files that I want to inject using CSS Modules. I essentially get 10
styleInject
function calls and 10 named exports. Once I consume the build file, I'll want to do something like the following in my component file:This works as expected, meaning that the button styles will be injected into the
<head>
element viastyleInject
. The problem is that I have 9 other style files that resulted in 9 otherstyleInject(..)
function calls in the build file (i.e.index.es.js
). Because thesestyleInject
calls are not wrapped in a function with a/*#__PURE__*/
annotation, just one import will cause all 10 CSS files to be injected into the<head>
element. This is not what I want because the other 9 CSS files (other than the one that I import) are not actually being used. This results in a larger build file for my component library, and thus a larger download for consumers of the component library.Tree Shaking/Dead Code Elimination
Bundlers like
Rollup
andWebpack
understand the/*#__PURE__*/
annotation preceding a function call. Webpack does a good job explaining this (see https://webpack.js.org/guides/tree-shaking/#mark-a-function-call-as-side-effect-free).The
/*#__PURE__*/
annotation tells the bundler "don't call this function unless it is used somewhere else." In the case of this Rollup plugin, we don't wantstyleInject(..)
to be called unless the styles are actually imported somewhere.Implementation
For reference, here is the current output:
If a user of the plugin states "I guarantee that my CSS has no side effects," we want to transform the above code into the following:
Here is what I changed in the second code snippet:
/*#__PURE__*/
annotationvar modules = {"button":".random_hash"};
, we need to return mapping from the IIFE. Since we are introducing a third variable to the mix, I set the mapping{"button":".random_hash"};
to a variable calledstyleMapping
instead ofmodules
. Now, I can set the result of the IIFE call to the variablemodules
. Note thatmodules
is still the variable being exported from the file.We'll also need an option name to tell this plugin to use the
/*#__PURE__*/
annotation and IIFE. Some ideas arepure
,noSideEffects
, andtreeShakable
(assuming the value would be a boolean).The text was updated successfully, but these errors were encountered: