webpack用のStylusローダー。StylusをCSSにコンパイルします。
始めるには、stylus
とstylus-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の実装を決定します。ローカルにインストールされているstylus
のpeerDependency
バージョンを上書きします。
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-loader
をcss-loader
とstyle-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,
},
},
],
},
],
},
};
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"],
},
},
},
],
},
],
},
};
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はファイルの解決を高度に制御するメカニズムを提供しています。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";
は同じです。
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の出力に特化しています)まだお読みでない場合は、コントリビューションガイドラインをお読みください。