├── .babelrc ├── .editorconfig ├── .eslintignore ├── .eslintrc ├── .gitignore ├── README.md ├── index.js ├── package.json ├── src ├── abstractLoader.js ├── browserLoader.js ├── nodeLoader.js └── plugins.js └── test ├── example ├── .gitignore ├── app.css ├── app.js ├── component.css ├── component.js ├── jspm.config.js └── package.json └── nodeLoader.spec.js /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": ["transform-runtime"], 3 | "presets": [ 4 | "es2015", 5 | "stage-0" 6 | ] 7 | } -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig helps developers define and maintain consistent 2 | # coding styles between different editors and IDEs 3 | # editorconfig.org 4 | 5 | root = true 6 | 7 | 8 | [*] 9 | 10 | # Change these settings to your own preference 11 | indent_style = space 12 | indent_size = 2 13 | 14 | # We recommend you to keep these unchanged 15 | end_of_line = lf 16 | charset = utf-8 17 | trim_trailing_whitespace = true 18 | insert_final_newline = true 19 | 20 | [*.md] 21 | trim_trailing_whitespace = false -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | test/example/** -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | "parserOptions": { 4 | "ecmaVersion": 6, 5 | "sourceType": "module" 6 | }, 7 | "rules": { 8 | "comma-dangle": [ 2, "never" ], 9 | "no-cond-assign": [ 2, "always" ], 10 | "no-console": [ 2 ], 11 | "no-constant-condition": [ 2 ], 12 | "no-control-regex": [ 2 ], 13 | "no-debugger": [ 2 ], 14 | "no-dupe-args": [ 2 ], 15 | "no-dupe-keys": [ 2 ], 16 | "no-duplicate-case": [ 2 ], 17 | "no-empty-character-class": [ 2 ], 18 | "no-empty": [ 2 ], 19 | "no-ex-assign": [ 2 ], 20 | "no-extra-boolean-cast": [ 2 ], 21 | "no-extra-parens": [ 2 ], 22 | "no-extra-semi": [ 2 ], 23 | "no-func-assign": [ 2 ], 24 | "no-inner-declarations": [ 2 ], 25 | "no-invalid-regexp": [ 2 ], 26 | "no-irregular-whitespace": [ 2 ], 27 | "no-negated-in-lhs": [ 2 ], 28 | "no-obj-calls": [ 2 ], 29 | "no-regex-spaces": [ 2 ], 30 | "no-sparse-arrays": [ 2 ], 31 | "no-unreachable": [ 2 ], 32 | "use-isnan": [ 2 ], 33 | "valid-jsdoc": [ 0 ], 34 | "valid-typeof": [ 2 ], 35 | "no-unexpected-multiline": [ 2 ], 36 | 37 | "accessor-pairs": [ 2 ], 38 | "block-scoped-var": [ 2 ], 39 | "complexity": [ 2, 10 ], 40 | "consistent-return": [ 2 ], 41 | "curly": [ 2 ], 42 | "default-case": [ 2 ], 43 | "dot-notation": [ 2 ], 44 | "dot-location": [ 2, "property" ], 45 | "eqeqeq": [ 2 ], 46 | "guard-for-in": [ 2 ], 47 | "no-alert": [ 2 ], 48 | "no-caller": [ 2 ], 49 | "no-div-regex": [ 2 ], 50 | "no-else-return": [ 2 ], 51 | "no-eq-null": [ 2 ], 52 | "no-eval": [ 2 ], 53 | "no-extend-native": [ 2 ], 54 | "no-extra-bind": [ 2 ], 55 | "no-fallthrough": [ 2 ], 56 | "no-floating-decimal": [ 2 ], 57 | "no-implicit-coercion": [ 2 ], 58 | "no-implied-eval": [ 2 ], 59 | "no-invalid-this": [ 2 ], 60 | "no-iterator": [ 2 ], 61 | "no-labels": [ 2 ], 62 | "no-lone-blocks": [ 2 ], 63 | "no-loop-func": [ 2 ], 64 | "no-multi-spaces": [ 2 ], 65 | "no-multi-str": [ 2 ], 66 | "no-native-reassign": [ 2 ], 67 | "no-new-func": [ 2 ], 68 | "no-new-wrappers": [ 2 ], 69 | "no-new": [ 2 ], 70 | "no-octal-escape": [ 2 ], 71 | "no-octal": [ 2 ], 72 | // It's pretty common to want to do "opts = opts || defaultValue" 73 | "no-param-reassign": [ 0 ], 74 | "no-process-env": [ 2 ], 75 | "no-proto": [ 2 ], 76 | "no-redeclare": [ 2 ], 77 | "no-return-assign": [ 2 ], 78 | "no-script-url": [ 2 ], 79 | "no-self-compare": [ 2 ], 80 | "no-sequences": [ 2 ], 81 | "no-throw-literal": [ 2 ], 82 | "no-unused-expressions": [ 2 ], 83 | "no-useless-call": [ 2 ], 84 | "no-useless-concat": [ 2 ], 85 | "no-void": [ 2 ], 86 | "no-warning-comments": [ 1 ], 87 | "no-with": [ 2 ], 88 | "radix": [ 2 ], 89 | "vars-on-top": [ 0 ], 90 | "wrap-iife": [ 2 ], 91 | "yoda": [ 2, "never" ], 92 | 93 | "strict": [ 2, "never" ], 94 | 95 | "init-declarations": [ 0 ], 96 | "no-catch-shadow": [ 2 ], 97 | "no-delete-var": [ 2 ], 98 | "no-label-var": [ 2 ], 99 | "no-shadow-restricted-names": [ 2 ], 100 | "no-shadow": [ 2 ], 101 | "no-undef-init": [ 2 ], 102 | "no-undef": [ 2 ], 103 | "no-undefined": [ 2 ], 104 | "no-unused-vars": [ 2 ], 105 | "no-use-before-define": [ 2 ], 106 | 107 | "callback-return": [ 2 ], 108 | "global-require": [ 2 ], 109 | "handle-callback-err": [ 2 ], 110 | "no-mixed-requires": [ 2 ], 111 | "no-new-require": [ 2 ], 112 | "no-path-concat": [ 2 ], 113 | "no-process-exit": [ 2 ], 114 | "no-restricted-modules": [ 2 ], 115 | "no-sync": [ 2 ], 116 | 117 | "array-bracket-spacing": [ 2, "never" ], 118 | "block-spacing": [ 2, "always" ], 119 | "brace-style": [ 120 | 2, 121 | "1tbs", 122 | { "allowSingleLine": false } 123 | ], 124 | "camelcase": [ 125 | 2, 126 | { "properties": "always" } 127 | ], 128 | "comma-spacing": [ 2 ], 129 | "comma-style": [ 2 ], 130 | "computed-property-spacing": [ 2 ], 131 | "consistent-this": [ 2, "that" ], 132 | "eol-last": [ 0 ], 133 | "func-names": [ 0 ], 134 | "func-style": [ 2, "expression" ], 135 | "id-length": [ 136 | 2, 137 | { "exceptions": [ "_", "$" ] } 138 | ], 139 | "id-match": [ 0 ], 140 | "indent": [ 141 | 2, 142 | 2, 143 | { "SwitchCase": 1 } 144 | ], 145 | "jsx-quotes": [ 0 ], 146 | "key-spacing": [ 2 ], 147 | "lines-around-comment": [ 0 ], 148 | "linebreak-style": [ 2, "windows" ], 149 | "max-nested-callbacks": [ 2 ], 150 | "new-cap": [ 2 ], 151 | "new-parens": [ 2 ], 152 | "newline-after-var": [ 0 ], 153 | "no-array-constructor": [ 2 ], 154 | "no-continue": [ 2 ], 155 | "no-inline-comments": [ 2 ], 156 | "no-lonely-if": [ 2 ], 157 | "no-mixed-spaces-and-tabs": [ 2 ], 158 | "no-multiple-empty-lines": [ 2 ], 159 | "no-nested-ternary": [ 2 ], 160 | 161 | "no-new-object": [ 2 ], 162 | "no-restricted-syntax": [ 0 ], 163 | "no-spaced-func": [ 2 ], 164 | "no-ternary": [ 0 ], 165 | "no-trailing-spaces": [ 2 ], 166 | "no-underscore-dangle": [ 0 ], 167 | "no-unneeded-ternary": [ 2 ], 168 | "object-curly-spacing": [ 2, "always" ], 169 | "one-var": [ 2, "never" ], 170 | "operator-assignment": [ 2, "always" ], 171 | "operator-linebreak": [ 2 ], 172 | "padded-blocks": [ 2, "never" ], 173 | "quote-props": [ 2, "consistent" ], 174 | "quotes": [ 2, "single" ], 175 | "require-jsdoc": [ 0 ], 176 | "semi-spacing": [ 2 ], 177 | "semi": [ 2, "always" ], 178 | "sort-vars": [ 0 ], 179 | "keyword-spacing": [ 2 ], 180 | "space-before-blocks": [ 2 ], 181 | "space-before-function-paren": [ 2, "never" ], 182 | "space-in-parens": [ 2 ], 183 | "space-infix-ops": [ 2 ], 184 | "space-unary-ops": [ 2 ], 185 | "spaced-comment": [ 0 ], 186 | "wrap-regex": [ 2 ], 187 | 188 | "arrow-parens": [ 2 ], 189 | "arrow-spacing": [ 2 ], 190 | "constructor-super": [ 2 ], 191 | "generator-star-spacing": [ 2 ], 192 | "no-class-assign": [ 2 ], 193 | "no-const-assign": [ 2 ], 194 | "no-dupe-class-members": [ 2 ], 195 | "no-this-before-super": [ 2 ], 196 | "no-var": [ 2 ], 197 | "object-shorthand": [ 2 ], 198 | "prefer-arrow-callback": [ 2 ], 199 | "prefer-const": [ 2 ], 200 | "prefer-spread": [ 2 ], 201 | "prefer-reflect": [ 2 ], 202 | "prefer-template": [ 2 ], 203 | "require-yield": [ 2 ], 204 | 205 | "max-depth": [ 2, 4 ], 206 | "max-len": [ 2, 120 ], 207 | "max-params": [ 2, 5 ], 208 | "max-statements": [ 2, 35 ], 209 | "no-bitwise": [ 2 ], 210 | "no-plusplus": [ 2 ] 211 | }, 212 | "env": { 213 | "es6": true 214 | } 215 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | tmp -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # JSPM Loader: CSS 2 | 3 | [![Join the chat at https://gitter.im/geelen/jspm-loader-css](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/geelen/jspm-loader-css?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) 4 | 5 | ## Description 6 | 7 | This is a CSS loader for jspm. It uses PostCSS plugins to parse your CSS files. By default, it only applies the CSS Modules plugin suite to your CSS, but it can be extended to suit your needs. 8 | This loader has been built for jspm >0.17. You may experience difficulties, or it may not work at all, if you are using jspm v0.16. 9 | 10 | > That's pretty cool, but what the heck is CSS Modules? 11 | 12 | Here's some reading material: 13 | 14 | - https://github.com/css-modules/css-modules 15 | - http://glenmaddern.com/articles/css-modules 16 | - https://github.com/css-modules/css-modules-loader-core 17 | 18 | Essentially, CSS Modules automatically namespaces all of your classes to guarantee uniqueness. It returns to you an object of key/value pairs (in JavaScript) which you use to apply the generated class names to your elements. 19 | 20 | ## Installation 21 | 22 | To installl, run the following command: 23 | 24 | ``` 25 | jspm install github:MeoMix/jspm-loader-css@master" 26 | ``` 27 | 28 | and in `jspm.config.js` you'll need to add the following: 29 | 30 | ```js 31 | SystemJS.config({ 32 | ... 33 | meta: { 34 | "*.css": { 35 | "loader": "jspm-loader-css", 36 | "cssOptions": {} 37 | } 38 | }, 39 | ... 40 | }); 41 | ``` 42 | 43 | Load the styles by referencing them in your JS: 44 | 45 | ```js 46 | import styles from './foo.css' 47 | elem.innerHTML = `
` 48 | ``` 49 | 50 | 51 | ## Loading additional PostCSS plugins 52 | 53 | It's likely that you will want to load additional, non-default PostCSS plugins for additional processing of your CSS. That is a supported scenario with this plugin, but requires minor adjustments to `jspm.config.js` 54 | 55 | You should re-write your meta configuration such that it looks similar to: 56 | 57 | ``` 58 | SystemJS.config({ 59 | ... 60 | meta: { 61 | "*.css": { 62 | "loader": "css.js" 63 | } 64 | }, 65 | ... 66 | }); 67 | ``` 68 | 69 | where `css.js` is a file you create yourself. You can place `css.js` in a directory if you'd like, but you'll need to provide the full path to it inside `jspm.config.js`. 70 | 71 | You'll need to import `jspm-loader-css` from within `css.js` like so: 72 | 73 | ``` 74 | import Plugins from 'jspm-loader-css/src/plugins.js' 75 | import Loader from 'jspm-loader-css/src/loader.js' 76 | 77 | const plugins = [ 78 | Plugins.values, 79 | Plugins.localByDefault, 80 | Plugins.extractImports, 81 | Plugins.scope 82 | ]; 83 | 84 | const { fetch, bundle } = new Loader(plugins); 85 | export { fetch, bundle }; 86 | ``` 87 | 88 | The above code will perform identically to the default behavior of `jspm-loader-css`. You are then free to add additional plugins to the mixture, such as: 89 | 90 | ``` 91 | import Plugins from 'jspm-loader-css/src/plugins.js' 92 | import Loader from 'jspm-loader-css/src/loader.js' 93 | import autoprefixer from 'autoprefixer'; 94 | 95 | const plugins = [ 96 | Plugins.values, 97 | Plugins.localByDefault, 98 | Plugins.extractImports, 99 | Plugins.scope, 100 | autoprefixer() 101 | ]; 102 | 103 | const { fetch, bundle } = new Loader(plugins); 104 | export { fetch, bundle }; 105 | ``` 106 | 107 | Keep in mind that `jspm-loader-css` runs both in the browser (during development) and in node (during production builds). Many PostCSS plugins are written with only node in mind. Your mileage may vary on being able to successfully use PostCSS plugins without modification. 108 | 109 | For a working example of `jspm-loader-css` in `css.js`, see here: https://github.com/MeoMix/StreamusWebsite/blob/development/jspm/css.js 110 | 111 | ## Passing cssOptions to jspm-loader-css 112 | To specify options to jspm-loader-css, provide a `cssOptions` configuration: 113 | ```js 114 | SystemJS.config({ 115 | meta: { 116 | "*.css": { 117 | "loader": "jspm-loader-css", 118 | "cssOptions": { 119 | "bundledStyleTagId": "id-of-style-element" 120 | } 121 | } 122 | }, 123 | }); 124 | ``` 125 | 126 | The options supported include: 127 | - `bundledStyleTagId`: a string that will be the `id` of the `