jsxstyle/webpack-plugin
is a webpack plugin that extracts static style props from jsxstyle components into a separate CSS file.
Don’t know what jsxstyle is? Check out the jsxstyle README for more information.
-
Import
jsxstyle/webpack-plugin
and add it to theplugins
section of your webpack config. -
Add a new rule object with
jsxstyle/webpack-plugin
’s companion loader to your webpack config, below any other JS loaders.jsxstyle/webpack-plugin
relies on untranspiled JSX to be present in order to extract styles. Since webpack loaders run from right to left and bottom to top,jsxstyle/webpack-plugin
should be placed at the end of your list of JS loaders. -
Ensure your webpack config contains a loader that handles
.css
files.
When you’re done, the relevant parts of your webpack config should look like this:
const { JsxstyleWebpackPlugin } = require('@jsxstyle/webpack-plugin');
module.exports = {
// ...
plugins: [new JsxstyleWebpackPlugin()],
// ...
module: {
rules: [
// ...
{
test: /\.js$/,
use: [
// loaders that transpile JSX should go before jsxstyle/webpack-plugin’s companion loader
{
loader: 'your-cool-js-loader',
},
// companion loader goes at the end
JsxstyleWebpackPlugin.loader,
],
},
{
test: /\.css$/,
use: 'your-cool-css-loader',
},
// ...
],
},
};
Plugin options are passed in object format to JsxstyleWebpackPlugin
.
An array of absolute paths to modules that should be treated as static. All modules in this list will be evaluated. Exports from these modules that are referenced in jsxstyle components will be inlined.
For example, with the following plugin config, any prop on a jsxstyle component that references a value from ./LayoutConstants.js
will be extracted:
new JsxstyleWebpackPlugin({
staticModules: [require.resolve('./LayoutConstants')],
}),
jsxstyle/webpack-plugin
uses @babel/parser
to parse javascript into an AST. By default, the webpack plugin is preconfigured with most of @babel/parser
’s plugins enabled, but if you need to enable additional plugins, you can specify an array of plugins with the parserPlugins
option.
You can see a list of all available plugins in the @babel/parser
documentation.
Out of the box, the jsxstyle webpack plugin will use a non-deterministic class naming scheme. Because webpack’s module iteration order is not guaranteed, class names will differ slightly between builds of the same code. If you need class names to remain the same each time the same code is bundled, set the classNameFormat
option to hash
in your loader config. Class names will be generated using a content-based hash.
Yes! Flow parsing is automatically enabled for any non-Typescript files.
Yes! Take a look at the TypeScript example and issue #82 for some context. You’ll need to make a few configuration changes:
- Set
jsx
topreserve
in thecompilerOptions
section of yourtsconfig.json
file. - Ensure
jsxstyle/webpack-plugin
’s companion loader runs afterts-loader
. Webpack loaders run from bottom to top, sojsxstyle/webpack-plugin
needs to be placed beforets-loader
in your webpack config. - Add a loader that transpiles JSX, since
ts-loader
is now set to preserve JSX.
-
Make sure the loader object
test
regex matches JS files that use jsxstyle. -
jsxstyle/webpack-plugin
relies on JSX still being around, so make sure the companion loader runs beforebabel-loader
does its thing. -
jsxstyle/webpack-plugin
only supports destructuredrequire
/import
syntax:// Cool! import { Block } from '@jsxstyle/react'; <Block />; // Neat! const { Block } = require('@jsxstyle/react'); <Block />; // Nope :( const Block = require('@jsxstyle/react').Block; <Block />;
Simply put, static style props are props whose values can be evaluated at build time. By default, this consists of any literal type (string
, number
, null
) as well as any variables provided to the evaluation context. The evaluation context is derived from the prop’s current scope.
For example, the fontSize
prop in the following component will be marked as evaluatable and will be extracted as 42
:
import { Block } from '@jsxstyle/react';
const bestNumber = 42;
<Block fontSize={bestNumber}>hello</Block>;
Any modules marked as static with the staticModules
plugin config option will also be added to the evaluation context.
If the value of a style prop is a ternary and both sides can be evaluated, the prop will be extracted and the ternary condition will be moved to the className
.
If the value of a prop is a simple logical expression with the &&
operator, it will be converted to a ternary with a null alternate.
See the jsxstyle FAQs.
It sure does, but using it in development will only cause confusion, since what you will see in the developer tools is the transformed JS. jsxstyle/webpack-plugin
is a production optimisation.
CSS class names are reused across components but they are not de-duplicated. Any CSS minifier that combines identical class names will handle deduplication.
Got an idea for the jsxstyle webpack plugin? Did you encounter a bug? Open an issue and let’s talk it through. PRs welcome too!