Webpack is not minimiziing my JavaScript files in production - javascript

Im new to react.js and currently working on a react.js project which runs 100% ok with development environment without any errors. After i build the project in production mode it will not minify my javascript files. But my scss files are get minified.
const path = require("path");
const CleanWebpackPlugin = require("clean-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const OptimizeCssAssetsPlugin = require("optimize-css-assets-webpack-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
mode: "production",
entry: {
main: "./src/index.js",
vendor: "./src/vendor.js",
},
output: {
filename: "[name].[contentHash].bundle.js",
path: path.resolve(__dirname, "dist"),
},
module: {
rules: [
{
test: /\.html$/,
use: ["html-loader"],
},
{
test: /\.(svg|png|jpg|gif)$/,
use: {
loader: "file-loader",
options: {
name: "[name].[hash].[ext]",
outputPath: "imgs",
},
},
},
{
test: /\.scss$/,
use: [MiniCssExtractPlugin.loader, "css-loader", "sass-loader"],
},
],
},
optimization: {
minimizer: [
new OptimizeCssAssetsPlugin(),
new HtmlWebpackPlugin({
template: __dirname + "/app/index.html",
minify: {
removeAttributeQuotes: true,
collapseWhitespace: true,
removeComments: true,
},
}),
],
},
plugins: [
new MiniCssExtractPlugin({ filename: "[name].[contentHash].css" }),
new CleanWebpackPlugin(),
],
};
Please someone help me to solve this problem and sorry for my bad English.

The default javascript minimizer plugin for webpack is TerserPlugin. When you setting minimizer attribute under the optimizaton, it will override the default values provided by webpack itself. To overcome this problem add TerserPlugin to your webpack.config.js file and pass it to the minimizer attribute.
const TerserPlugin = require("terser-webpack-plugin");
optimization: {
minimizer: [
new TerserPlugin(),
new OptimizeCssAssetsPlugin(),
new HtmlWebpackPlugin({
minify: {
removeAttributeQuotes: true,
collapseWhitespace: true,
removeComments: true,
},
}),
],
},

It seems like you only have minimization for your scss files, if you want to minify your javascript files aswell, you'll need a plugin such as Uglify, you just import it on the top and add it to the optimization.minimizer like it says in plugin page example:
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
module.exports = {
optimization: {
minimizer: [new UglifyJsPlugin()],
},
};

MiniCssExtractPlugin will extract your CSS into a separate file and It creates a CSS file per JS file which contains CSS. It won't minify your CSS files.
Import css-minimizer-webpack-plugin for minification. You can configure minification based on your environment.
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
const { getIfUtils } = require('webpack-config-utils')
const {ifProduction, ifNotProduction} = getIfUtils(process.env.NODE_ENV)
module.exports = {
module: {
loaders: [
{
test: /.s?css$/,
use: [MiniCssExtractPlugin.loader, 'css-loader', 'sass-loader'],
},
],
},
optimization: {
minimize: ifProduction(true, false),
minimizer: [
new CssMinimizerPlugin(),
],
},
};

Related

in webview, javascript module is not working..?

