UNPKG

11 kBMarkdownView Raw
1<p align="center">
2 <a href="https://stylus-lang.com/"><img src="https://stylus-lang.com/img/stylus-logo.svg" alt="Stylus" title="Stylus" height="80" valign="middle"></a>
3 <a href="https://webpack.js.org/"><img src="https://webpack.js.org/assets/icon-square-big.svg" alt="Webpack" title="Webpack" height="120" valign="middle"></a>
4</p>
5<p align="center">
6 <a href="https://www.npmjs.com/package/stylus-native-loader"><img src="https://img.shields.io/npm/v/stylus-native-loader" alt="Version"></a>
7 <a href="https://nodejs.org"><img src="https://img.shields.io/node/v/stylus-native-loader" alt="Node.js Version"></a>
8 <a href="https://packagephobia.com/result?p=stylus-native-loader"><img src="https://packagephobia.com/badge?p=stylus-native-loader" alt="Size"></a>
9 <a href="https://www.npmjs.com/package/stylus-native-loader"><img src="https://img.shields.io/npm/dm/stylus-native-loader" alt="Downloads"></a>
10 <a href="https://github.com/slightlyfaulty/stylus-native-loader/issues?q="><img src="https://img.shields.io/maintenance/yes/2020" alt="Maintained"></a>
11</p>
12
13# stylus-native-loader
14
15A super fast [Stylus](https://stylus-lang.com/) loader for [Webpack](https://webpack.js.org/) that leverages the built-in power of Stylus. Configured for modern development.
16
17Unlike other Stylus loaders available that make use of Webpack's resolver for import path resolution (which comes with several limitations and increased overhead), stylus-native-loader relies on the powerful "native" [@import/require](https://stylus-lang.com/docs/import.html) capabilities of Stylus.
18
19The result is a highly configurable, lean Stylus loader with near-baseline build speeds and unhindered @import/require functionality (with Webpack alias support) 🥳
20
21> **Update:** The Webpack team has taken over maintenance of stylus-loader as the official loader for Stylus! A lot of stylus-native-loader has already been merged into the new stylus-loader. Once it's ready for prime time, this loader will likely be deprecated in favor of having one single maintained Stylus loader for the community.
22
23## Why use this instead of [stylus-loader](https://github.com/shama/stylus-loader)?
24
25- It's [fast](#benchmarks).
26- It's compatible with Webpack 4 and 5.
27- It's actively maintained. Stylus-loader has many critical [issues](https://github.com/shama/stylus-loader/issues), with its last commit on Feb 26, 2018.
28- It doesn't do any weird/buggy magic to get Stylus working in Webpack. If it works in Stylus, it works in stylus-native-loader.
29- It supports webpack [aliases](https://webpack.js.org/configuration/resolve/#resolvealias) and has automatic tilde path resolution (e.g. `~nib` = `/path/to/node_modules/nib`).
30- It generates better source maps.
31- It disables all built-in vendor prefixing (by default). Vendor prefixing should be done with [PostCSS Autoprefixer](https://github.com/postcss/autoprefixer#webpack) or similar.
32- It uses raw defines (by default), allowing JS object literals to be passed via options and converted to Stylus hashes.
33- Stylus is awesome ❤️ and it deserves an awesome Webpack loader.
34
35## Benchmarks
36
37*Build times for the [vuejs.org Stylus source code](https://github.com/vuejs/vuejs.org/tree/master/themes/vue/source/css), sorted from fastest to slowest.*
38
39| | Min | Max | Average | Diff % |
40| ------------------------------------------------------------ | -------- | -------- | ------------ | ------- |
41| **[stylus](https://stylus-lang.com/docs/js.html)** (no Webpack) | 72.67ms | 104.75ms | **80.47ms** | |
42| **stylus-native-loader** | 79.61ms | 104.26ms | **86.41ms** | +7.38% |
43| **[stylus-loader](https://github.com/shama/stylus-loader)** | 85.62ms | 128.05ms | **104.39ms** | +29.73% |
44| **[stylus-relative-loader](https://github.com/walmartlabs/stylus-relative-loader)** | 117.32ms | 198.78ms | **143.10ms** | +77.83% |
45
46## Getting started
47
48To begin, install `stylus-native-loader` and `stylus`:
49
50```sh
51yarn add -D stylus-native-loader stylus
52# or
53npm i -D stylus-native-loader stylus
54```
55
56Then add the loader to your **webpack.config.js**. For example, a minimal configuration might look like this:
57
58```js
59module.exports = {
60 module: {
61 rules: [
62 {
63 test: /\.styl$/,
64 use: ['style-loader', 'css-loader', 'stylus-native-loader'],
65 },
66 ],
67 },
68}
69```
70
71## Configuration by example
72
73Below is an example **webpack.config.js** using all `stylus-native-loader` options. None are required.
74
75```js
76const path = require('path')
77const MiniCssExtractPlugin = require('mini-css-extract-plugin')
78
79module.exports = {
80 // Any "original source" option excluding "eval" enables source map generation
81 // @see https://webpack.js.org/configuration/devtool/
82 devtool: 'source-map',
83
84 resolve: {
85 // All aliases are used for Stylus @import and @require path resolution
86 // See `alias` loader option below for adding stylus-specific aliases
87 alias: {
88 // A standard alias that matches the first segment of an import path
89 // Note: Tilde (~) is not required, but is convention for stylesheet aliases
90 // Maps @import '~styl/*' to '/path/to/src/styl/*'
91 '~styl': path.join(__dirname, 'src/styl'),
92
93 // An "exact match" alias (i.e. will only match @import 'mixins')
94 // @see https://webpack.js.org/configuration/resolve/#resolvealias
95 // Maps @import 'mixins' to '/path/to/src/styl/mixins'
96 'mixins$': path.join(__dirname, 'src/styl/mixins'),
97 },
98 },
99
100 module: {
101 rules: [
102 {
103 test: /\.styl$/,
104 use: [
105 {
106 // Extracts CSS to a separate file
107 loader: MiniCssExtractPlugin.loader
108 },
109 {
110 // Translates CSS into CommonJS
111 loader: 'css-loader',
112 options: {
113 // Required for Stylus source map output
114 sourceMap: true,
115 }
116 },
117 {
118 // Compiles Stylus to CSS
119 loader: 'stylus-native-loader',
120 options: {
121 /**
122 * Specify Stylus plugins to use. Plugins may be passed as
123 * strings instead of importing them in your Webpack config.
124 *
125 * @type {string|Function|(string|Function)[]}
126 * @default []
127 */
128 use: 'nib',
129
130 /**
131 * Add path(s) to the import lookup paths.
132 *
133 * @type {string|string[]}
134 * @default []
135 */
136 include: path.join(__dirname, 'src/styl/config'),
137
138 /**
139 * Import the specified Stylus files/paths.
140 *
141 * @type {string|string[]}
142 * @default []
143 */
144 import: [
145 'nib',
146 path.join(__dirname, 'src/styl/mixins'),
147 ],
148
149 /**
150 * Define Stylus variables or functions.
151 *
152 * @type {Object}
153 * @default {}
154 */
155 define: {
156 '$development': process.env.NODE_ENV === 'development'
157 },
158
159 /**
160 * The 3rd parameter of the Stylus `define()` method.
161 * Controls whether object literals are converted into
162 * hashes (true) or lists/expressions (false).
163 *
164 * @type {boolean}
165 * @default true
166 */
167 defineRaw: false,
168
169 /**
170 * Include regular CSS on @import.
171 *
172 * @type {boolean}
173 * @default false
174 */
175 includeCSS: true,
176
177 /**
178 * Resolve relative url()'s inside imported files.
179 *
180 * @see https://stylus-lang.com/docs/js.html#stylusresolveroptions
181 *
182 * @type {boolean|Object}
183 * @default false
184 */
185 resolveUrl: true,
186
187 /**
188 * Aliases used for @import and @require path resolution.
189 * If set, webpack `resolve.alias` config is ignored.
190 *
191 * @type {Object|false}
192 * @default `resolve.alias`
193 */
194 alias: {
195 'mixins': path.join(__dirname, 'src/styl/mixins'),
196 },
197
198 /**
199 * Non-alias imports beginning with tilde (~) are resolved
200 * using `require.resolve()` to find the module's base path.
201 *
202 * @example @import '~nib' resolves to '/path/to/node_modules/nib'
203 *
204 * @type {boolean}
205 * @default true
206 */
207 resolveTilde: true,
208
209 /**
210 * Toggle built-in Stylus/Nib vendor prefixing.
211 * Disabled by default (prefer PostCSS Autoprefixer).
212 *
213 * @type {boolean}
214 * @default false
215 */
216 vendors: true,
217
218 /**
219 * Toggle/configure source map generation.
220 * Set according to `devtool` config value by default.
221 *
222 * @see https://stylus-lang.com/docs/sourcemaps.html
223 *
224 * @type {boolean|Object}
225 * @default `devtool`|false
226 */
227 sourceMap: {
228 // Toggle loading of source file contents into source map
229 content: true,
230 // All other Stylus "sourcemap" options can be set if needed
231 },
232
233 /**
234 * Callback that triggers right before Stylus compiles,
235 * allowing access to the Stylus JS API and loader context.
236 *
237 * @see https://stylus-lang.com/docs/js.html
238 *
239 * @type {Function}
240 * @default undefined
241 *
242 * @param {Renderer} renderer The stylus renderer instance
243 * @param {Object} context The loader context object
244 * @param {Object} options The unified stylus options object
245 */
246 beforeCompile(renderer, context, options) {
247 renderer.define('expression', {foo: 'bar', bar: 'baz'})
248 renderer.define('hash', {foo: 'bar', bar: 'baz'}, true)
249 },
250
251 /**
252 * Stylus has several other options/configurations that can be
253 * set here and will be passed directly to the Stylus compiler.
254 *
255 * @see https://stylus-lang.com/docs/js.html
256 * @see https://stylus-lang.com/docs/executable.html
257 */
258 },
259 },
260 ],
261 },
262 ],
263 },
264}
265```
266
267## License
268
269[MIT](./LICENSE)