38
Help us understand the problem. What are the problem?

More than 5 years have passed since last update.

posted at

updated at

vue-cli with Semantic UI on webpack

Vue with Semantic-UI on webpack

Bootstrap もよいですが、 Semantic UI がとてもよくできています。「これはいい!」と意気込んでみたものの、 webpack で扱うのにつまずきました。調べたところ世界で多くの方たちが悩まれているようです。ここらでひとつ真面目に取り組んでみるかということで、なんとか動作した設定に至るまでの流れを残しておきます。

ちなみに Vue を前提に話を進めていますが、 React であれば Semantic UI React がオフィシャルに提供されているのでそれを素直に使うのがよいでしょう。

前提

$ date
2017年 3月28日 火曜日 21時12分35秒 JST

$ node -v
v7.7.4

$ npm -v
4.5.0

vue-cli

$ npm install -g vue-cli
$ vue -V
2.8.1

ポイントを簡潔に示すために webpack-simple テンプレートを選択しています。

$ vue init webpack-simple my-project

  This will install Vue 2.x version of the template.

  For Vue 1.x use: vue init webpack-simple#1.0 my-project

? Project name my-project
? Project description A Vue.js project
? Author mail@example.com
? Use sass? No
$ cd my-project

$ npm install

Semantic UI

※ 以下の操作は結局のところダウンロードした Semantic UI ソースを Gulp を使って js, css, components, themes をビルドし配置しているに過ぎません。カスタマイズのつもりもなくデフォルトのテーマでよい場合は上記リンク先に記載の Simpler Setup の Download Zip から入手すればOK。

$ npm install -g gulp
$ npm install semantic-ui --save
[21:50:18] Starting 'run setup'...
? Set-up Semantic UI Automatic (Use defaults locations and all components)
?     
    We detected you are using NPM. Nice!  

    Is this your project folder?
    /Users/syon/repo/my-project 

 Yes

? Where should we put Semantic UI inside your project? semantic/
[21:52:26] Finished 'run setup' after 2.13 min
[21:52:26] Starting 'create install files'...
$ cd semantic/

$ gulp build

Semantic UI dist directory

Import Semantic UI to webpack

Semantic UI の依存パッケージである jQuery をインストールします。また、ビルドした CSS を webpack で読み込むための style-loader もインストールします。

$ npm install jquery --save

$ npm install style-loader --save-dev

webpack.config.js

Semantic UI の CSS を webpack に読み込ませ style タグに定義し、Webフォントもファイルとして読み込んでいます。ここで name=semantic/dist/themes/default/assets/fonts/[name].[ext] に着目。CSS ファイルが参照しているパスに合わせる必要があります。 jQuery は webpack グローバルで使えるようにプラグインとして登録します。これで各コンポーネントで毎回 import する必要がなくなります。

diff --git a/webpack.config.js b/webpack.config.js
index beb773d..d91f610 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -30,9 +30,23 @@ module.exports = {
         options: {
           name: '[name].[ext]?[hash]'
         }
+      },
+      {
+        test: /\.css$/,
+        use: ['style-loader', 'css-loader']
+      },
+      {
+        test: /\.(eot|svg|ttf|woff|woff2)$/,
+        loader: 'file-loader?name=semantic/dist/themes/default/assets/fonts/[name].[ext]'
       }
     ]
   },
+  plugins: [
+    new webpack.ProvidePlugin({
+      $: 'jquery',
+      jQuery: 'jquery'
+    })
+  ],
   resolve: {
     alias: {
       'vue$': 'vue/dist/vue.esm.js'

src/main.js

diff --git a/src/main.js b/src/main.js
index 385fcfe..5f7d4e4 100644
--- a/src/main.js
+++ b/src/main.js
@@ -1,6 +1,9 @@
 import Vue from 'vue'
 import App from './App.vue'

+import '../semantic/dist/semantic.css'
+import '../semantic/dist/semantic.js'
+
 new Vue({
   el: '#app',
   render: h => h(App)

App.vue (Sample)

冒頭の画像のソースコードです。 mountedupdatedのタイミングでスクリプトを呼んでいます。

App.vue
<template>
  <div id="app">
    <img src="./assets/logo.png">
    <div class="ui container">
      <div class="ui labeled button" tabindex="0">
        <div class="ui red button">
          <i class="heart icon"></i> Like
        </div>
        <a class="ui basic red left pointing label">
          1,048
        </a>
      </div>
      <div class="ui labeled button" tabindex="0">
        <div class="ui basic blue button">
          <i class="fork icon"></i> Forks
        </div>
        <a class="ui basic left pointing blue label">
          1,048
        </a>
      </div>
      <div class="ui yellow progress" data-percent="60">
        <div class="bar"></div>
      </div>
      <div class="ui olive progress" data-percent="30">
        <div class="bar"></div>
      </div>
      <div class="ui green progress" data-percent="85">
        <div class="bar"></div>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name: 'app',
  mounted () {
    $(this.$el).find('.progress').progress();
  },
  updated () {
    $(this.$el).find('.progress').progress();
  },
  data () {
    return {
      msg: 'Welcome to Your Vue.js App'
    }
  }
}
</script>

<style>
...
</style>

Dependencies

package.json(抜粋)
  "dependencies": {
    "jquery": "^3.2.1",
    "semantic-ui": "^2.2.9",
    "vue": "^2.2.1"
  },
  "devDependencies": {
    "babel-core": "^6.0.0",
    "babel-loader": "^6.0.0",
    "babel-preset-latest": "^6.0.0",
    "cross-env": "^3.0.0",
    "css-loader": "^0.25.0",
    "file-loader": "^0.9.0",
    "style-loader": "^0.16.1",
    "vue-loader": "^11.1.4",
    "vue-template-compiler": "^2.2.1",
    "webpack": "^2.2.0",
    "webpack-dev-server": "^2.2.0"
  }

Enjoy!

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sign upLogin
38
Help us understand the problem. What are the problem?