I tested lots of way to figure out why my javascript is not working :(
my guess is... javascript module is not working with webview. is it true? or is there any way to use javascript module?
any guess and answers would be appreciated. thanks in advance.
condition
I am using...
android
javascript
webpack
When webview is opened, I want the initialFucntion to be fired by itself.
// kotlin
Handler().post {
web_view_event.loadUrl("javascript:initialFunction('${userId}')")
}
this following code is working fine obviously.
// html codes...
<script>
function initialFucntion(userId){
alert(userId)
}
</script>
but...this following code is not working :(
// html code ...
<script src='test.js'></script>
<body>....
// test.js
function initialFucntion(userId){
alert(userId)
}
What shall I do? What did I miss? Any advice is welcome.
I have to use javascript module :/ since there's lots of code line more than this sample codes..
webpack code
const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const mode = process.env.NODE_ENV || 'development';
module.exports = {
mode: mode,
entry: {
main: ['./src/test.js', './src/main.css'],
infomation: ['./src/infomation.css'],
},
output: {
filename: '[name].js',
path: path.resolve('./dist'),
},
module: {
rules: [
{
test: /\.(scss|css)$/,
use: [MiniCssExtractPlugin.loader, 'css-loader', 'sass-loader'],
},
{
test: /\.(png|jpg|svg|gif)$/,
loader: 'url-loader',
options: {
name: '[name].[ext]?[hash]',
limit: 10000,
},
},
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader',
},
],
},
plugins: [
new webpack.BannerPlugin({
banner: `빌드 날짜: ${new Date().toLocaleString()}`,
}),
new HtmlWebpackPlugin({
filename: 'index.html',
excludeChunks: ['infomation'],
template: './src/index.html',
minify:
mode === 'production'
? {
collapseWhitespace: true, // 빈칸 제거
removeComments: true, // 주석 제거
}
: false,
hash: mode === 'production',
}),
new HtmlWebpackPlugin({
filename: 'infomation.html',
template: './src/infomation.html',
chunks: ['infomation'],
minify:
mode === 'production'
? {
collapseWhitespace: true, // 빈칸 제거
removeComments: true, // 주석 제거
}
: false,
hash: mode === 'production',
}),
new CleanWebpackPlugin(),
new MiniCssExtractPlugin({ filename: `[name].css` }),
],
};

MiniCSSExtractPlugin doesn't extract styles from definePlugin entries

I would like to divide my scss styles into chunks. Therefore, I created a separate subpage.scss imported by subpage.js file (one of the entries). I use miniCssExtractPlugin to extract SCSS styles from JS and create style bundles for each file. I map them in my BundleConfig to specific style chunks referenced in HTML.
The whole process works for the main.js and main.scss but not for subpage.js and subpage.scss - it leaves styles in .js file and the styles are loaded twice (both from JS and from HTML). The only difference between these cases is that the main.js is loaded as an entry in webpack.config.js and subpage.js is loaded with the remaining entries in webpack.DefinePlugin().
Any idea why MiniCssExtractPlugin doesn't extract the styles from a .js file loaded using this method and extracts styles for the main entry correctly?
My webpack.config.js
const readEntries = require('./entries');
const path = require('path');
const webpack = require('webpack');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const VueLoaderPlugin = require('vue-loader/lib/plugin');
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const entries = readEntries('../Scripts/entries');
module.exports = (mode) => ({
name: 'name',
context: path.resolve(__dirname, '../Scripts'),
resolve: {
extensions: ['.js', '.json', '.html', '.vue'],
alias: {
'~': path.resolve(__dirname, '../Scripts'),
'vue$': 'vue/dist/vue.esm.js',
'#trackers': path.resolve(__dirname, '../Scripts/trackers')
},
},
entry: {
main: './main.js',
},
output: {
path: path.resolve(__dirname, '../Content/bundle'),
publicPath: '/Content/bundle/',
filename: '[name].bundle.js',
chunkFilename: process.env.NODE_ENV === 'production' ? '[id].js?v=[contenthash]' : '[name].js?v=[contenthash]'
},
plugins: [
new CleanWebpackPlugin(),
new webpack.ProgressPlugin(),
new webpack.DefinePlugin({
'process.env': {
'ENTRIES': JSON.stringify(entries),
'NODE_ENV': JSON.stringify(mode)
}
}),
new VueLoaderPlugin(),
new MiniCssExtractPlugin({
filename: '[contenthash].[name].bundle.css',
}),
new BundleAnalyzerPlugin({
openAnalyzer: false,
analyzerMode: 'static'
})
],
module: {
rules: [
{
test: require.resolve('vue'),
use: [
{
loader: `expose-loader`,
options: 'Vue'
}
]
},
{
test: /\.vue$/,
loader: 'vue-loader'
},
{
test: /\.(js)$/,
use: [
'babel-loader'
],
exclude: /node_modules/
},
{
test: /\.(png|jpg|gif|svg)$/,
loader: 'file-loader',
options: {
name: '[name].[ext]?[contenthash]'
}
},
{
test: /\.(sa|sc|c)ss$/,
use: [
{
loader: MiniCssExtractPlugin.loader
},
'css-loader',
'postcss-loader',
'sass-loader'
]
}
]
},
optimization: {
splitChunks: {
chunks: 'async'
}
},
performance: {
hints: false
},
externals: {
jquery: 'jQuery',
DM: 'DM'
},
stats: {
modules: false
},
target: 'web'
});
my BundleConfig:
public class BundleConfig
{
public static void RegisterBundles(BundleCollection bundles)
{
bundles.IgnoreList.Clear();
BundleTable.EnableOptimizations = true;
bundles.Add(new ScriptBundle("~/bundles/js/head").Include(
"~/Scripts/head.js"
));
bundles.Add(new Bundle("~/bundles/js/scripts").Include(
"~/Content/bundle/main.bundle.js"
));
bundles.Add(new StyleBundle("~/bundles/css/main").Include(
"~/Content/bundle/*main.bundle.css"
));
bundles.Add(new StyleBundle("~/bundles/css/trends").Include(
"~/Content/bundle/*trends.bundle.css"
));
}
}

how to make webpack import polyfills only for a specific build?

I just managed to make webpack create two separete builds one for es5 and another for es6.
See below the config file:
const path = require("path");
const common = require("./webpack.common");
const merge = require("webpack-merge");
const CleanWebpackPlugin = require("clean-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const OptimizeCssAssetsPlugin = require("optimize-css-assets-webpack-plugin");
const TerserPlugin = require("terser-webpack-plugin");
var HtmlWebpackPlugin = require("html-webpack-plugin");
const es5Config = merge(common,{
mode: "production",
output: {
filename: "[name].[contentHash].bundle.es5.js",
path: path.resolve(__dirname, "dist")
},
optimization: {
minimizer: [
new OptimizeCssAssetsPlugin(),
new TerserPlugin(),
new HtmlWebpackPlugin({
template: "./src/template.html",
minify: {
removeAttributeQuotes: true,
collapseWhitespace: true,
removeComments: true
}
}),
]
},
plugins: [
new MiniCssExtractPlugin({ filename: "[name].[contentHash].css" }),
new CleanWebpackPlugin(),
],
module: {
rules: [
{
test: /\.scss$/,
use: [
MiniCssExtractPlugin.loader, //3. Extract css into files
"css-loader", //2. Turns css into commonjs
"sass-loader" //1. Turns sass into css
]
},
{
test: /\.m?js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: [
['#babel/preset-env', {
modules: false,
useBuiltIns: 'entry',
targets: {
browsers: [
"IE 11"
],
},
}],
],
},
},
}],
},
});
const es6Config = merge(common, {
mode: "production",
output: {
filename: "[name].[contentHash].bundle.es6.js",
path: path.resolve(__dirname, "dist")
},
optimization: {
minimizer: [
new OptimizeCssAssetsPlugin(),
new TerserPlugin(),
new HtmlWebpackPlugin({
template: "./src/template.html",
minify: {
removeAttributeQuotes: true,
collapseWhitespace: true,
removeComments: true
}
}),
]
},
plugins: [
new MiniCssExtractPlugin({ filename: "[name].[contentHash].css" }),
new CleanWebpackPlugin(),
],
module: {
rules: [
{
test: /\.scss$/,
use: [
MiniCssExtractPlugin.loader, //3. Extract css into files
"css-loader", //2. Turns css into commonjs
"sass-loader" //1. Turns sass into css
]
},
{
test: /\.m?js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: [
['#babel/preset-env', {
modules: false,
useBuiltIns: "usage",
targets: {
browsers: [
'Chrome >= 60',
'Safari >= 10.1',
'iOS >= 10.3',
'Firefox >= 54',
'Edge >= 15',
],
},
}],
],
},
},
}],
},
});
module.exports = [es5Config, es6Config];
The issue is now that I wanted webpack to import the polyfills only for the es5 build. and use usebuilins set to usage did not work to polyfill anything.
Am I probably using it wrong maybe something related to the the node_modules package??
So I am just importing the polyfills in the main file like:
import "core-js/stable";
import "regenerator-runtime/runtime";
How can I make these imports to be added only for the es5 build? Or how can I include polyfills/imports from webpack?
And extra question if anyone knows, how can I use the usebuiltins with "usage" correctly? Cause so far even thought the polifylls are added for my main file I still get errors for Symbols in IE11, for example.
I figured it out. here is the webpack config:
common:
const path = require("path");
module.exports = {
entry: {
main: "./src/index.js",
vendor: "./src/vendor.js"
},
module: {
rules: [
{
test: /\.html$/,
use: ["html-loader"]
},
{
test: /\.(svg|png|jpg|gif)$/,
use: {
loader: "file-loader",
options: {
name: "[name].[hash].[ext]",
outputPath: "imgs"
}
}
}
]
}
};
prod:
const path = require("path");
const common = require("./webpack.common");
const merge = require("webpack-merge");
const CleanWebpackPlugin = require("clean-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const OptimizeCssAssetsPlugin = require("optimize-css-assets-webpack-plugin");
const TerserPlugin = require("terser-webpack-plugin");
var HtmlWebpackPlugin = require("html-webpack-plugin");
const { BundleAnalyzerPlugin } = require("webpack-bundle-analyzer");
const es5Config = merge(common,{
mode: "production",
output: {
filename: "[name].[contentHash].bundle.es5.js",
path: path.resolve(__dirname, "dist")
},
optimization: {
runtimeChunk: 'single',
splitChunks: {
chunks: 'all',
maxInitialRequests: Infinity,
minSize: 0,
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/,
name: (module) => {
// get the name. E.g. node_modules/packageName/not/this/part.js
// or node_modules/packageName
const packageName = module.context.match(/[\\/]node_modules[\\/](.*?)([\\/]|$)/)[1];
// npm package names are URL-safe, but some servers don't like # symbols
return `npm.${packageName.replace('#', '')}`;
},
},
},
},
minimizer: [
new OptimizeCssAssetsPlugin(),
new TerserPlugin(),
new HtmlWebpackPlugin({
filename: 'main.aspx',
template: "./src/main.html",
// minify: {
// removeAttributeQuotes: true,
// collapseWhitespace: true,
// removeComments: true
// }
}),
]
},
plugins: [
new MiniCssExtractPlugin({ filename: "[name].[contentHash].css" }),
new CleanWebpackPlugin(),
new BundleAnalyzerPlugin(),
],
module: {
rules: [
{
test: /\.scss$/,
use: [
MiniCssExtractPlugin.loader, //3. Extract css into files
"css-loader", //2. Turns css into commonjs
"sass-loader" //1. Turns sass into css
]
},
{
test: /\.m?js$/,
exclude: /node_modules/,
//exclude: /node_modules\/(?!(\#pnp)\/).*/,
use: {
loader: 'babel-loader',
options: {
//configFile : './es5.babel.config.json',
presets: [
['#babel/preset-env', {
modules: false,
useBuiltIns: false,
targets: {
browsers: [
"IE 11"
],
},
}],
],
},
},
}],
},
});
const es6Config = merge(common, {
mode: "production",
output: {
filename: "[name].[contentHash].bundle.es6.js",
path: path.resolve(__dirname, "dist")
},
optimization: {
runtimeChunk: 'single',
splitChunks: {
chunks: 'all',
maxInitialRequests: Infinity,
minSize: 0,
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/,
name: (module) => {
// get the name. E.g. node_modules/packageName/not/this/part.js
// or node_modules/packageName
const packageName = module.context.match(/[\\/]node_modules[\\/](.*?)([\\/]|$)/)[1];
// npm package names are URL-safe, but some servers don't like # symbols
return `npm.${packageName.replace('#', '')}`;
},
},
},
},
minimizer: [
new OptimizeCssAssetsPlugin(),
new TerserPlugin(),
new HtmlWebpackPlugin({
filename: 'main_es6.html',
template: "./src/main.html",
// minify: {
// removeAttributeQuotes: true,
// collapseWhitespace: true,
// removeComments: true
// }
}),
]
},
plugins: [
new MiniCssExtractPlugin({ filename: "[name].[contentHash].css" }),
new CleanWebpackPlugin(),
],
module: {
rules: [
{
test: /\.scss$/,
use: [
MiniCssExtractPlugin.loader, //3. Extract css into files
"css-loader", //2. Turns css into commonjs
"sass-loader" //1. Turns sass into css
]
},
],
},
});
module.exports = [ es5Config, es6Config];
babel.config.json:
{
"plugins": [
[
"#babel/plugin-transform-runtime",
{
"absoluteRuntime": true,
"helpers": true,
"regenerator": true,
"useESModules": false
}
]
]
}
so this combined with the cdn polyfill works to load the polifylls only for IE11. it also has it's own build.
The only issue here is that the resulting output will have separated files and the es5 build should have nomodule in all it's scripts. Also for the es6 all should have module.
I then have to go and manually add those which I can easily make a custom template to handle that.
But then the scripts for the polyfill is removed and I still have to manually merge the html files. Anyone knows how to handle that?
edit:
1 - for the attributes you can use HtmlWebpackPlugin hooks () or ScriptExtHtmlWebpackPlugin to place the attributes in the tags.
find some code with hooks here:
const HtmlWebpackPlugin = require('html-webpack-plugin');
class es5TagTransformerHook {
apply (compiler) {
compiler.hooks.compilation.tap('MyPlugin', (compilation) => {
HtmlWebpackPlugin.getHooks(compilation).alterAssetTagGroups.tapAsync(
'es5TagTransformerHook', stacktraces
async (data, cb) => {
// Manipulate the content
// data.html += 'The Magic Footer'
// Tell webpack to move on
data.bodyTags.forEach(t=>t.tagName === 'script'?t.attributes.nomodule = true:null)
cb(null, data)
}
)
})
}
}
module.exports = es5TagTransformerHook
2 - for merging the resulting html I ended up using this gist:
https://gist.github.com/agoldis/21782f3b9395f78d28dce23e3b6ddd56

