webpack 4では extract-text-webpack-plugin
が deplicated になったので、代替の minicss-ectract-plugin
を使おうと思ったのだけど、簡単にはいかなかった。のでまとめ。
dir.src = 'src'
, dir.dest = 'public'
って感じです。
/////////////////////////////////////////////////////////////////////////////////////
// Requirement
const path = require('path')
const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const FixStyleOnlyEntriesPlugin = require('webpack-fix-style-only-entries')
const cssDeclarationSorter = require('css-declaration-sorter')
const cssMqpacker = require('css-mqpacker')
const autoprefixer = require('autoprefixer')
/////////////////////////////////////////////////////////////////////////////////////
// Config
const config = require('./config')
const dir = config.dir
const devMode = process.env.NODE_ENV !== 'production'
/////////////////////////////////////////////////////////////////////////////////////
// Exports
module.exports = {
mode: process.env.NODE_ENV || 'development',
entry: {
index: path.resolve(__dirname, dir.src, 'js', 'index.js'),
index2: path.resolve(__dirname, dir.src, 'js', 'index2.js'),
'style.css': path.resolve(__dirname, dir.src, 'stylus', 'style.styl'),
'style2.css': path.resolve(__dirname, dir.src, 'stylus', 'style2.styl')
},
output: {
filename: 'js/[name].js',
path: path.resolve(__dirname, dir.dest)
},
optimization: {
minimizer: [
new OptimizeCssAssetsPlugin()
],
minimize: !devMode
},
plugins: [
new FixStyleOnlyEntriesPlugin({
extensions: ['styl', 'css']
}),
new MiniCssExtractPlugin({
filename: 'css/[name]'
})
],
module: {
rules: [
{
test: /\.js$/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env']
}
},
exclude: /node_modules/
},
{
test: /\.(styl|css)$/,
use: [
{
loader: MiniCssExtractPlugin.loader
},
{
loader: 'css-loader'
},
{
loader: 'postcss-loader',
options: {
ident: 'postcss',
plugins: () => [
cssMqpacker({
sort: true
}),
cssDeclarationSorter({
order: 'smacss'
}),
autoprefixer({
grid: true,
browsers: [
'last 2 versions'
]
})
]
}
},
{
loader: 'stylus-loader',
options: {
'include css': true
}
}
]
}
]
}
}
ポイント
まず、 entry
のキーにファイル名を指定するが、このときJavaScriptの拡張子は output.filename
で指定、CSSの拡張子はキーに直接書き、プラグインオプションの filename
では拡張子は指定しないようにする。理由は以下のとーり。
順を追って説明すると、まず extract-text-webpack-plugin の代わりに使う minicss-extract-plugin は、なぜかcssを取り出す前のjsファイルが残ってしまう。そもそも不要だし、ともすると「同じファイル名のChunkがあってコンフリクトしてます」とかエラーが出る。
これを解決するのが webpack-fix-style-only-entries
なんだけど、これは cssの名前.js
ファイルを消してくれる挙動っぽいので、正しく消してもらうためにはこのパターン以外うまくいかない。
もうひとつ。 webpack-fix-style-only-entries
の extensions
に、対象のスタイルの拡張子を配列で書く。デフォルトは ["less", "scss", "css"]
なので、stylやsassなら書き換えが必要。