{"id":18347691,"url":"https://github.com/ghivert/modular-styles","last_synced_at":"2025-04-06T09:31:23.929Z","repository":{"id":47774668,"uuid":"202201050","full_name":"ghivert/modular-styles","owner":"ghivert","description":"Extract CSS into CSS Modules for any language!","archived":false,"fork":false,"pushed_at":"2021-08-16T11:31:58.000Z","size":385,"stargazers_count":26,"open_issues_count":1,"forks_count":3,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-03-21T21:11:35.376Z","etag":null,"topics":["build-tool","clojurescript","css","css-modules","frontend","spa"],"latest_commit_sha":null,"homepage":"","language":"Clojure","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ghivert.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-08-13T18:21:00.000Z","updated_at":"2023-07-04T08:32:37.000Z","dependencies_parsed_at":"2022-09-23T19:41:36.914Z","dependency_job_id":null,"html_url":"https://github.com/ghivert/modular-styles","commit_stats":null,"previous_names":[],"tags_count":13,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ghivert%2Fmodular-styles","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ghivert%2Fmodular-styles/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ghivert%2Fmodular-styles/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ghivert%2Fmodular-styles/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ghivert","download_url":"https://codeload.github.com/ghivert/modular-styles/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247463744,"owners_count":20942935,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["build-tool","clojurescript","css","css-modules","frontend","spa"],"created_at":"2024-11-05T21:14:40.812Z","updated_at":"2025-04-06T09:31:23.544Z","avatar_url":"https://github.com/ghivert.png","language":"Clojure","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Modular Styles\n\nImplements CSS Modules for any SPA framework, especially in other languages than\nJavaScript!\n\nRight now, the simplest solution to use CSS Modules consists of instantiating\nWebpack, and running everything through it. Doing things like\n`import styles from 'stylesheet.module.css'`. But what if you’re not running\nWebpack? What if you’re using another language that is not supported by Webpack? Or a\nlanguage which don’t have access to `require`? Well, unless your build tool\nincludes CSS Modules itself, you’re stuck with classic CSS. Or maybe with SASS.\nBut we can do better now! PostCSS is here, it’s time to do better things!\n\nThe idea behind Modular Styles is to give\naccess to PostCSS and all of the future features of CSS, right now, for all\nlanguages and frameworks.\n\n# How does it work?\n\nModular Styles uses the power of PostCSS and Gulp to provide an easy way to\ncompile your CSS into usable CSS for any browser.\n\n- First, all CSS is gathered though Gulp.\n- Everything is processed by PostCSS to activate the future features of CSS.\n- Optionally, the files processed can be dumped somewhere in your project.\n- In parallel, all files get an interface in JSON, with the corresponding CSS\n  Modules names from the stylesheets, converted into your favorite language\n  interface.\n- All files get concatenated into one.\n- This file is finally processed by `cssnano` in order to remove code duplication.\n- Finally, just include the resulting file into your HTML template, and enjoy\n  using all the features of CSSNext!\n\nAt the end, you end up with two parts: a `styles.css` stylesheet, containing all\nthe converted CSS, and a bunch of interfaces into multiple files, corresponding\nto each stylesheet, such as `navbar.cljs`, `main.cljs`, etc.\n\n# What does Modular Styles support?\n\nFor now, the package has been written for ClojureScript, in use with shadow-cljs.\nIt fully supports ClojureScript and CSS Modules. It is thought to also handle\nall PostCSS plugins according to the project dependencies.\n\n# How does it work?\n\nModular Styles exists in two flavors: the CLI, and the API, in order to\nintegrate easily with all flows, whether they are NPM scripts or more advanced\nprocesses.\n\n## Installation\n\n```bash\n# For NPM users\nnpm install --save-dev modular-styles\n# For Yarn users\nyarn add --dev modular-styles\n```\n\n## Additional Set-up\n\nTo start using modular styles, you need to prepare several things.\n\n### Install PostCSS plugins and configure it:\n\n```bash\n# For NPM users\nnpm install --save-dev \u003clist of PostCSS plugins\u003e\n# For Yarn users\nyarn add --dev \u003clist of PostCSS plugins\u003e\n```\n\nExample:\n\n```bash\nnpm install --save-dev postcss-import postcss-preset-env\n# For Yarn users\nyarn add --dev postcss-import postcss-preset-env\n```\n\nFor configuration look at the [dedicated section](#postcss-configurations).\n\n### Prepare NPM scripts\n\n```json\n{\n  \"scripts\": {\n    \"watch-styles\": \"\u003cyour styles watching script\u003e\",\n    \"build-styles\": \"\u003cyour styles building script\u003e\"\n  }\n}\n```\n\nTo write scripts either use [CLI](#cli) ([example](https://github.com/ghivert/re-frame-template/blob/master/package.json)) or [JavaScript](#api) ([example](https://github.com/guillaumeboudon/wishlist)).\n\n## Usage\n\nBefore the development, open a dedicated terminal window and run:\n\n```bash\nnpm run watch-styles\n# For Yarn users\nyarn watch-styles\n```\n\nThis command will bring to foreground watching process rebuilding your CSS on every file save.\n\n## CLI\n\n```bash\nmodular-styles [command] \u003coptions\u003e\n```\n\n`[command]` should either be `compile` or `watch`. The `compile` command runs the program\nonce, compiles everything and shutdown. When using `watch`, the program\nconstantly watches for every source file change and rebuilds everything each time\nto ensure you’re always up to date.\n\nSome options are required, some are not. Many configuration options are available to suit your needs.\n\n- `--files \u003cfilesPath\u003e` should point to your CSS files. You can also just\n  indicate your `src` path if you don’t have a specific stylesheets folder.\n- `--dest \u003cdestPath\u003e` should point to where you want to put your interfaces\n  once generated.\n- `--source \u003csourcePath\u003e` should point to the correct source path of your\n  interfaces. In ClojureScript, every interface gets compiled with a\n  `(ns package.name.path)` interface. The sourcePath allows to find the base path.\n  Some smarter things could be done for those languages.\n- `--extension \u003cextension\u003e` should be your stylesheets extension. Defaults to css.\n- `--tempCSS \u003ctempCSS\u003e` should point to the path for stylesheets without\n  minification dumping.\n- `--bundleName \u003cbundleName\u003e` is the name for the resulting CSS bundle. Defaults to `styles.css`.\n- `--bundlePath \u003cbundleCSSPath\u003e` is the path for the resulting CSS bundle. Defaults to `public`.\n- `--language \u003clanguage\u003e` is the language in which you want your CSS modules to be converted. Defaults to `cljs`. Supports `elm`, `cljs` and `purs`.\n\nYou probably will end up with something like:\n\n```bash\nmodular-styles watch --source src --dest src/project_name/styles --files src/styles\n```\n\nThis means all files into `src/styles` will be converted into one\n`public/styles.css` file.\n\n# API\n\n```javascript\nconst modularStyles = require('modular-styles')\n\nconst options = {\n  sourcePath: 'src',\n  filesPath: 'src/styles',\n  destPath: 'src/project_name/styles',\n  extension: 'css',\n  bundleName: 'styles.css',\n  bundleCSSPath: 'public',\n  tempCSS: 'public/css',\n  language: 'cljs',\n}\n\n// Use once.\nmodularStyles.compile(options)\n\n// Or watch all files.\nmodularStyles.watch(options)\n```\n\nThe options are the same as below.\n\n# PostCSS configurations\n\nYou can use any plugin you want for PostCSS. Just add them to your `package.json`,\ncreate a `.postcssrc.json`, a `.postcssrc.js` or a `postcss.config.js`, and\nadd your plugins and options directly into this file.\n\nLike so:\n\n```javascript\n// .postcss.config.js\nmodule.exports = {\n  plugins: {\n    'postcss-import': {},\n    'postcss-preset-env': {\n      stage: 1,\n    },\n  },\n}\n```\n\nThis way, all the plugins and options are transferred to PostCSS.\n\n# How does the class name extraction work?\n\nAfter the compilation of your CSS, PostCSS allows you to do what you want with the\nJSON interfaces it provides. By default, it extracts all the information and\ndumps them into the correct ClojureScript file. It is really easy to write\nanother function to convert the JSON into another language.\n\n# An example?\n\nFor Elm, unfortunately, we didn’t have examples yet. But for ClojureScript, take a look at the [re-frame-template example](https://github.com/ghivert/re-frame-template)!\n\nBut to sum up, let’s take an imaginary file.css. (Be careful, in this example, the\n`\u0026` is the nesting rules from PostCSS which in stage 1 in PostCSS Preset Env. You\nshould have a `.postcss.config.js` at the root of your project with\n`module.exports = { plugins: { 'postcss-preset-env: { stage: 1 }' } }` inside and\nhave `postcss-preset-env` in your dependencies.)\n\n```css\n/* file.css */\n.test {\n  color: red;\n\n  \u0026:hover {\n    color: blue;\n  }\n}\n```\n\nWhen compiled by `modular-styles`, a ClojureScript file (like `src/re_frame_template/styles/file.cljs`) will be emitted.\n\n```clojure\n(ns re-frame-template.styles.file)\n\n(def test \"__test_xed87\")\n```\n\nAnd a final file will be generated (`public/styles.css`).\n\n```css\n.__test_xed87 {\n  color: red;\n}\n.__test_xed87:hover {\n  color: blue;\n}\n```\n\nYou can then just import the `styles.css` stylesheet in your code and use the interfaces in your ClojureScript code:\n\n```clojure\n(ns example\n  (:require [re-frame-template.styles.file :as styles]))\n\n(defn component []\n  [:div {:class styles/test} \"The class is correctly linked!\"])\n```\n\nYou’re done and can profit of PostCSS and CSS Modules!\n\n# Contributing?\n\nAll contributions are welcome! Please submit a PR or open an issue!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fghivert%2Fmodular-styles","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fghivert%2Fmodular-styles","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fghivert%2Fmodular-styles/lists"}