今まで、SASSを使うときは1つの.scssファイルにまとめて
$ ./node_modules/node-sass/bin/node-sass ./scss/foo.scss ./htdocs/css/foo.css --output-style compressed --source-map true &
とかやってたんだけど、JavaScriptも一緒にコンパイルしたいなと。TypeScriptじゃなくてJavaScriptなんだけど、npm installとかしたやつを一緒にコンパイルしたくなったんです。今までは、Laravel mix使ってたんで素で使うっというのが無くて…
とりあえず、package.json
{ "name": "myproject-sass", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "prod": "NODE_ENV=production webpack --mode=production", "dev": "NODE_ENV=development webpack --mode=development --watch" }, "author": "", "license": "ISC", "devDependencies": { "css-loader": "^5.1.2", "mini-css-extract-plugin": "^1.3.9", "node-sass": "^5.0.0", "sass-loader": "^11.0.1", "webpack": "^5.25.1", "webpack-cli": "^4.5.0", "webpack-fix-style-only-entries": "^0.6.1" }, "dependencies": { "bs-custom-file-input": "^1.3.4" } }
node-sass使ってるのは、いにしえのSCSSライブラリcompassを使ってるからである。
当初、sass-loaderさえあればcss-loaderいらんやろ、CSSなんて書いて無いしって思ったんだけど、いるのね。
webpack.config.js
const path = require('path'); const MiniCSSExtractPlugin = require("mini-css-extract-plugin"); const FixStyleOnlyEntries = require("webpack-fix-style-only-entries"); const enabledSourceMap = process.env.NODE_ENV !== 'production'; module.exports = ( env, argv ) => ({ entry: { "foo_script": './src/js/foo.js', "foo_style": './src/scss/foo.scss' }, output: { filename: 'js/[name].js', path: path.resolve(__dirname, 'htdocs') }, module: { rules: [ { test: /\.(sa|sc|c)ss$/, use: [ { loader: MiniCSSExtractPlugin.loader, }, { loader: "css-loader", options: { url: false, sourceMap: enabledSourceMap } }, { loader: "sass-loader", options: { sourceMap: enabledSourceMap } } ] }] }, plugins: [ new FixStyleOnlyEntries(), new MiniCSSExtractPlugin({ filename: "./css/[name].css" }) ], devtool: "inline-source-map", });
ハマりポイント
- devtoolを付けないと、sourceMapが有効にならなかった。
- 本当は、foo.js foo.cssってしたかったんだけど、するとentryに同じキーになるのでできなかった。
- じゃあ、outputのfilenameでfoo.css/foo.jsってそれぞれ指定すればいいじゃんって思ったんだけど、そうするとエラーが出てうまくいかなかった。多分、CSSにする際に一旦JavaScriptを経由してて、そのJavaScriptのファイル名が被ってしまうせいだと思う。
- 環境変数NODE_ENVは、NODE_ENV=development ってpackage.jsonで指定しないといけなかったのを知らんかった。
これで、npm run prod/devで快適にSCSSとJavaScriptが書ける。・