stylus-loader

免責事項 stylus-loaderは、コミュニティメンバーによって保守されているサードパーティパッケージです。webpackと同じサポート、セキュリティポリシー、またはライセンスを持っているとは限らず、webpackによって保守されているわけではありません。

npm node tests cover discussion size

webpack用のStylusローダー。Stylusを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ドキュメントを参照してください。ダッシュケースのオプションはcamelCaseを使用する必要があります。

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.dokyumento.jp/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.dokyumento.jp/docs/executable.html
                 *
                 * @type {boolean}
                 * @default false
                 */
                lineNumbers: true,

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

                /**
                 * Compress CSS output.
                 * In the "production" mode is `true` by default
                 *
                 * @see https://stylus.dokyumento.jp/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.dokyumento.jp/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-ruleは機能しなくなるため、注意して使用してください。

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エントリファイルなど、これよりも簡単な解決策があります。

string

module.exports = {
  module: {
    rules: [
      {
        test: /\.styl/,
        use: [
          "style-loader",
          "css-loader",
          {
            loader: "stylus-loader",
            options: {
              additionalData: `@env: ${process.env.NODE_ENV};`,
            },
          },
        ],
      },
    ],
  },
};

function

同期
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.dokyumento.jp/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.dokyumento.jp/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の実装を決定します。ローカルにインストールされているstyluspeerDependencyバージョンを上書きします。

function

webpack.config.js

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

string

webpack.config.js

module.exports = {
  module: {
    rules: [
      {
        test: /\.styl/i,
        use: [
          "style-loader",
          "css-loader",
          {
            loader: "stylus-loader",
            options: {
              implementation: require.resolve("stylus"),
            },
          },
        ],
      },
    ],
  },
};

通常の使用方法

すべてのスタイルをすぐにDOMに適用するには、stylus-loadercss-loaderstyle-loaderとチェーンします。

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

ソースマップ

CSSのソースマップを有効にするには、ローダーのオプションでsourceMapプロパティを渡す必要があります。これが渡されない場合、ローダーはdevtoolで設定されたwebpackソースマップの設定を尊重します。

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のresolverは.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 resolver

Webpackはファイルの解決を高度に制御するメカニズムを提供しています。stylus-loaderはクエリ処理時にwebpackのresolverを適用します。そのため、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とStylusファイルは、相対ファイルのインポートに特別な構文を持たないためです。@import "file"@import "./file";は同じです。

Stylus resolver

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(Flash of Unstyled Content)が発生する可能性があります。そのため、最終的な本番ビルドでは、それらを個別のファイルとして持つ方が良いことがよくあります。

バンドルからスタイルシートを抽出するには2つの方法があります。

  • extract-loader(シンプルですが、css-loaderの出力に特化しています)
  • MiniCssExtractPlugin(より複雑ですが、あらゆるユースケースで機能します)

コントリビューション

まだお読みでない場合は、コントリビューションガイドラインをお読みください。

コントリビューション

ライセンス

MIT