stylus-loader

免責聲明:stylus-loader是一個由社群成員維護的第三方套件,它可能沒有與 webpack 相同的支援、安全政策或授權,而且它並非由 webpack 維護。

npm node tests cover discussion size

webpack 的 Stylus 載入器。將 Styl 編譯成 CSS。

入門

首先,您需要安裝 stylusstylus-loader

npm install stylus stylus-loader --save-dev

yarn add -D stylus stylus-loader

pnpm add -D stylus stylus-loader

然後將載入器新增到您的 webpack 設定檔。例如

webpack.config.js

module.exports = {
  module: {
    rules: [
      {
        test: /\.styl$/,
        loader: "stylus-loader", // compiles Styl to CSS
      },
    ],
  },
};

並透過您偏好的方法執行 webpack

選項

stylusOptions

類型

type stylusOptions =
  | {
      use: Array<string | Function>;
      include: string;
      import: string;
      define: Array;
      includeCSS: false;
      resolveURL: boolean | Object;
      lineNumbers: boolean;
      hoistAtrules: boolean;
      compress: boolean;
    }
  | (loaderContext: LoaderContext) => Array<string>;

預設值:{}

您可以透過 載入器選項 中的 stylusOptions 屬性,將任何 Stylus 特定選項傳遞給 stylus-loader。請參閱 Stylus 文件。連字號分隔的選項應使用駝峰式大小寫。

object

使用物件傳遞選項給 Stylus。

webpack.config.js

module.exports = {
  module: {
    rules: [
      {
        test: /\.styl$/,
        use: [
          {
            loader: "style-loader",
          },
          {
            loader: "css-loader",
          },
          {
            loader: "stylus-loader",
            options: {
              stylusOptions: {
                /**
                 * Specify Stylus plugins to use. Plugins may be passed as
                 * strings instead of importing them in your Webpack config.
                 *
                 * @type {(string|Function)[]}
                 * @default []
                 */
                use: ["nib"],

                /**
                 * Add path(s) to the import lookup paths.
                 *
                 * @type {string[]}
                 * @default []
                 */
                include: [path.join(__dirname, "src/styl/config")],

                /**
                 * Import the specified Stylus files/paths.
                 *
                 * @type {string[]}
                 * @default []
                 */
                import: ["nib", path.join(__dirname, "src/styl/mixins")],

                /**
                 * Define Stylus variables or functions.
                 *
                 * @type {Array|Object}
                 * @default {}
                 */
                // Array is the recommended syntax: [key, value, raw]
                define: [
                  ["$development", process.env.NODE_ENV === "development"],
                  ["rawVar", 42, true],
                ],
                // Object is deprecated syntax (there is no possibility to specify "raw')
                // define: {
                //   $development: process.env.NODE_ENV === 'development',
                //   rawVar: 42,
                // },

                /**
                 * Include regular CSS on @import.
                 *
                 * @type {boolean}
                 * @default false
                 */
                includeCSS: false,

                /**
                 * Resolve relative url()'s inside imported files.
                 *
                 * @see https://stylus.dev.org.tw/docs/js.html#stylusresolveroptions
                 *
                 * @type {boolean|Object}
                 * @default { nocheck: true }
                 */
                resolveURL: true,
                // resolveURL: { nocheck: true },

                /**
                 * Emits comments in the generated CSS indicating the corresponding Stylus line.
                 *
                 * @see https://stylus.dev.org.tw/docs/executable.html
                 *
                 * @type {boolean}
                 * @default false
                 */
                lineNumbers: true,

                /**
                 * Move @import and @charset to the top.
                 *
                 * @see https://stylus.dev.org.tw/docs/executable.html
                 *
                 * @type {boolean}
                 * @default false
                 */
                hoistAtrules: true,

                /**
                 * Compress CSS output.
                 * In the "production" mode is `true` by default
                 *
                 * @see https://stylus.dev.org.tw/docs/executable.html
                 *
                 * @type {boolean}
                 * @default false
                 */
                compress: true,
              },
            },
          },
        ],
      },
    ],
  },
};

function

允許根據載入器內容設定傳遞給 Stylus 的選項。

module.exports = {
  module: {
    rules: [
      {
        test: /\.styl/,
        use: [
          "style-loader",
          "css-loader",
          {
            loader: "stylus-loader",
            options: {
              stylusOptions: (loaderContext) => {
                // More information about available properties https://webpack.dev.org.tw/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"],
                };
              },
            },
          },
        ],
      },
    ],
  },
};

sourceMap

類型

type sourceMap = 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,
            },
          },
        ],
      },
    ],
  },
};

webpackImporter

類型

type webpackImporter = boolean;

預設值:true

啟用/停用預設的 Webpack 匯入器。

在某些情況下,這可以提升效能。請小心使用,因為別名和以 ~ 開頭的 @import at 規則將無法運作。

webpack.config.js

