Webpack/grunt-webpack , stop logging on prod build task - javascript

I have a webpack grunt task building my app for me. It's been working great, however I notices my jenkins job logs a huge blob of text from the prod buil (specifically the webpack part), and I'm looking into if i can fix that.
The problem is it logs out this :
...0% compile 10% 0/1 build modules 70% 1/1 build modules 40% 1/2 build modules 30% 1/3...
I cut this short, its around 600 modules, so the text block is gigantic.
From googling around I found something, and tried to add this to my prod webpack file
stats: {
assets: false,
colors: true,
modules: false,
version: false,
hash: false,
timings: false,
chunks: false,
chunkModules: false
},
However, this did not seem to work. I found this thread which seemed to be the right direction https://github.com/webpack/webpack/issues/476 , however I could not get any of those suggested fixes to work. I am using grunt-webpack, and just incase it may help, here is my prod task :
return {
prod: {
entry: {
index: './client/app.jsx'
},
output: {
path: path.join(__dirname, '../client'),
publicPath: "/client/",
filename: 'bundle.js'
},
module: {
loaders: [{
test: /\.jsx?$/,
exclude: /node_modules/,
loader: 'babel-loader'
}]
},
resolve: {
extensions: ['', '.js', '.jsx']
},
stats: {
assets: false,
colors: true,
modules: false,
version: false,
hash: false,
timings: false,
chunks: false,
chunkModules: false
},
plugins: [
new webpack.DefinePlugin({
"process.env": {
"NODE_ENV": JSON.stringify("production")
}
}),
new webpack.optimize.DedupePlugin(),
new webpack.optimize.UglifyJsPlugin()
]
}
}
I am just trying to change it so the prod task doesn't everything, if it just said something like 'build complete' that would be ideal. Is there any way to accomplish this? Thanks!

Related

Webpack code splitting impacts web performance

