Edited at

webpack.configはCoffeeScriptで書くと幸せになれる

More than 1 year has passed since last update.

「CoffeeScript信者として何か書かねばならぬが、ネタが思い浮かばないぜ。」

皆さん日々、四苦八苦しながらwebpack.configを書いているでしょうか?その四苦八苦、CoffeeScriptを使うと少し楽になりますよ。


webpack.configをCoffeeScriptで使う方法

まずは、coffeescriptをpackageに含めます。

$ yarn add -D coffeescript

あとは拡張子を.coffeeにしてwebpack.config.coffeeとするだけです。偉いぞwebpack!


CoffeeScriptの何が嬉しいか


記述が簡潔になる

CoffeeScriptを使うと記述が簡潔になる気がします。実際に見比べてみてください。


webpack.config.js

const path = require('path');

const webpack = require('webpack');
const merge = require('webpack-merge');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');

let loader = {};
loader.coffee = ['babel-loader', 'coffee-loader'];
loader.css = [
{ loader: 'css-loader' , options: { sourceMap: true } },
{ loader: 'postcss-loader', options: { sourceMap: true } },
{ loader: 'stylus-loader' , options: { sourceMap: true } },
];
loader.stylus = [
{ loader: 'style-loader' , options: { sourceMap: true } },
{ loader: 'css-loader' , options: { sourceMap: true } },
{ loader: 'postcss-loader', options: { sourceMap: true } },
{ loader: 'stylus-loader' , options: { sourceMap: true } },
{
loader: 'stylus-resources-loader',
options: {
resources: [
path.resolve(__dirname, './src/styles/_variables.styl'),
path.resolve(__dirname, './src/styles/_mixins.styl')
]
}
},
];
loader.json = ['json-loader'];

baseConfig = {
entry: './src/main.js',
output: {
path: path.resolve(__dirname, './dist'),
publicPath: ''
},
module: {
rules: [
{
test: /\.vue$/,
use: {
loader: 'vue-loader',
options: {
loaders: {
coffee: loader.coffee,
stylus: loader.stylus
}
}
}
},
{
test: /\.(png|jpg|gif|svg)$/,
use: [
{
loader: 'file-loader',
options: {
name: '[name].[ext]?[hash]'
}
}
]
},
{
test: /\.coffee$/,
use: loader.coffee
},
{
test: /\.css$/,
use: loader.css
},
{
test: /\.styl$/,
use: loader.stylus
},
{
test: /\.json$/,
use: loader.json
}
]
},
resolve: {
alias: {
'@root': path.resolve(__dirname),
'@src': path.resolve(__dirname, 'src'),
'@scripts': path.resolve(__dirname, 'src', 'scripts'),
'@components': path.resolve(__dirname, 'src', 'components'),
'@pages': path.resolve(__dirname, 'src', 'pages'),
'@assets': path.resolve(__dirname, 'src', 'assets'),
'@styles': path.resolve(__dirname, 'src', 'styles'),
'vue$': 'vue/dist/vue.esm.js'
}
},
plugins: [
new HtmlWebpackPlugin({
template: path.resolve(__dirname, 'src', 'index_template.html')
}),
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: `'${process.env.NODE_ENV}'`
}
}),
new webpack.ProvidePlugin({
'_': 'lodash',
'axios': 'axios'
})
]
};

if (process.env.NODE_ENV === 'production') {
config = merge(baseConfig, {
output: {
filename: 'build-[hash].js'
},
devtool: '#source-map',
plugins: [
new CleanWebpackPlugin(['dist']),
new webpack.optimize.UglifyJsPlugin({
sourceMap: true,
compress: {
warnings: false
}
}),
new webpack.LoaderOptionsPlugin({
minimize: true
})
]
});
} else {
config = merge(baseConfig, {
output: {
filename: 'build.js'
},
devtool: '#eval-source-map',
devServer: {
contentBase: 'dist',
historyApiFallback: true,
noInfo: true
},
performance: {
hints: false
}
});
}

module.exports = config;



webpack.config.coffee

path = require('path')

webpack = require('webpack')
merge = require('webpack-merge')
HtmlWebpackPlugin = require('html-webpack-plugin')
CleanWebpackPlugin = require('clean-webpack-plugin')

