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
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)
冒頭の画像のソースコードです。 mounted
やupdated
のタイミングでスクリプトを呼んでいます。
<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
"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!