I have a React/Node + SSR application, I am trying to create a production build, I have managed to do that but the problem is that the files that I have in the build are too large.
I use latest version of react + webpack 4.
Here is my webpack configuration:
clientConfig.js
const path = require('path');
const common = require('./webpack.common-config');
const clientConfig = {
...common,
mode: 'production',
name: 'client',
target: 'web',
devtool: false,
entry: {
client: [
'#babel/polyfill',
'./src/client.js'
],
},
output: {
path: path.resolve(__dirname, 'build'),
filename: '[name].js',
},
optimization: {
splitChunks: {
cacheGroups: {
vendor: {
chunks: 'all',
name: 'vendor',
test: module => /node_modules/.test(module.resource),
enforce: true
},
common: {
chunks: 'all',
name: 'client'
}
},
},
},
node: {
fs: 'empty',
net: 'empty',
tls: 'empty',
}
};
module.exports = clientConfig;
serverConfig.js
const nodeExternals = require('webpack-node-externals');
const path = require('path');
const common = require('./webpack.common-config');
const serverConfig = {
...common,
mode: 'production',
name: 'server',
target: 'node',
devtool: false,
externals: [nodeExternals()],
entry: {
server: ['#babel/polyfill', path.resolve(__dirname, 'src', 'server.js')],
},
optimization: {
splitChunks: {
chunks: 'all',
}
},
output: {
path: path.resolve(__dirname, 'build'),
filename: '[name].js',
chunkFilename: "[id].chunk.js"
},
node: {
console: false,
global: false,
process: false,
Buffer: false,
__filename: false,
__dirname: false,
},
};
module.exports = serverConfig;
commonConfig.js
const path = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const TerserPlugin = require('terser-webpack-plugin');
const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin");
const common = {
module: {
rules: [
{
test: /\.jsx?$/,
loader: 'babel-loader',
include: [path.resolve(__dirname, 'src')],
query: {
presets: [
['#babel/preset-env', {loose: true, modules: false}],
"#babel/preset-react"
],
plugins: [
"#babel/plugin-proposal-class-properties"
]
},
},
{
test: /\.css$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
},
'css-loader'
]
},
{
test: /\.(woff(2)?|ttf|eot|svg)(\?v=\d+\.\d+\.\d+)?$/,
use: [
{
loader: 'file-loader',
options: {
name: '[name].[ext]',
outputPath: 'fonts/'
}
}
]
}
]
},
plugins: [
new OptimizeCSSAssetsPlugin(),
new MiniCssExtractPlugin({
filename: "styles.css",
})
],
optimization: {
minimize: true,
minimizer: [new TerserPlugin()]
},
};
module.exports = common;
And another file which basically merges the client and the server config.
I run npm run build after that I run webpack -p --mode=production --optimize-minimize && node ./build/server.js
I get the following warning:
WARNING in asset size limit: The following asset(s) exceed the recommended size limit (244 KiB).
This can impact web performance.
Assets:
vendor.js (667 KiB)
WARNING in entrypoint size limit: The following entrypoint(s) combined asset size exceeds the recommended limit (244 KiB). This can impact web performance.
Entrypoints:
client (928 KiB)
vendor.js
styles.css
client.js
Any advice or idea for the above size warning would be great! Thank you!
I recommend that you try core-js instead of babel/pollyfill this can help you to reduce your bundle size.
Also, I recommend that you try dynamic importing with react-loadable which supports SSR. there are different strategies for splitting your code. you can read more here(most important one)
In case you are using CSS frameworks such as bootstrap you should only use parts that you need and avoid importing all of them. there is a tool for purging unused CSS named purgecss but use it with caution and you have to know what are you doing.
In case you are using libraries such as lodash or material-ui you should import your module specifically to avoid importing all the packages into your bundle.
exp:
import debounce from 'lodash/debounce'
npm dedup or yarn dedup can help to remove duplicate dependencies inside bundle.
You may be able to get some reduction through adjusting your babel configuration. For instance, specifying some options for the "preset-env", such as bugfixes, targets if you don't have support older browsers, and using corejs polyfills instead of babel/polyfill.
"#babel/preset-env", {
"targets": {
"browsers": [
"last 2 years"
]
},
"bugfixes": true,
"useBuiltIns": "entry", // experiment with "entry" vs. "usage"
"corejs": 3
...
Depending on your codebase, the babel-plugin-transform-runtime may help too. I had some projects where it made a substantial difference, but other where it hasn't.
"#babel/plugin-transform-runtime",
{
"corejs": 3,
"version": "7.9.2"
}
Additional options for Webpack include using the webpack-cdn-plugin. This can greatly reduce your vendor bundle size. Of course, users will still have to download those same libraries, but they will be cached and don't need to re-downloaded every time your bundle changes or updates.
A little additional savings can be had by specifying runtimeChunk: true, and optionally inlining that chunk in your index.html with
new HTMLWebpackPlugin({
inlineSource: 'runtime~.+[.]js',
...
and the html-webpack-inline-source-plugin or similar.
You can split files to lower size to remove warning using splitChunks:
optimization: {
splitChunks: {
chunks: 'all',
minSize: 10000,
maxSize: 250000,
}
}
Check more for minSize and maxSize.
If you want to disable the warning, you can do it using performance
performance: {
hints: false
}
or remove warning for certain size limit like 1 MB:
performance: {
maxAssetSize: 1000000
}
I managed to switch to Next.js so all of this is not necessary anymore.

Webpack Tree-Shaking Dynamic Imports seems not to be working

History:
I recently discovered an odd behaviour with using Webpack and dynamic imports. First I thought it might be the 3rd-party library 'Loadable Components' I used, so I opened a bug issue (https://github.com/gregberge/loadable-components/issues/517) on their end. The author replied telling me that the behaviour is coming from Webpack and the dynamic imports themselves.
I can stand the fact that it does not tree-shake the dynamic import, for me it is more important to understand why that is the case.
Demo repository to demonstrate the behaviour can be found here: https://github.com/dazlious/treeshaking-dynamic-imports
Short description of the problem: From my perspective, an imported named export should not force all the exported code to be bundled within it.
In the demo case we have a component (./lib/index.jsx) that has two sub components called module1 (./lib/module1/module1.jsx) and module2 (./lib/module1/module2.jsx). Module1 exports a constant called FOO_BAR that is then imported by Module2 as a named import.
When looking at the build output, you'll find Module2 containing Module1 in whole and not only the string that is specifically imported.
Is anyone with deep knowledge of Webpack and/or dynamic imports around here? Would be happy to learn more about the behaviour.
I edited the webpack.config to be:
const path = require('path');
const TerserPlugin = require('terser-webpack-plugin');
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');
const baseDir = path.resolve(__dirname);
const config = {
mode: process.env.NODE_ENV,
stats: 'minimal',
resolve: {
extensions: ['.js', '.jsx'],
symlinks: false,
},
plugins: [
new BundleAnalyzerPlugin({
analyzerMode: 'static',
openAnalyzer: false,
reportFilename: 'analyze.html',
}),
],
target: 'web',
devtool: 'hidden-source-map',
entry: {
bundle: [path.resolve(baseDir, 'lib')],
},
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
parallel: true,
}),
],
mangleWasmImports: true,
splitChunks: {
cacheGroups: {
default: false,
vendors: false,
vendor: {
name: 'vendor',
chunks: 'all',
test: /node_modules/,
priority: 20
},
common: {
name: 'common',
minChunks: 2,
chunks: 'all',
priority: 10,
reuseExistingChunk: true,
enforce: true
}
}
},
},
output: {
chunkFilename: '[name].[chunkhash].js',
publicPath: '/',
path: path.join(baseDir, 'dist'),
filename: '[name].[hash].js',
},
module: {
rules: [
{
test: /^.*\.jsx?$/,
include: [path.resolve(baseDir, 'lib')],
loader: 'babel-loader?cacheDirectory',
},
{
test: /\.mjs$/,
include: /node_modules/,
type: 'javascript/auto',
},
],
},
};
module.exports = config;
I think this has the result you are looking for?
image of bunde analyzer showing modules in their own bundles
I think it requires the splitChunks option to actually tree-shake the components properly.
I have spend a lot of time trying to figure webpack out, but I'm still guessing here.

