手を動かしてみると違いがわかるはず。
Webpack
webpackを導入
$ mkdir counter-webpack
$ cd counter-webpack
$ npm init -y
$ npm i -D webpack webpack-cli webpack-dev-server
$ touch webpack.config.js
webpack.config.js
const path = require('path')
module.exports = {
entry: './src/index.js',
output: {
path: path.resolve(__dirname, './dist'),
filename: 'bundle.js'
},
devServer: {
contentBase: path.resolve(__dirname, 'public')
}
}
package.json
"scripts": {
"start": "webpack-dev-server",
"build": "webpack -p"
}
$ mkdir src
$ touch src/index.js
$ mkdir public
$ touch public/index.html
src/index.js
console.log('Hello, World!')
public/index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Vue app</title>
</head>
<body>
<div id="app"></div>
<script src="bundle.js"></script>
</body>
</html>
$ npm start
http://localhost:8080/ を開いて一度動作確認。
Vueと関連ツールをインストール
$ npm i vue
$ npm i -D vue-loader vue-template-compiler css-loader style-loader
$ npm i -D babel-loader @babel/core @babel/preset-env
webpack.config.js
const path = require('path')
+ const VueLoaderPlugin = require('vue-loader/lib/plugin')
module.exports = {
entry: './src/index.js',
output: {
path: path.resolve(__dirname, './dist'),
filename: 'bundle.js'
},
+ module: {
+ rules: [
+ {
+ test: /\.vue$/,
+ loader: 'vue-loader'
+ },
+ {
+ test: /\.js$/,
+ loader: 'babel-loader',
+ },
+ {
+ test: /\.css$/,
+ use: [
+ 'vue-style-loader',
+ 'css-loader'
+ ]
+ },
+ ]
+ },
+ resolve: {
+ extensions: ['.js', '.vue'],
+ alias: {
+ vue$: 'vue/dist/vue.esm.js',
+ }
+ },
+ plugins: [
+ new VueLoaderPlugin()
+ ],
devServer: {
contentBase: path.resolve(__dirname, './public')
}
}
package.json
{
"babel": {
"presets": ["@babel/preset-env"]
},
"browserslist": "last 2 versions, not dead, not ie > 0",
}
プログラムを記述
$ mkdir src/components
$ touch src/components/App.vue
$ touch src/components/Counter.vue
src/components/Counter.vue
<script>
export default {
data() {
return {
count: 0,
}
},
methods: {
add: function() {
this.count++
},
reduce: function() {
this.count--
}
}
}
</script>
<template>
<div>
<p>Written in Counter.vue</p>
<button @click='reduce'>-</button>
<span>{{ count }}</span>
<button @click='add'>+</button>
</div>
</template>
<style scoped>
div {
color: blue;
}
button {
width: 30px;
height: 30px;
border-radius: 50%;
}
</style>
src/components/App.vue
<script>
import Counter from './Counter'
export default {
components: { Counter }
}
</script>
<template>
<div>
<p>Written in App.vue</p>
<counter/>
</div>
</template>
<style scoped>
div {
background: green;
}
</style>
src/index.js
import Vue from 'vue'
import App from './components/App'
new Vue({
el: '#app',
components: { App },
template: '<app/>'
})
ビルド時にpublicディレクトリ内のファイルを含める
npm i -D copy-webpack-plugin
webpack.config.js
const CopyPlugin = require('copy-webpack-plugin')
module.exports = {
// ...
plugins: [
// ...
new CopyPlugin([{ from: './public' }])
],
// ...
}
完成!
Vue CLI
セットアップ
$ npm install -g @vue/cli
$ vue create counter-vuecli
? Please pick a preset: default (babel, eslint) #defaultを選択
$ cd counter-vuecli
$ npm run serve
http://localhost:8080/ にアクセスして表示を確認
プログラムを記述
$ touch src/components/Counter.vue
src/components/Counter.vue
<template>
<div>
<p>Written in Counter.vue</p>
<button @click="reduce">-</button>
<span>{{ count }}</span>
<button @click="add">+</button>
</div>
</template>
<script>
export default {
data() {
return {
count: 0
};
},
methods: {
add: function() {
this.count++;
},
reduce: function() {
this.count--;
}
}
};
</script>
<style scoped>
div {
color: blue;
}
button {
width: 30px;
height: 3
0px;
border-radius: 50%;
}
</style>
src/App.vue
<template>
<div>
<p>Written in App.vue</p>
<counter />
</div>
</template>
<script>
import Counter from "./components/Counter";
export default {
components: { Counter }
};
</script>
<style scoped>
div {
background: green;
}
</style>
完成!
Vue CLIの内部でWebpackが動いていて、いろんな設定を自動でやってくれているようです。
public/index.html
内に<!-- built files will be auto injected -->
って書いてある通り、バンドルされたjsファイルが自動で挿入されます。
ビルド用にcopy-webpack-plugin
を手動で入れる必要もありません。
Nuxt.js
セットアップ
$ npx create-nuxt-app counter-nuxt
# 以下を選択。他はデフォルト
# language: JavaScript
# package manager: npm
# mode: Single Page App
$ cd counter-nuxt
$ npm run dev
http://localhost:3000/ にアクセスして表示を確認
プログラムを記述
$ touch components/Counter.vue
components/Counter.vue
<template>
<div>
<p>Written in Counter.vue</p>
<button @click="reduce">-</button>
<span>{{ count }}</span>
<button @click="add">+</button>
</div>
</template>
<script>
export default {
data() {
return {
count: 0
};
},
methods: {
add: function() {
this.count++;
},
reduce: function() {
this.count--;
}
}
};
</script>
<style scoped>
div {
color: blue;
}
button {
width: 30px;
height: 30px;
border-radius: 50%;
}
</style>
pages/index.vue
<template>
<div>
<p>Written in index.vue</p>
<counter />
</div>
</template>
<script>
import Counter from "../components/Counter";
export default {
components: { Counter }
};
</script>
<style scoped>
div {
background: green;
}
</style>
layouts/default.vue
<template>
<div>
<nuxt />
</div>
</template>