質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.12%

【webpack】別ファイルのstylusファイルをビルドするconfigの書き方について

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 523

hasshy

score 60

webpackで、vue+pug+stylusをビルドしたいのですが、stylusをcssファイルにビルドして読み込ませる方法が分かりません。  

vueファイル内のstyleタグ内でlangにstylusを指定して変換する事はできました。 
しかし、別ファイルにしているstylusファイルをビルドする方法が分かりません。  

別ファイルにしたい目的は、vueで動的に変えない静的な要素(例えばヘッダーやフッター)は、stylusファイルからビルドしたcssを使用したいためです。  

configの設定で足りない部分があると考えているのですが、どの様にすればstyulsファイルからcssをビルドできるのでしょうか?
また、仮想環境で確認したいのですが、どの様に設定を書けば良いのでしょうか?

仕様

ディレクトリ構成

下記の様な構成になっています。 
ビルドしたいファイルは、src/stylus配下にあるファイルです。

.
├── dest(ビルドしたファイルを置くディレクトリです)
│   ├── bundle.js
│   └── index.html
├── node_modules
├── package-lock.json
├── package.json
├── src(ビルドする元のファイルです)
│   ├── App.vue
│   ├── components
│   │   └── Counter.vue
│   ├── index.js
│   ├── pug
│   │   ├── index.pug
│   │   └── parts
│   └── stylus
│       ├── app.stylus
│       └── common.styl
├── static
└── webpack.config.js

インストールしているnpmのライブラリ

package.jsonのライブラリの中身をそのまま転記して恐縮ですが、次のライブラリをインストールしています。  
試行錯誤でインストールしたものもあり、不要なものもあるかもしれません。

"devDependencies": {
  "@babel/core": "^7.2.2",
  "@babel/preset-env": "^7.3.1",
  "autoprefixer": "^9.4.7",
  "babel-loader": "^8.0.5",
  "clean-webpack-plugin": "^1.0.1",
  "css-loader": "^2.1.0",
  "html-webpack-plugin": "^3.2.0",
  "postcss-loader": "^3.0.0",
  "pug": "^2.0.3",
  "pug-plain-loader": "^1.0.0",
  "raw-loader": "^1.0.0",
  "style-loader": "^0.23.1",
  "stylus": "^0.54.5",
  "stylus-loader": "^3.0.2",
  "vue-loader": "^15.6.2",
  "vue-template-compiler": "^2.5.22",
  "webpack": "^4.29.0",
  "webpack-cli": "^3.2.1",
  "webpack-dev-server": "^3.1.14"
},
"dependencies": {
  "vue": "^2.5.22"
},

ファイルについて

index.html

head内で読み込んでるcommon.cssとapp.cssは、それぞれ、common.stylusと、app.stylusをビルドしたものを読み込ませる想定で入れています。  

<!DOCTYPE html>
<html lang="jp" dir="ltr">

<head>
  <meta charset="utf-8">
  <title>タイトルタグ</title>
  <link rel="stylesheet" href="css/common.css">
  <link rel="stylesheet" href="css/app.css">
</head>

<body>
  <header>
    <h1 class="header__title">ページタイトル</h1>
  </header>
  <div id="app"></div>
  <div id="main"></div>
  <div class="container">
    <h2 class="container__subtitle">注意</h2>
    <p>ホゲホゲ</p>
  </div>
  <footer>
    <div class="copylight">&copy; コピーライト</div>
  </footer>
  <script type="text/javascript" src="bundle.js"></script>
</body>

</html>

(参考)元のpugファイル

ご参考までにビルド前の状態です。

doctype html
html(lang='jp' dir='ltr')
  head
    meta(charset='utf-8') 
    title タイトルタグ
    link(rel='stylesheet', href="css/common.css")
    link(rel='stylesheet', href="css/app.css")

  body
    header
      h1.header__title ページタイトル

    #app
    #main

    .container
      h2.container__subtitle 注意
      p ホゲホゲ

    footer
      .copylight &copy; コピーライト

webpack.config.js

'use strict'

const path = require('path')

const vueLoaderPlugin = require('vue-loader/lib/plugin')
const htmlWebpackPlugin = require('html-webpack-plugin')