Large console output produced by mini-css-extract-plugin

Been trying to research this but it doesn't seem as if any else has this, or see this as an issue.
I am using mini-css-extract-plugin(MiniCssExtractPlugin) in my webpack.config.js.
However, when I run webpack the console is littered with hundreds of instances of something similar to this...
Child mini-css-extract-plugin ../../../node_modules/css-loader/index.js??ref--6-1!../../../node_modules/postcss-loader/src/index.js!../../../node_modules/sass-loader/lib/loader.js!ui/radiolist-toggler/RadioListToggler.scss:
Entrypoint mini-css-extract-plugin = *
[../../../node_modules/css-loader/index.js?!../../../node_modules/postcss-loader/src/index.js!../../../node_modules/sass-loader/lib/loader.js!./ui/radiolist-toggler/RadioListToggler.scss] /Users/~~~/git/user-section/node_modules/css-loader??ref--6-1!/Users/~~~/git/user-section/node_modules/postcss-loader/src!/Users/~~/git/user-section/node_modules/sass-loader/lib/loader.js!./ui/radiolist-toggler/RadioListToggler.scss 5.33 KiB {mini-css-extract-plugin} [built]
+ 1 hidden module
I need to scroll up for a good few seconds to be able to see all my assets etc.
I am pretty new to webpack, so not exactly sure how to prevent this from being output to the console?
Below is my webpack.config.js
const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const OptimizeCssAssetsPlugin = require("optimize-css-assets-webpack-plugin");
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
const modernizr = require("modernizr");
const CopyWebpackPlugin = require('copy-webpack-plugin');
const CompressionPlugin = require('compression-webpack-plugin');
module.exports = {
context: path.resolve(__dirname, 'src/main/client'),
entry: './index',
devtool: 'cheap-module-source-map',
optimization: {
minimizer: [
new UglifyJsPlugin({
cache: true,
parallel: true,
uglifyOptions: {
mangle: true,
compress: true,
ecma: 6
},
sourceMap: true
}),
new OptimizeCssAssetsPlugin({}),
],
splitChunks: {
chunks: 'all'
}
},
plugins: [
new CompressionPlugin({
test: /\.js$|\.css$|\.html$|\.(png|svg|jpg|gif)$/,
cache: true,
filename: '[path].gz[query]',
algorithm: 'gzip',
threshold: 10240
}),
new CleanWebpackPlugin([
'./target/webapp'
]),
new HtmlWebpackPlugin({
template: './index.html',
filename: '../index.html',
xhtml: true
}),
new MiniCssExtractPlugin({
filename: "[name].css",
}),
new CopyWebpackPlugin([{
from: '../webapp/**/*',
to: '../'
}]),
new webpack.DefinePlugin({
'process.env.NODE_ENV': '"production"'
}),
],
output: {
publicPath: '/app/',
filename: '[name].bundle.js',
chunkFilename: '[id].js',
path: path.resolve(__dirname, 'target/webapp/app/')
},
module: {
rules: [{
loader: "webpack-modernizr-loader",
test: /\.modernizrrc\.js$/
},
{
test: /\.html$/,
exclude: /node_modules/,
use: {
loader: 'html-loader'
}
},
{
test: /\.s?css$/,
use: [
MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
options: {
importLoaders: 1
}
},
{
loader: 'postcss-loader'
},
{
loader: 'sass-loader'
}
]
},
{
test: /\.(png|svg|jpg|gif)$/,
use: [
'file-loader'
]
},
{
test: /\.(woff|woff2|eot|ttf|otf)$/,
use: [{
loader: 'file-loader',
options: {
name: '[name].[ext]',
outputPath: './assets/fonts/'
}
}]
},
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
loader: "babel-loader",
options: {
presets: ["#babel/env"]
}
}
],
},
resolve: {
alias: {
// You can add comment "Please do not delete this file" in this file
modernizr$: path.resolve(__dirname, "./.modernizrrc.js")
}
}
}
#mcclosa mentioned this as a comment but in case anyone should look at this question, see no answer and click away, the solution is to add the stats option to your webpack.config.js file as follows:
module.exports = {
stats: { children: false },
}
The above option uses the children: false option suggested by #mcclosa, which does successfully remove the junk output by mini-css-extract-plugin, but I find using the preset stats: "minimal" produces a much nicer overall output. Using:
module.exports = {
stats: "minimal",
}
..gives me the following tiny output whenever my build has no errors:
i 「wdm」: Compiling...
i 「wdm」: 69 modules
i 「wdm」: Compiled successfully.
..as opposed to dozens of lines of useless build data, but it will continue to give give error information when errors are present.
Unfortunately, mini-css-extract-loader does not have a setting to control the verbosity of its log output.
Setting stats.children to false or "minimal" in your webpack.config.js can remove a lot of other useful output like your bundle names and sizes, entry point information, time taken to build, legitimate warnings and errors from other plugins that you may want to keep, etc.
Instead it seems that we must add a plugin that executes on the compiler's done hook to remove items from the stats.compilation object associated with mini-css-extract-plugin.
This example plugin should work:
class CleanupMiniCssExtractPlugin {
apply(compiler) {
compiler.hooks.done.tap("CleanupMiniCssExtractPlugin", stats => {
if (this._children) {
const children = stats.compilation.children;
if (Array.isArray(children)) {
stats.compilation.children = children.filter(
child => child.name.indexOf("mini-css-extract-plugin") == -1
);
}
}
});
}
}
Or you can use this npm package: https://www.npmjs.com/package/cleanup-mini-css-extract-plugin