Webpack Dev Server Not Hot Reloading .vue files

Been working on a project and was sure HMR was working, any of my .js files if I would update them webpack would compile and the module would be replaced all hot like.
I was working on a .vue file and webpack would recompile, but there was no super fresh HMR.
Hoping someone can take a look and tell me if something is off:
The script I'm using in the cli looks like this.
webpack-dev-server --d --watch --output-path ./public --config ./_src/webpack.config.js --progress --env.dev
I'm guessing the most important bit to look at is this:
devServer: {
contentBase: 'public',
hot: true,
filename: 'main.js',
overlay: true,
stats: { colors: true },
port: 3000,
proxy: {
'/': {
target: 'http://moment.local/',
secure: false,
changeOrigin: true
}
},
historyApiFallback: true
},
But here is my whole config if it helps.
const webpack = require('webpack')
const {resolve} = require('path')
const ExtractTextPlugin = require('extract-text-webpack-plugin')
module.exports = env => {
const addPlugin = (add, plugin) => add ? plugin : undefined
const ifProd = plugin => addPlugin(env.prod, plugin)
const removeEmpty = array => array.filter(i => !!i)
// Our Sass Extraction Plugin
const extractSass = new ExtractTextPlugin({
filename: 'style.css',
disable: env.dev
})
return {
entry: {
'vendor': ['jquery', 'KlaviyoSubscribe', 'learnq', 'select2', 'slick-carousel', 'moment', 'lodash'],
'main': resolve(__dirname, './js/index.js')
},
output: {
filename: '[name].js',
path: resolve(__dirname, '../public/'),
pathinfo: !env.prod
},
module: {
loaders: [
{
test: /\.vue$/,
loader: 'vue-loader',
options: {
loaders: {
css: 'vue-style-loader!css-loader!postcss-loader!sass-loader', // <style lang='scss'>
scss: 'vue-style-loader!css-loader!postcss-loader!sass-loader', // <style lang='scss'>
sass: 'vue-style-loader!css-loader!postcss-loader!sass-loader?indentedSyntax' // <style lang='sass'>
}
}
},
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader'
},
{ test: /\.s(c|a)ss$/,
use: extractSass.extract({
fallback: 'style-loader',
use: [
{
loader: 'css-loader',
options: {
importLoaders: 1,
sourceMap: true
}
},
'postcss-loader?sourceMap',
'sass-loader?sourceMap'
]
})
},
{
test: /\.(png|jpg|gif|svg)$/,
loader: 'file-loader',
options: {
name: '[name].[ext]?[hash]'
}
}
]
},
devtool: env.prod ? 'source-map' : 'eval',
devServer: {
contentBase: 'public',
hot: true,
filename: 'main.js',
overlay: true,
stats: { colors: true },
port: 3000,
proxy: {
'/': {
target: 'http://moment.local/',
secure: false,
changeOrigin: true
}
},
historyApiFallback: true
},
bail: env.prod, // Fail out on the first error if production
resolve: {
alias: {
'vue$': 'vue/dist/vue.common.js'
}
},
plugins: removeEmpty([
extractSass,
new webpack.HotModuleReplacementPlugin(),
new webpack.optimize.CommonsChunkPlugin({
// Let's create js for our vendor scripts
name: 'vendor',
// (with more entries, this ensures that no other module
// goes into the vendor chunk)
minChunks: Infinity
}),
new webpack.optimize.CommonsChunkPlugin({
name: 'commons',
filename: 'commons.js',
// (Modules must be shared between 2 entries)
minChunks: 2
})
...
])
}
}
Really struggling here so anything would be great.
It sounds like you want the "hot" behaviour but you are missing the --hot option in the script you posted. The documentation for that option is here.
You have a lot of options already; just add --hot and that should do the trick.
UPDATE:
I do see that you have the hot: true set in the devServer property of your webpack config, but if I don't use --hot in the cli, I get the following error in the console, so that is why I am saying to use it even though you would think it would be covered by the config - its not.
Uncaught Error: [HMR] Hot Module Replacement is disabled.
Add a file called vue.config.js in your root directory.
Inside it you can enable hot reloading via:
module.exports = {
devServer: {
watchOptions: {
poll: true
}
}
};
I used this settings in a project that was set up via vue create.

