一個(gè) webpack 的 Stylus loader。將 Stylus 文件編譯為 CSS。
首先,你需要安裝 stylus 和 stylus-loader:
$ npm install stylus stylus-loader --save-dev
然后將該 loader 添加到 webpack 配置中。例如:
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.styl$/,
loader: "stylus-loader", // 將 Stylus 文件編譯為 CSS
},
],
},
};
接著按照你習(xí)慣的方式運(yùn)行 webpack。
Name | Type | Default | Description |
---|---|---|---|
stylusOptions
|
{Object|Function}
|
{}
|
Stylus 的可選項(xiàng)。 |
sourceMap
|
{Boolean}
|
compiler.devtool
|
啟用/禁用生成 SourceMap。 |
webpackImporter
|
{Boolean}
|
true
|
啟用/禁用默認(rèn)的 webpack importer。 |
additionalData
|
{String|Function}
|
undefined
|
在入口文件起始或末尾添加 Stylus 代碼。 |
implementation
|
{String|Function}
|
stylus
|
配置 Stylus 使用的實(shí)現(xiàn)庫。 |
類型:?Object|Function
? 默認(rèn)值:{}
通過 stylusOptions 屬性,你可以給 stylus-loader 配置 loader options 中任意特定的選項(xiàng)值。 所有可用選項(xiàng)可以查看 Stylus 文檔。 這些配置項(xiàng)需要將破折號(hào)(dash-case)轉(zhuǎn)換為駝峰值(camelCase)后進(jìn)行設(shè)置。
使用對(duì)象(Object)的形式傳遞 options 給 Stylus。
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.styl$/,
use: [
{
loader: "style-loader",
},
{
loader: "css-loader",
},
{
loader: "stylus-loader",
options: {
stylusOptions: {
/**
* 指定要使用的 Stylus 插件。將插件作為
* 字符串進(jìn)行傳遞,而不是從 Webpack 配置中導(dǎo)入。
*
* @type {(string|Function)[]}
* @default []
*/
use: ["nib"],
/**
* 指定 path 的查找路徑。
*
* @type {string[]}
* @default []
*/
include: [path.join(__dirname, "src/styl/config")],
/**
* 導(dǎo)入指定的 Stylus 文件或者路徑
*
* @type {string[]}
* @default []
*/
import: ["nib", path.join(__dirname, "src/styl/mixins")],
/**
* 定義 Stylus 變量或者函數(shù)。
*
* @type {Array|Object}
* @default {}
*/
// 定義數(shù)組語法的推薦格式:[key, value, raw]
define: [
["$development", process.env.NODE_ENV === "development"],
["rawVar", 42, true],
],
// Object 語法已經(jīng)棄用(不可指定 "raw' 選項(xiàng))
// define: {
// $development: process.env.NODE_ENV === 'development',
// rawVar: 42,
// },
/**
* 是否包含通過 @import 導(dǎo)入的常規(guī) CSS。
*
* @type {boolean}
* @default false
*/
includeCSS: false,
/**
* 解析導(dǎo)入文件中的相對(duì) url()。
*
* @see https://stylus-lang.com/docs/js.html#stylusresolveroptions
*
* @type {boolean|Object}
* @default { nocheck: true }
*/
resolveURL: true,
// resolveURL: { nocheck: true },
/**
* 生成 CSS 后 注入注釋并指定其所在 Stylus 文件行。
*
* @see https://stylus-lang.com/docs/executable.html
*
* @type {boolean}
* @default false
*/
lineNumbers: true,
/**
* 將 @import 和 @charset 移至文件頂部。
*
* @see https://stylus-lang.com/docs/executable.html
*
* @type {boolean}
* @default false
*/
hoistAtrules: true,
/**
* 壓縮輸出的 CSS。
* 生產(chǎn)環(huán)境默認(rèn)值為 `true`
*
* @see https://stylus-lang.com/docs/executable.html
*
* @type {boolean}
* @default false
*/
compress: true,
},
},
},
],
},
],
},
};
允許根據(jù) loader 的 context 來設(shè)置 options,再傳遞給 Stylus。
module.exports = {
module: {
rules: [
{
test: /\.styl/,
use: [
"style-loader",
"css-loader",
{
loader: "stylus-loader",
options: {
stylusOptions: (loaderContext) => {
// 更多可用的屬性參見 https://webpack.js.org/api/loaders/
const { resourcePath, rootContext } = loaderContext;
const relativePath = path.relative(rootContext, resourcePath);
if (relativePath === "styles/foo.styl") {
return {
paths: ["absolute/path/c", "absolute/path/d"],
};
}
return {
paths: ["absolute/path/a", "absolute/path/b"],
};
},
},
},
],
},
],
},
};
類型:?Boolean
?
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.styl$/i,
use: [
"style-loader",
{
loader: "css-loader",
options: {
sourceMap: true,
},
},
{
loader: "stylus-loader",
options: {
sourceMap: true,
},
},
],
},
],
},
};
類型:?Boolean
? 默認(rèn)值:true
啟用/禁用 webpack 默認(rèn)的 importer。
在某些情況下,這樣做可以提高性能。 但是請(qǐng)慎用,因?yàn)榭赡軙?huì)使得 aliases 和以 ~ 開頭的 @import 規(guī)則失效。
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.styl/i,
use: [
"style-loader",
"css-loader",
{
loader: "stylus-loader",
options: {
webpackImporter: false,
},
},
],
},
],
},
};
類型:?String|Function
? 默認(rèn)值:undefined
在實(shí)際入口文件的起始位置添加 Stylus 代碼。 這種情況下,stylus-loader 只會(huì)追加并不會(huì)覆蓋文件內(nèi)容。
當(dāng)你的 Stylus 變量依賴環(huán)境變量時(shí)這個(gè)屬性將非常有用:
? 由于你注入了代碼,因此它將破壞入口文件的源映射關(guān)系。通常有比這更簡單的解決方案,例如多個(gè) Stylus 入口文件。
module.exports = {
module: {
rules: [
{
test: /\.styl/,
use: [
"style-loader",
"css-loader",
{
loader: "stylus-loader",
options: {
additionalData: `@env: ${process.env.NODE_ENV};`,
},
},
],
},
],
},
};
module.exports = {
module: {
rules: [
{
test: /\.styl/,
use: [
"style-loader",
"css-loader",
{
loader: "stylus-loader",
options: {
additionalData: (content, loaderContext) => {
// 更多可用的屬性參見 https://webpack.js.org/api/loaders/
const { resourcePath, rootContext } = loaderContext;
const relativePath = path.relative(rootContext, resourcePath);
if (relativePath === "styles/foo.styl") {
return "value = 100px" + content;
}
return "value 200px" + content;
},
},
},
],
},
],
},
};
module.exports = {
module: {
rules: [
{
test: /\.styl/,
use: [
"style-loader",
"css-loader",
{
loader: "stylus-loader",
options: {
additionalData: async (content, loaderContext) => {
// 更多可用的屬性參見 https://webpack.js.org/api/loaders/
const { resourcePath, rootContext } = loaderContext;
const relativePath = path.relative(rootContext, resourcePath);
if (relativePath === "styles/foo.styl") {
return "value = 100px" + content;
}
return "value 200px" + content;
},
},
},
],
},
],
},
};
類型:?Function | String
?
特殊的 implementation 選項(xiàng)決定使用 Stylus 的哪個(gè)實(shí)現(xiàn)。將會(huì)覆蓋本地安裝的 stylus 的 peerDependency 版本。
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.styl/i,
use: [
"style-loader",
"css-loader",
{
loader: "stylus-loader",
options: {
implementation: require("stylus"),
},
},
],
},
],
},
};
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.styl/i,
use: [
"style-loader",
"css-loader",
{
loader: "stylus-loader",
options: {
implementation: require.resolve("stylus"),
},
},
],
},
],
},
};
將 ?stylus-loader
?、?css-loader
? 和 ?style-loader
? 串聯(lián)起來使用可立即將所有樣式更新到 DOM。
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.styl$/,
use: [
{
loader: "style-loader", // 從 JS 中創(chuàng)建樣式節(jié)點(diǎn)
},
{
loader: "css-loader", // 將 CSS 轉(zhuǎn)為 CommonJS
},
{
loader: "stylus-loader", // 將 Stylus 編譯為 CSS
},
],
},
],
},
};
為了生成 CSS 的 source map, 你需要在 loader 的可選項(xiàng)中設(shè)置 sourceMap 屬性。如果沒設(shè)置的話 loader 將會(huì)繼承你 webpack 中為生成 source map 設(shè)置的屬性值 devtool。
webpack.config.js
module.exports = {
devtool: "source-map", // 任何類似于 "source-map" 的 devtool 值都可以
module: {
rules: [
{
test: /\.styl$/,
use: [
"style-loader",
{
loader: "css-loader",
options: {
sourceMap: true,
},
},
{
loader: "stylus-loader",
options: {
sourceMap: true,
},
},
],
},
],
},
};
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.styl$/,
use: [
{
loader: "style-loader", // 從 JS 中創(chuàng)建樣式節(jié)點(diǎn)
},
{
loader: "css-loader", // 將 CSS 轉(zhuǎn)為 CommonJS
},
{
loader: "stylus-loader", // 將 Stylus 編譯為 CSS
options: {
stylusOptions: {
use: [require("nib")()],
import: ["nib"],
},
},
},
],
},
],
},
};
Stylus 在 json 函數(shù)中無效。 因此 webpack 解析器不適用于 .json 文件。 可使用 stylus resolver。
index.styl
// 假設(shè)文件位置在這里 `node_modules/vars/vars.json`
json('vars.json')
@media queries-small
body
display nope
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.styl$/,
use: [
"style-loader",
"css-loader",
{
loader: "stylus-loader",
options: {
stylusOptions: {
// 指定文件查找路徑。
paths: ["node_modules/vars"],
},
},
},
],
},
],
},
};
在生產(chǎn)環(huán)境中推薦使用 MiniCssExtractPlugin 來提取樣式表到專門的文件中,這樣你的樣式就不需要依賴 JavaScript。
webpack 提供了一種 解析文件的高級(jí)機(jī)制。 stylus-loader 將所有的查詢結(jié)果傳遞給了 webpack 解析器。 因此你可以從 node_modules 中導(dǎo)入 Stylus 模塊。
@import 'bootstrap-styl/bootstrap/index.styl';
~ 用法已被廢棄,可以從代碼中刪除(我們建議這么做),但是我們會(huì)因?yàn)橐恍v史原因一直支持這種寫法。 為什么你可以移除它呢?loader 首先會(huì)嘗試以相對(duì)路徑解析 @import,如果它不能被解析,loader 將會(huì)嘗試在 node_modules 中解析 @import。 只要在包名前加上 ~,告訴 webpack 在 modules 中進(jìn)行查找。
@import "~bootstrap-styl/bootstrap/index.styl";
重要的是只在它的前面加上 ~,因?yàn)?nbsp;~/ 會(huì)被解析到根目錄。 webpack 需要區(qū)分 bootstrap 和 ~bootstrap,因?yàn)?CSS 和 Stylus 文件沒有特殊的語法可以導(dǎo)入相對(duì)路徑的文件。 @import "file" 和 @import "./file"; 寫法是等價(jià)的。
如果指定 paths 選項(xiàng),將從指定的 paths 中搜索模塊。 這是 Stylus 的默認(rèn)行為。
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.styl/,
use: [
{
loader: "style-loader",
},
{
loader: "css-loader",
},
{
loader: "stylus-loader",
options: {
stylusOptions: {
paths: [path.resolve(__dirname, "node_modules")],
},
},
},
],
},
],
},
};
通過 webpack 打包 CSS 有很多好處,比如給引用圖片和字體文件路徑添加 hash, 在開發(fā)環(huán)境可以模塊熱更新。另一方面,在生產(chǎn)環(huán)境,根據(jù) JS 來控制應(yīng)用樣式表不是一個(gè)好的方式,可能會(huì)導(dǎo)致延遲渲染,甚至可能會(huì)出現(xiàn)閃爍現(xiàn)象。因此,在你最終的生產(chǎn)環(huán)境中將它們拆分成單獨(dú)的文件來存放通常是比較好的選擇。
有兩種從 bundle 中提取樣式表的方式:
如果你還沒有看過我們的貢獻(xiàn)者指南請(qǐng)先花點(diǎn)時(shí)間看一下。
CONTRIBUTING
更多建議: