I'm trying to take all the sass files in a particular folder, and copy/transform them into css files in a different folder, preserving the folder structure. Like:
into
I'm trying to use copy webpack plugin to copy all the src scss files, and the transform option to use node-sass to convert them, which seems to work, except it won't rename the files to .css and i can't figure how to fix this. Any ideas?
snip from my webpack.config.js:
{
context: path.join(__dirname, "src"),
from: "**/*.scss",
to: path.join(__dirname, "dest"),
transform(content, path) {
const result = sass.renderSync({ file: path });
return result.css.toString();
}
}
Transforming files by using webpack-copy-plugin
is not really a right way to process your assets. It is more like hackish/anti-pattern way. Instead you, should rely on proper loader pipeline. Webpack loaders are especially designed to handle this task. You need 4 things to accomplish you task.
sass-loader
.css-loade
r to convert CSS into CommonJS format.mini-css-extract-plugin
to extract CSS from JS code into actual CSS file.Your configuration would look like:
const path = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
output: {
// Whatever name pattern you need.
filename: `[name]/bundle-[contenthash].js`,
path: path.resolve(__dirname, 'dest')
},
entry: {
'folder1': './src/folder1/test1.scss',
'folder2': './src/folder2/test2.scss',
'folder2/folder3': './src/folder2/folder3/test3.scss'
},
modules: {
rules: [
{
test: /\.(sa|sc|c)ss$/,
use: [
// Mark content for extraction into seperate CSS file
MiniCssExtractPlugin.loader,
// Translates CSS into CommonJS
'css-loader',
// Compiles Sass to CSS
'sass-loader'
]
}
]
},
plugins: [
// Run the actual plugin to extract CSS into separate CSS files
new MiniCssExtractPlugin({
// Whatever name pattern you need
filename: `[name].css`
})
]
};
Adjust your filename
with the patterns you need.
Alternately, if you wish to stick to the same approach, the to
parameter of copy plugin configuration accepts the webpack style output patterns. Something similar can work for you:
// You can use .css instead of [ext]
to: '[path][name].[contenthash].[ext]'
Finally, as one last option, if there are too many SASS files, then you can dynamically construct the Webpack entry
object using glob package and then using that in your module configuration.