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 |
|
15 | A 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 |
|
17 | Unlike 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 |
|
19 | The 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 |
|
48 | To begin, install `stylus-native-loader` and `stylus`:
|
49 |
|
50 | ```sh
|
51 | yarn add -D stylus-native-loader stylus
|
52 | # or
|
53 | npm i -D stylus-native-loader stylus
|
54 | ```
|
55 |
|
56 | Then add the loader to your **webpack.config.js**. For example, a minimal configuration might look like this:
|
57 |
|
58 | ```js
|
59 | module.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 |
|
73 | Below is an example **webpack.config.js** using all `stylus-native-loader` options. None are required.
|
74 |
|
75 | ```js
|
76 | const path = require('path')
|
77 | const MiniCssExtractPlugin = require('mini-css-extract-plugin')
|
78 |
|
79 | module.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)
|