module.exports = {
  module: {
    rules: [
      {
        test: /\.styl/i,
        use: [
          "style-loader",
          "css-loader",
          {
            loader: "stylus-loader",
            options: {
              webpackImporter: false,
            },
          },
        ],
      },
    ],
  },
};

additionalData

類型

type additionalData =
  | string
  | (
      content: string | Buffer,
      loaderContext: LoaderContext,
      meta: any
    ) => string;

預設值:undefined

在實際的進入檔案之前,預先加入 Stylus 程式碼。在這種情況下,stylus-loader 載入器不會覆寫來源,而只是預先加入進入檔案的內容。

當你的某些 Stylus 變數取決於環境時,這項功能特別有用。

注意

由於你正在注入程式碼,這會中斷進入檔案中的來源對應。通常有比這更簡單的解決方案,例如多個 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) => {
                // More information about available properties https://webpack.dev.org.tw/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) => {
                // More information about available properties https://webpack.dev.org.tw/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;
              },
            },
          },
        ],
      },
    ],
  },
};

implementation

類型

type implementation = Function | string;

特殊的 implementation 選項決定要使用哪一種 Stylus 實作。會覆寫本機安裝的 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-loaderstyle-loader 連結,以立即將所有樣式套用至 DOM。

webpack.config.js

module.exports = {
  module: {
    rules: [
      {
        test: /\.styl$/,
        use: [
          {
            loader: "style-loader", // creates style nodes from JS strings
          },
          {
            loader: "css-loader", // translates CSS into CommonJS
          },
          {
            loader: "stylus-loader", // compiles Stylus to CSS
          },
        ],
      },
    ],
  },
};

Source maps

若要為 CSS 啟用 sourcemaps,您需要在 loader 的選項中傳遞 sourceMap 屬性。如果未傳遞此屬性,loader 將尊重 webpack source maps 的設定,設定在 devtool 中。

webpack.config.js

module.exports = {
  devtool: "source-map", // any "source-map"-like devtool is possible
  module: {
    rules: [
      {
        test: /\.styl$/,
        use: [
          "style-loader",
          {
            loader: "css-loader",
            options: {
              sourceMap: true,
            },
          },
          {
            loader: "stylus-loader",
            options: {
              sourceMap: true,
            },
          },
        ],
      },
    ],
  },
};

與 stylus 搭配使用 nib

webpack.config.js

module.exports = {
  module: {
    rules: [
      {
        test: /\.styl$/,
        use: [
          {
            loader: "style-loader", // creates style nodes from JS strings
          },
          {
            loader: "css-loader", // translates CSS into CommonJS
          },
          {
            loader: "stylus-loader", // compiles Stylus to CSS
            options: {
              stylusOptions: {
                use: [require("nib")()],
                import: ["nib"],
              },
            },
          },
        ],
      },
    ],
  },
};

匯入 JSON 檔案

Stylus 未在 json 函式中提供解析功能。因此 webpack 解析器無法用於 .json 檔案。請使用 stylus resolver

index.styl

// Suppose the file is located here `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: {
                // Specify the path. where to find files
                paths: ["node_modules/vars"],
              },
            },
          },
        ],
      },
    ],
  },
};

在生產環境中

通常建議在生產環境中使用 MiniCssExtractPlugin 將樣式表萃取到專屬檔案中。如此一來,您的樣式將不依賴 JavaScript。

webpack 解析器

Webpack 提供了 進階機制來解析檔案stylus-loader 在處理查詢時會套用 webpack 解析器。因此,您可以從 node_modules 匯入 Stylus 模組。

@import 'bootstrap-styl/bootstrap/index.styl';

使用 ~ 已過時,可以從程式碼中移除(我們建議這麼做),但我們基於歷史原因仍支援它。為什麼可以移除它?載入器會先嘗試將 @import/@require 解析為相對路徑,如果無法解析,載入器會嘗試在 node_modules 內解析 @import/@require。只要在前面加上 ~,即可告知 webpack 尋找 modules

@import "~bootstrap-styl/bootstrap/index.styl";

只在前面加上 ~ 非常重要,因為 ~/ 會解析為家目錄。Webpack 需要區分 bootstrap~bootstrap,因為 CSS 和 Styl 檔案沒有用於匯入相對檔案的特殊語法。撰寫 @import "file"@import "./file"; 相同

Stylus 解析器

如果您指定 paths 選項,系統會在指定的 paths 中搜尋模組。這是 Stylus 的預設行為。

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 有些不錯的優點,例如使用雜湊 URL 參照圖片和字型,或在開發中使用 熱模組替換。另一方面,在製作環境中,最好不要讓樣式表依賴 JS 執行。這樣可能會延遲呈現,甚至會看到 FOUC。因此,在最終製作版本中,最好還是讓樣式表成為獨立的檔案。

有兩種方法可以從綑綁中擷取樣式表

貢獻

如果您尚未閱讀我們的貢獻指南,請花點時間閱讀。

貢獻

授權

MIT