loader = {}
loader.coffee = ['babel-loader', 'coffee-loader']
loader.css = [
{ loader: 'css-loader' , options: sourceMap: true }
{ loader: 'postcss-loader', options: sourceMap: true }
{ loader: 'stylus-loader' , options: sourceMap: true }
]
loader.stylus = [
{ loader: 'style-loader' , options: sourceMap: true }
{ loader: 'css-loader' , options: sourceMap: true }
{ loader: 'postcss-loader', options: sourceMap: true }
{ loader: 'stylus-loader' , options: sourceMap: true }
{
loader: 'stylus-resources-loader'
options:
resources: [
path.resolve(__dirname, './src/styles/_variables.styl')
path.resolve(__dirname, './src/styles/_mixins.styl')
]
}
]
loader.json = ['json-loader']

baseConfig =
entry: './src/main.js'
output:
path: path.resolve(__dirname, './dist')
publicPath: ''
module:
rules: [
test: /\.vue$/
use:
loader: 'vue-loader'
options:
loaders:
coffee: loader.coffee
stylus: loader.stylus
,
test: /\.(png|jpg|gif|svg)$/
use: [
loader: 'file-loader'
options:
name: '[name].[ext]?[hash]'
]
,
test: /\.coffee$/
use: loader.coffee
,
test: /\.css$/
use: loader.css
,
test: /\.styl$/
use: loader.stylus
,
test: /\.json$/
use: loader.json
]
resolve:
alias:
'@root': path.resolve(__dirname)
'@src': path.resolve(__dirname, 'src')
'@scripts': path.resolve(__dirname, 'src', 'scripts')
'@components': path.resolve(__dirname, 'src', 'components')
'@pages': path.resolve(__dirname, 'src', 'pages')
'@assets': path.resolve(__dirname, 'src', 'assets')
'@styles': path.resolve(__dirname, 'src', 'styles')
'vue$': 'vue/dist/vue.esm.js'
plugins: [
new HtmlWebpackPlugin
template: path.resolve(__dirname, 'src', 'index_template.html')
new webpack.DefinePlugin
'process.env':
NODE_ENV: "'#{process.env.NODE_ENV}'"
new webpack.ProvidePlugin
'_': 'lodash'
'axios': 'axios'
]

if process.env.NODE_ENV == 'production'
config = merge baseConfig,
output:
filename: 'build-[hash].js'
devtool: '#source-map'
plugins: [
new CleanWebpackPlugin(['dist'])
new webpack.optimize.UglifyJsPlugin
sourceMap: true
compress:
warnings: false
new webpack.LoaderOptionsPlugin
minimize: true
]
else
config = merge baseConfig,
output:
filename: 'build.js'
devtool: '#eval-source-map'
devServer:
contentBase: 'dist'
historyApiFallback: true
noInfo: true
performance:
hints: false

module.exports = config


どうでしょうか?webpack.config.coffeeのほうが余計なブレースやカンマがなくなり、スッキリした見た目になっていると思いませんか?そうでもないですか?

まぁ、分かる人にだけわかってもらえれば結構。


試行錯誤しやすい

webpack.configを試行錯誤しながら編集することはままあります。そんなときjsだと結構いらいらさせられます。


webpack.config.js

    plugins: [

new webpack.optimize.UglifyJsPlugin({
sourceMap: true,
compress: {
warnings: false
}
}),
new webpack.LoaderOptionsPlugin({
minimize: true
})
+ new CleanWebpackPlugin(['dist']) // pluginを足してみて動きを確かめたい。
]

このweboack.config.jsはシンタックスエラーになります。追加した行の手前にカンマがないからです。憎い!

CoffeeScriptならこのようなイライラとは無縁です。


webpack.config.coffee

    plugins: [

new webpack.optimize.UglifyJsPlugin
sourceMap: true
compress:
warnings: false
- new webpack.LoaderOptionsPlugin # 削除も
- minimize: true
+ new CleanWebpackPlugin(['dist']) # 追加も自由自在!
]


まとめ

どうですか?CoffeeScriptが使ってみたくなりましたか?なりませんか?そうですか。残念です・・・。