Webpack 2 - Suppress chunk files

As we are putting this output on a load balancer (not using sticky), we need to place the output of these files without chunks (neither hashes).
These are the main two files for webpack configuration.
webpack.common.js
const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const helpers = require('./helpers');
const STATIC_TRANSLATION_MAP = require('../TranslationMap.json');
module.exports = {
entry: {
app: ['./src/public/main.ts'],
vendor: './src/public/vendor.ts',
polyfills: './src/public/polyfills.ts'
},
output: {
path: helpers.root('dist/public')
},
module: {
rules: [
{
test: /\.ts$/,
loaders: ['awesome-typescript-loader', 'angular2-template-loader', 'angular2-router-loader']
},
{
test: /\.html$/,
loader: 'html-loader?-minimize'
},
{
test: /\.(png|jpe?g|gif|svg|woff|woff2|ttf|eot|ico)$/,
loader: 'file-loader?name=assets/[name].[ext]'
},
{
test: /\.styl$/,
include: helpers.root('src', 'public', 'app'),
use: [
'raw-loader',
'stylus-loader'
]
},
{
test: /\.styl$/,
include: helpers.root('src', 'public'),
exclude: helpers.root('src', 'public', 'app'),
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: [
'css-loader',
'stylus-loader'
]
})
},
{
test: /\.css$/,
include: helpers.root('src', 'public', 'assets', 'css'),
loader: 'raw-loader'
},
{
test: /\.xlf$/,
loader: 'raw-loader'
}
]
},
resolve: {
extensions: ['.webpack.js', '.web.js', '.ts', '.js'],
alias: {}
},
plugins: [
new webpack.optimize.CommonsChunkPlugin({
name: ['app', 'vendor', 'polyfills']
}),
new HtmlWebpackPlugin({
template: 'src/public/index.html'
}),
new webpack.DefinePlugin({
'process.env': {
'LOCALE_LIST': JSON.stringify(Object.keys(STATIC_TRANSLATION_MAP))
}
})
]
};
webpack.prod.js
const webpack = require('webpack');
const webpackMerge = require('webpack-merge');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const commonConfig = require('./webpack.common.js');
const helpers = require('./helpers');
const prodEnv = 'production';
module.exports = webpackMerge(commonConfig, {
devtool: 'source-map',
output: {
filename: '[name].js',
chunkFilename: '[name].js'
},
plugins: [
new webpack.NoEmitOnErrorsPlugin(),
new webpack.optimize.UglifyJsPlugin({
mangle: {
keep_fnames: true
}
}),
new webpack.LoaderOptionsPlugin({
htmlLoader: {
minimize: false
}
}),
new ExtractTextPlugin('[name].css'),
new webpack.DefinePlugin({
'process.env': {
'ENV': JSON.stringify(prodEnv)
}
})
]
});
But for my surprise, I noticed webpack is producing extra files. Can you see those ones with numbers? (From 0 to 19). I'm not sure from where they're coming from, and every content of those starts with webpackJsonp.
Is there a way to disable this chunk feature and just produce the three files from entry?
What is happening?
But for my surprise, I noticed webpack is producing extra files. Can you see those ones with numbers? (From 0 to 19)
output.chunkFilename
This option determines the name of non-entry chunk files.
By default [id].js is used or a value inferred from output.filename (name is replaced with id):
Non-entry chunks (external)
./dist/[0].js
./dist/[1].js
./dist/[2].js
./dist/[3].js
...
Entry-chunks from webpack.config.entry
./dist/app.js
./dist/vendor.js
...
How to fix it?
Currently CommonChunkPlugin only receives modules imported from entry chunks.
webpack/issues/4392
Workarounds / hacks
This concept may be used to obtain implicit common vendor chunks:
new webpack.optimize.CommonsChunkPlugin({
name: "vendor",
minChunks: function (module) {
// this assumes your vendor imports exist in the node_modules directory
return module.context && module.context.indexOf("node_modules") !== -1;
}
})
Passing the minChunks property a function
webpack/issues/2855#issuecomment-239606760
https://stackoverflow.com/a/39401288/6836839

Categories