Unexpected Token error using UglifyJS with Preact, Webpack 2

I'm building a Chrome extension with Preact/ES6/Webpack. I pack using one of 2 configurations: debug uses ESLint, Babel and CSS + JSON loaders, prod adds 2 plugins: UglifyJS and Zip. Here's the webpack.config.js:
const webpack = require('webpack');
const path = require('path');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const WebpackCleanupPlugin = require('webpack-cleanup-plugin');
const ZipPlugin = require('zip-webpack-plugin');
const manifest = require('./src/manifest');
let options = {
// entry file - starting point for the app
entry: {
popup: './src/scripts/popup.js',
options: './src/scripts/options.js',
background: './src/scripts/background.js'
},
// where to dump the output of a production build
output: {
path: path.join(__dirname, 'build'),
filename: 'scripts/[name].js'
},
module: {
rules: [
{
test: /\.jsx?/i,
exclude: /node_modules/,
loader: 'eslint-loader',
options: {
},
enforce: 'pre'
},
{
test: /\.jsx?/i,
exclude: /node_modules/,
loader: 'babel-loader',
options: {
presets: [
['env', {
'targets': {
'chrome': 52
}
}]
],
plugins: [
['transform-react-jsx'],
['module-resolver', {
'root': ['.'],
'alias': {
'react': 'preact-compat',
'react-dom': 'preact-compat'
}
}]
]
}
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
},
{
test: /\.json$/,
use: 'json-loader'
}
]
},
plugins: [
new WebpackCleanupPlugin(),
new CopyWebpackPlugin([
{from: './src/_locales', to: '_locales'},
{from: './src/icons', to: 'icons'},
{from: './src/manifest.json', flatten: true},
{from: './src/*.html', flatten: true}
])
],
// enable Source Maps
devtool: 'source-map',
};
if(process.env.NODE_ENV === 'production') {
options.plugins.push(
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false,
drop_console: false,
screw_ie8: true,
conditionals: true,
unused: true,
comparisons: true,
sequences: true,
dead_code: true,
evaluate: true,
if_return: true,
join_vars: true,
},
output: {
comments: false,
},
}),
new ZipPlugin({
path: '../dist',
filename: `${manifest.name} ${manifest.version}.zip`
})
);
}
console.log(`This is a ${process.env.NODE_ENV === 'production' ? 'production' : 'development'} build with ${options.plugins.length} plugins`);
module.exports = options;
But when I run the prod, I get the following errors:
ERROR in scripts/popup.js from UglifyJs
Unexpected token: name (getLatestValues) [scripts/popup.js:29428,4]
ERROR in scripts/options.js from UglifyJs
Unexpected token: name (getLatestValues) [scripts/options.js:29428,4]
ERROR in scripts/background.js from UglifyJs
Unexpected token: name (getLatestValues) [scripts/background.js:28678,4]
It's worth mentioning that getLatestResults is not the only the only function in my code that has await in front of it. Also, it should only appear in background.js as the other entry points are not supposed to call it.
Also worth mentioning is that if I just comment the UglifyJS code, the resulting zipped extension works well.
What configuration piece am I missing to make these errors go away?
It turns out that currently (5/2017) the built in webpack.optimize.UglifyJsPlugin does not support ES6. When Babel transpiles await/async it turns them into generators, which causes UglifyJS to throw an error.
There are several alternatives to UglifyJS listed in this article, but I'm hoping that the Webpack guys will update the plugin, and I'd be able to leave my code intact.
TL;DR: My code is OK; UglifyJS does not support ES6; Will support in the future, or will be replaced by alternative.
I've replaced uglify-js to uglify-es for ES6 compatibility:
https://www.npmjs.com/package/uglify-es
Works fine for me!

