board-game
Version:
an online board game engine
237 lines (231 loc) • 8.29 kB
JavaScript
const fs = require('fs');
const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const extend = require('extend');
const mime = require('mime');
const rimraf = require('rimraf');
const loadToBase64 = path => {
if (/^https?:\/\//.test(path)) {
return path;
} else {
let mimeType = mime.lookup(path);
return 'data:' + (mimeType ? mimeType + ';' : '') + 'base64,' + Buffer.from(fs.readFileSync(path)).toString('base64');
}
};
const asDefine = value => {
if (typeof value === 'undefined') {
return value;
} else if (typeof value === 'object') {
if (Array.isArray(value)) {
return value.map(v => asDefine(v));
} else {
let result = { };
for (let name in value) {
if (value.hasOwnProperty(name)) {
result[name] = asDefine(value[name]);
}
}
return result;
}
} else {
return JSON.stringify(value);
}
};
const extensions = {
css: {
less: [ '.less' ]
},
mvvm: {
vue: [ '.vue' ]
}
};
const externals = {
vue: {
vue: 'Vue'
}
};
const loaders = {
css: {
less() {
return [
{
test: /\.less$/,
loader: 'style-loader!css-loader!less-loader',
exclude: {
and: [
/node_modules|bower_components/,
{ not: [ /board-game/ ] }
]
}
}
]
}
},
mvvm: {
vue(config) {
const cssLoaders = {
less() {
return {
less: 'vue-style-loader!css-loader!less-loader'
};
}
};
return [
{
test: [ require.resolve('./web/vue/adapter'), require.resolve('./web/vue/mixin') ],
loader: 'babel-loader',
options: { presets: config.presets }
},
{
test: /\.vue$/,
loader: 'vue-loader',
options: {
loaders: extend(true, {
js: {
loader: 'babel-loader',
options: {
presets: config.presets
}
}
}, cssLoaders[config.css] && cssLoaders[config.css](config) || { })
},
exclude: {
and: [
/node_modules|bower_components/,
{ not: [ /board-game/ ] }
]
}
}
]
}
}
};
module.exports = (config, callback) => {
if (fs.existsSync(path.resolve(config.assets))) {
rimraf.sync(path.resolve(config.assets));
}
fs.mkdirSync(path.resolve(config.assets));
webpack({
entry: {
index: config.index
},
output: {
path: path.resolve(config.assets),
filename: config.hash ? '[name].[hash].js' : '[name].js'
},
module: {
loaders: [
{
test: /\.js$/,
loader: 'babel-loader',
options: {
presets: config.presets
},
// exclude: /node_modules|bower_components/
exclude: {
and: [
/node_modules|bower_components/,
{ not: [ /board-game/ ] }
]
}
},
{
test: require.resolve('./client'),
use: [
{
loader: 'babel-loader',
options: {
presets: config.presets
}
},
{
loader: `imports-loader?css=./css/${ config.css }/client.${ config.css }&adapter=./web/${ config.mvvm }/adapter`
}
],
},
{
test: /\.css$/,
loader: 'style-loader!css-loader',
},
{
test: /\.(png|jpe?g|gif|ico|wav|mp[34]|ogg)$/,
loader: 'url-loader?limit=10000&name=[name].[ext]'
},
{
test: /\.woff2?(\?.*)?$/,
loader: 'url-loader?limit=10000&name=[name].[ext]&mimetype=application/font-woff'
},
{
test: /\.ttf(\?.*)?$/,
loader: 'url-loader?limit=10000&name=[name].[ext]&mimetype=application/octet-stream'
},
{
test: /\.eot(\?.*)?$/,
loader: 'url-loader?limit=10000&name=[name].[ext]'
},
{
test: /\.svg(\?.*)?$/,
loader: 'url-loader?limit=10000&name=[name].[ext]&mimetype=image/svg+xml'
}
]
.concat(loaders.css[config.css] && loaders.css[config.css](config) || [])
.concat(loaders.mvvm[config.mvvm] && loaders.mvvm[config.mvvm](config) || [])
.concat(config.loaders || [])
},
resolve: {
extensions: ['.js', '.json'].concat(extensions.css[config.css] || []).concat(extensions.mvvm[config.mvvm] || [])
},
resolveLoader: {
modules: [path.join(__dirname, 'node_modules'), 'node_modules']
},
externals: extend(true, {
jquery: 'jQuery',
'socket.io-client': 'io',
qrcode: 'qrcode',
}, externals[config.mvvm] || { }),
plugins: [
new HtmlWebpackPlugin({
filename: 'entry.html',
title: config.name,
meta: {
description: config.description || config.name,
keywords: config.keywords || config.name
},
inject: 'head',
template: path.join(__dirname, 'index.ejs'),
body: fs.readFileSync(path.join(__dirname, `web/${ config.mvvm }/index.html`)),
logo: config.logo ? loadToBase64(config.logo) : false
}),
new HtmlWebpackPlugin({
filename: 'seo.html',
seo: true,
title: config.name,
meta: {
description: config.description || config.name,
keywords: config.keywords || config.name
},
inject: 'head',
template: path.join(__dirname, 'index.ejs'),
logo: config.logo ? loadToBase64(config.logo) : false
}),
new webpack.DefinePlugin({ config: extend(true, asDefine(config), { dev: process.env.NODE_ENV === 'development' }) })
].concat(config.compress ? [
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false,
drop_debugger: true,
drop_console: true,
properties: true,
join_vars: true
}
})
] : []),
watch: config.watch,
devtool: config.devtool
}, (err, stats) => {
process.stdout.write(stats.toString(config.stats) + "\n");
if(err) console.error(err);
else callback && callback();
});
};