I would like to compile all scss
file but without generating the extra js
file,currently my code structure is:
-public
-index.html
-login.html
-src
-index.js
-index.scss
-login.js
-login.scss
-test.scss
I want to generate in my dist folder like
-dist
-css
-login.xxxxxx.css
-index.xxxxxx.css
-test.xxxxxx.css
-index.xxxxxx.js
-index.html
-login.xxxxxx.js
-login.html
In my last thread, I get to know webpack-remove-empty-scripts and my webpack.config.js
like below.
npm install webpack-remove-empty-scripts --save-dev
'use strict';
const path = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const RemoveEmptyScriptsPlugin = require('webpack-remove-empty-scripts');
const fs = require("fs");
const scssFiles = fs.readdirSync("./src").filter(function (file) {
return file.match(/.*\.scss$/);
});
const scssEntries = scssFiles.map((filename) => {
const filenameWithoutExtension = filename.replace(/\.[^/.]+$/, "");
const entryName = filenameWithoutExtension;
return { [entryName]: "./src/" + filename };
});
const isDev = process.env.NODE_ENV === 'development';
const config = require('./public/config')[isDev ? 'dev' : 'build'];
module.exports = {
devtool: 'eval-cheap-module-source-map',
mode: isDev ? 'development' : 'production',
entry: {
index: './src/index.js',
login: './src/login.js',
...Object.assign({}, ...scssEntries)
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].[chunkhash:6].js',
publicPath: '/'
},
module: {
rules: [
{
test: /\.jsx?$/,
use: ['cache-loader','babel-loader'],
include: [path.resolve(__dirname, 'src')]
},
{
test: /\.(sc|sa|c)ss/,
use: [MiniCssExtractPlugin.loader, 'css-loader', 'sass-loader'],
include: [path.resolve(__dirname, 'src')]
// exclude: /node_modules/
},
{
test: /.html$/,
use: 'html-withimg-loader'
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: './public/index.html',
filename: 'index.html',
config: config.template,
minify: {
removeAttributeQuotes: false,
collapseWhitespace: false,
},
chunks: ['index']
}),
new RemoveEmptyScriptsPlugin(),
new MiniCssExtractPlugin({
filename: 'css/[name].[contenthash:6].css'
}),
]
}
If I do not use this plugin, it will generate three js file in dist. If I use it, my index.xxxxxx.js
and login.xxxxxx.js
are also be removed and there is no js file at all.
What is the problem?I want to keep js file generated by .js
of entry but remove js file generated by .scss
of entry.
the problem is with the usage of the webpack entry:
entry: {
index: './src/index.js',
login: './src/login.js',
...Object.assign({}, ...scssEntries) // <== HERE IS THE PROBLEM
},
This line ...Object.assign({}, ...scssEntries)
generate following:
{
index: './src/index.scss',
login: './src/login.scss'
}
Then two object will be merged via ...
.
But, this both objects have same keys: index
and login
, therefore last object, contained same keys but with .scss
files, override first object with .js
files.
The merging of:
entry: {
index: './src/index.js',
login: './src/login.js',
... { index: './src/index.scss', login: './src/login.scss' }
},
has the result:
entry: {
index: './src/index.scss',
login: './src/login.scss'
},
Use advanced syntax of webpack entry-point to define files with same basename
(filename without extention).
Change the webpack entry:
entry: {
index: './src/index.js', // => dist/index.xxxxxx.js
login: './src/login.js', // => dist/login.xxxxxx.js
// use uniq key in entry
indexCss: {
import: './src/index.scss',
filename: 'css/index.[contenthash:6].css' // => dist/css/index.xxxxxx.css
},
// use uniq key in entry
loginCss: {
import: './src/login.scss',
filename: 'css/login.[contenthash:6].css' // => dist/css/login.xxxxxx.css
}
},
Or other variant:
entry: {
index: './src/index.js', // => dist/index.xxxxxx.js
login: './src/login.js', // => dist/login.xxxxxx.js
// use uniq key in entry
'css/index': './src/index.scss',
// use uniq key in entry
'css/login': './src/login.scss'
},
In this case use
plugin: [
new MiniCssExtractPlugin({
filename: '[name].[contenthash:6].css', // <= remove `css/` from filename
}),
//...
]