プロジェクトの雛形2016年2月版!
前回雛形との違い
- index.template.html.
- Split files vendor.js app.js and app.css.
- To compress the source using the UglifyJs.
- Use bourbon and bourbon-neat.
setup directory and node_modules
mkdir -p {build,test/{unit,e2e},src/{components,views/app,filters,directives,assets/{js,style,images,html}}}
npm init -y
npm i -g webpack webpack-dev-server mocha babel-core babel-loader power-assert node-sass
npm i -S vue vuex
npm i -D babel-core babel-loader webpack style-loader css-loader node-sass sass-loader html-loader mocha mocha-loader babel-plugin-add-module-exports babel-plugin-transform-runtime babel-polyfill babel-preset-es2015 babel-preset-stage-2 babel-runtime file-loader url-loader espower-babel power-assert lodash
npm i -D extract-text-webpack-plugin html-webpack-plugin@2
npm i -D node-bourbon node-neat
Please run with the "sudo" If the permission error has occurred
.babelrc
{
"presets": ["es2015", "stage-2"]
}
webpack.config.js
var webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var contentBase = __dirname + '/build';
var cssLoader = ExtractTextPlugin.extract('style', 'css?sourceMap!sass')
var htmlWebpackPlugin = new HtmlWebpackPlugin({
filename: 'index.html',
template: 'src/assets/html/index.template.html'
});
var pkg = require('./package.json');
var vendor = Object.keys(pkg.dependencies);
var options = {
entry: {
app: ["./src/assets/js/app.js", "./src/assets/style/app.scss"],
vendor: vendor,
},
output: {
path: contentBase + '/',
filename: "js/[name].js",
contentBase: contentBase + '/build'
},
resolve: {
alias: {
vue: "vue/dist/vue",
lodash: "lodash"
},
modulesDirectories: ['node_modules', 'src/', 'src/assets/js/', 'src/assets/style/', 'src/views/', 'src/directives/', 'src/filters/', 'src/components/'],
// require()するときに拡張子を省略可能にします
extensions: ['', '.webpack.js', '.web.js', '.js']
},
devServer: {
contentBase: "./build",
},
module: {
preloaders: [],
loaders: [
{
test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/,
loader: "url-loader?limit=10000&minetype=application/font-woff"
},
{
test: /\.png$/,
loader: "url-loader?limit=100000"
},
{
test: /\.jpg$/,
loader: "file-loader"
},
{
test: /\.(ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
loader: "file-loader"
},
{
test: /\.scss$/,
loader: cssLoader
},
{
test: /\.html$/,
loader: "html"
},
{
test: /\.js(x?)$/,
loader: 'babel-loader?sourceMaps=true'
}
]
},
plugins: [
htmlWebpackPlugin,
new ExtractTextPlugin('./css/app.css', {disable: false}),
new webpack.optimize.CommonsChunkPlugin('vendor', 'js/vendor.js')
]
};
if (process.env.NODE_ENV === 'production') {
var defplugin = new webpack.DefinePlugin({
'process.env': {
NODE_ENV: '"production"'
}
});
var minplugin = new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false
}
});
options.plugins.push(defplugin);
options.plugins.push(minplugin);
options.plugins.push(new webpack.optimize.OccurenceOrderPlugin());
}
module.exports = options;
package.json (scripts property)
"scripts": {
"hot": "webpack-dev-server -d --inline",
"build": "NODE_ENV=production webpack --progress --hide-modules",
"test": "mocha --compilers js:espower-babel/guess test/unit",
"e2e": "mocha --compilers js:espower-babel/guess test/e2e"
},
src/assets/html/index.template.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>テンプレート</title>
</head>
<body>
<app>ここにAPPが入ります</app>
</body>
</html>
src/assets/js/app.js
import Vue from 'vue';
import App from '../../views/app'
require('../style/app.scss');
new Vue({
el:'body',
components: {App}
});
src/assets/style/app.scss
@import "~bourbon";
@import "~bourbon-neat";
body {
@include outer-container();
background-color: #000000;
color: yellow;
.header {
@include span-columns(3);
background-color: #999999;
}
.navigator {
@include span-columns(5);
background-color: #333333;
}
.footer {
@include span-columns(12);
background-color: #666666;
}
}
src/views/app/index.js
export default {
template: require("./template.html")
}
src/views/app/template.html
<div class="header">ヘッダー</div>
<div class="navigator">ナビゲーター</div>
<div class="contents">コンテンツ</div>
<div class="footer">フッター</div>