Webpack, html-webpack-plugin, Error: Child compilation failed

I 've got a problem with my webpack configuration. After implementing html-webpack-plugin I got an Error, there's whole error stack from generated index.html.
Error Stack:
Html Webpack Plugin:
Error: Child compilation failed:
Conflict: Multiple assets emit to the same filename index.html:
Error: Conflict: Multiple assets emit to the same filename index.html
compiler.js:76
[Pre-build]/[html-webpack-plugin]/lib/compiler.js:76:16
Compiler.js:291 Compiler.
[Pre-build]/[webpack]/lib/Compiler.js:291:10
Compiler.js:494
[Pre-build]/[webpack]/lib/Compiler.js:494:13
Tapable.js:138 next
[Pre-build]/[tapable]/lib/Tapable.js:138:11
CachePlugin.js:62 Compiler.
[Pre-build]/[webpack]/lib/CachePlugin.js:62:5
Tapable.js:142 Compiler.applyPluginsAsyncSeries
[Pre-build]/[tapable]/lib/Tapable.js:142:13
Compiler.js:491
[Pre-build]/[webpack]/lib/Compiler.js:491:10
Tapable.js:131 Compilation.applyPluginsAsyncSeries
[Pre-build]/[tapable]/lib/Tapable.js:131:46
Compilation.js:645 self.applyPluginsAsync.err
[Pre-build]/[webpack]/lib/Compilation.js:645:19
Tapable.js:131 Compilation.applyPluginsAsyncSeries
[Pre-build]/[tapable]/lib/Tapable.js:131:46
Compilation.js:636 self.applyPluginsAsync.err
[Pre-build]/[webpack]/lib/Compilation.js:636:11
Tapable.js:131 Compilation.applyPluginsAsyncSeries
[Pre-build]/[tapable]/lib/Tapable.js:131:46
Compilation.js:631 self.applyPluginsAsync.err
[Pre-build]/[webpack]/lib/Compilation.js:631:10
Tapable.js:131 Compilation.applyPluginsAsyncSeries
[Pre-build]/[tapable]/lib/Tapable.js:131:46
Compilation.js:627 sealPart2
[Pre-build]/[webpack]/lib/Compilation.js:627:9
Tapable.js:131 Compilation.applyPluginsAsyncSeries
[Pre-build]/[tapable]/lib/Tapable.js:131:46
Compilation.js:575 Compilation.seal
[Pre-build]/[webpack]/lib/Compilation.js:575:8
Compiler.js:488
[Pre-build]/[webpack]/lib/Compiler.js:488:16
Tapable.js:225
[Pre-build]/[tapable]/lib/Tapable.js:225:11
Compilation.js:477 _addModuleChain
[Pre-build]/[webpack]/lib/Compilation.js:477:11
Compilation.js:448 processModuleDependencies.err
[Pre-build]/[webpack]/lib/Compilation.js:448:13
next_tick.js:73 _combinedTickCallback
internal/process/next_tick.js:73:7
next_tick.js:104 process._tickCallback
internal/process/next_tick.js:104:9
My webpack configuration code:
var webpack = require('webpack'),
path = require('path');
var CopyWebpackPlugin = require('copy-webpack-plugin'),
ExtractTextWebpackPlugin = require('extract-text-webpack-plugin'),
HtmlWebpackPlugin = require('html-webpack-plugin'),
const sourcePath = path.resolve(__dirname, './src');
const staticPath = path.resolve(__dirname, './static');
module.exports = function (env) {
const nodeEnv = env && env.prod ? 'production' : 'development';
const isProd = nodeEnv === 'production';
const postcssLoader = {
loader: 'postcss-loader',
options: {
plugins: function () {
return [
require('autoprefixer')
];
}
}
}
const plugins = [
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
minChunks: Infinity,
filename: 'vendor.bundle.js'
}),
new webpack.EnvironmentPlugin({
NODE_ENV: nodeEnv,
}),
new HtmlWebpackPlugin({
template: 'index.html',
minify: {
removeComments: true,
collapseWhitespace: true,
removeAttributeQuotes: true
},
chunksSortMode: 'dependency'
})
];
if(isProd) {
plugins.push(
new webpack.LoaderOptionsPlugin({
minimize: true,
debug: false
}),
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false,
screw_ie8: true,
conditionals: true,
unused: true,
comparisons: true,
sequences: true,
dead_code: true,
evaluate: true,
if_return: true,
join_vars: true,
},
output: {
comments: false,
},
})
);
} else {
plugins.push(
new webpack.HotModuleReplacementPlugin()
);
}
return {
devtool: isProd? 'source-map' : 'eval',
context: sourcePath,
entry: {
app: './app/entry.ts',
vendor: './app/vendor.ts'
},
output: {
path: staticPath,
filename: '[name].bundle.js',
},
module: {
rules: [
{
test: /\.html$/,
exclude: /node_modules/,
use: {
loader: 'file-loader',
query: {
name: '[name].[ext]'
},
},
},
{
test: /\.css$/,
exclude: /node_modules/,
use: [
'style-loader',
'css-loader',
'postcss-loader'
]
},
{
test: /\.scss$/,
exclude: /node_modules/,
use: [
'style-loader',
'css-loader',
'postcss-loader',
'sass-loader'
]
},
{
test: /\.ts$/,
exclude: /node_modules/,
use: [
'ts-loader'
],
},
],
},
resolve: {
alias: {
Public: path.resolve(__dirname,'src/public'),
Style: path.resolve(__dirname,'src/styles')
},
extensions: ['.ts','.js', '.html'],
modules: [
path.resolve(__dirname, 'node_modules'),
sourcePath
]
},
plugins,
performance: isProd && {
maxAssetSize: 100,
maxEntrypointSize: 300,
hints: 'warning'
},
stats: {
colors: {
green: '\u001b[32m'
}
},
devServer: {
contentBase: './src',
historyApiFallback: true,
port: 3000,
compress: isProd,
inline: !isProd,
hot: !isProd,
stats: {
assets: true,
children: false,
chunks: false,
hash: false,
modules: false,
publicPath: false,
timings: true,
version: false,
warnings: true,
color: {
green: '\u001b[32m'
}
},
}
};
};
I couldn't find any source of that Error, maybe I am little bit tired, but I would like to finish it up, so I hope for your help guys.
Maybe should I use some raw-loader to load .html(?), which does not make me happy.
The problem is indeed the file-loader, because it simply copies the file over. By the time html-webpack-plugin tries to write index.html it has already been written by file-loader, hence resulting in a conflict.
There are several ways to resolve that issue, depending on what your needs are.
You could use html-loader for your HTML, although if you expect your imported HTML to simply be copied, it isn't the correct choice. To be clear, by the imported HTML I don't mean the template used by the html-webpack-plugin.
If you want to keep using the file-loader for your other HTML files, you can exclude the index.html so html-webpack-plugin falls back to its default loader. require.resolve works like require but gives you the full path of the module instead of its content.
{
test: /\.html$/,
exclude: [/node_modules/, require.resolve('./index.html')],
use: {
loader: 'file-loader',
query: {
name: '[name].[ext]'
},
},
},
When no loader matches the template, the html-webpack-plugin uses an ejs loader as a fallback. If you don't need any loader for .html files, you could remove the rule entirely and it would work just fine. That is rather unlikely, otherwise you wouldn't have a .html rule in the first place, but this also means you can use the .ejs extension to not apply the .html rule, as all HTML is valid EJS. You would rename index.html to index.ejs and change your plugin configuration accordingly:
new HtmlWebpackPlugin({
template: 'index.ejs',
minify: {
removeComments: true,
collapseWhitespace: true,
removeAttributeQuotes: true
},
chunksSortMode: 'dependency'
})
I had to upgrade my node version. then the issue is fixed.
upgrade to latest node version(ubuntu)
sudo npm cache clean -f
sudo npm install -g n
sudo n stable
sudo n latest
to check the version
node -v
you might need to restart your terminal to see the latest version.
For my case I had the template file name misspelled.
Solution to my problem was updating node version.
This is may be not ordinary case, but for me, problem was caused by symbol "!" in the path. After I moved all content to the folder without "!" then the error disappeared.
delete node modules package then run npm install all package install then npm start the same problem are face but this process to run solve the problem so this solution is useful
I had the same issue few minutes ago and I switched to a stable version of node to solve it. It worked
sudo npm cache clean -f
sudo npm install -g n
sudo n stable
Simple Updated Node JS Version. And use
npm i
this will update your all libraries
This method works for me you can also try

Categories

Resources