const cleanWebpackPlugin = require('clean-webpack-plugin')

module.exports = {

  entry: {
    app: './src/index.js'
  },

  output: {
    path: path.resolve(__dirname, './dest'),
    filename: 'bundle.js'
  },

  devServer: {
    contentBase: path.resolve(__dirname, 'public')
  },

  module: {
    rules: [
      {
        test: /\.vue$/,
        loader: 'vue-loader'
      },
      {
        test: /\.js$/,
        loader: 'babel-loader'
      },
      {
        test: /\.pug$/,
        oneOf: [
          {
            resourceQuery: /^\?vue/,
            use: [
              'pug-plain-loader'
            ]
          },
          {
            use: [
              'raw-loader',
              'pug-plain-loader'
            ]
          }
        ]
      },
      {
        test: /\.css$/,
        use: [
          'vue-style-loader',
          'css-loader'
        ]
      },
      {
        test: /\.styl(us)?$/,
        exclude: /node_modules/,
        use: [
          {
            loader: 'vue-style-loader'
          },
          {
            loader: 'css-loader'
          },
          {
            loader: 'stylus-loader'
          }
        ]
      }
    ]
  },

  // リザーブ
  resolve: {
    extensions: ['.js', '.vue'],
    alias: {
      vue$: 'vue/dist/vue.esm.js'
    }
  },

  // プラグイン設定
  plugins: [
    new cleanWebpackPlugin(['dest']),
    new vueLoaderPlugin(),
    new htmlWebpackPlugin({
      template: './src/pug/index.pug',
      inject: true
    })
  ]
}

App.vue 

vueは下記の様に記載しました。  
stylusについてですので、Counterについては省略します。

<template lang="pug">
.container
  h2.container__subtitle メインアプリ
  p.container__message Heelo, World!
  counter
</template>

<script>
import Counter from './components/Counter'

export default {
  components: {Counter},
}
</script>

<style lang="stylus">
.container__message
  color red
</style>

index.js(エントリーポイントに使用しているjs)

import Vue from 'vue'
import App from './App'

new Vue({
  el: '#app',
  components: { App },
  template: '<app/>'
})

stylusのファイルについて

stylusで現在コードがあるのは、common.stylのみですので、こちらを記載します。

#main
  color: red;
  width: 100%;
  border: 1px

実現出来ている事

前述した内容と重複しますが次の事は出来ています。  

  • pug内に記載したstylusはビルド出来ている。 
  • 仮想環境で確認するためにwebpack-dev-server --hotを実行すると、pugから作成されたhtmlと、vueからビルドしたjsファイルを読み込まれていることが確認できた。   
  • 仮想環境環境は、webpack-dev-serverを使用しています。  
  • 実ファイルを生成するために、webpack -pを実行すると、pugから作成されたhtmlと、vueからビルドしたjsファイルが生成されることは確認できた。
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • wwbQzhMkhhgEmhU

    2019/02/02 14:35

    CSSとか詳しくなくてすみませんが、index.jsが分からないです。
    1つでいいのでstylusファイルも置いてください。
    とりあえず以下の想定なら変更なしである程度動くような気がするのですが。。。
    =src/index.js=
    import './stylus/index.stylus'
    =src/stylus/index.stylus
    @import 'a.stylus'
    @import 'b.stylus'
    @import 'c.stylus'

    キャンセル

  • hasshy

    2019/02/02 15:09

    ご回答ありがとうございます。
    解決方法までお教えいただきありがとうございます。

    エンドポイントのjs内でstylusファイルをインポートするのですね。
    jsと同様にcssも生成するのだと勘違いしておりました。
    webpackについて知識が足りておらずお手数をおかけしました。

    キャンセル

  • wwbQzhMkhhgEmhU

    2019/02/02 15:27

    この設定はそういう意図に見えました。
    CSSを別ファイル出力にする記事もいくつか見たことがありますが、なんとなく読んでません。
    お力になれず、申し訳ありません。

    キャンセル

  • hasshy

    2019/02/02 15:29

    いえいえ、ご回答頂き助かりました。
    ありがとうございます。

    キャンセル

回答 1

check解決した方法

0

エンドポイントのjsでstylusのファイルをインポートする事で解決しました。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.12%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる