Webpack Build Speed performance - javascript

The Webpack Bulid runs pretty slow, project background is a community portal developed in Vue.js...
Can anybody tell if there is any potential for improvement and if so, what?
I wonder if the time for the build process of 37401ms can still be changed by changing the codebase?
const path = require('path');
const fs = require('fs');
const webpack = require('webpack');
const glob = require('glob');
const VueLoaderPlugin = require('vue-loader/lib/plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const autoprefixer = require('autoprefixer');
const statsSettings = {
all: false,
modules: true,
maxModules: 0,
errors: true,
warnings: false,
moduleTrace: true,
errorDetails: true,
timings: true,
performance: true,
builtAt: true,
};
const {
rootDir,
srcDir,
assetsDir,
stylesDir,
buildDir,
sitepackageDir,
publicPath,
} = require('./config');
const chunks = glob.sync(path.join(rootDir, srcDir, 'pages/**/index.js'))
.reduce((obj, file) => {
const name = path.basename(path.dirname(file));
return {
...obj,
[name]: file,
};
}, {});
module.exports = env => {
return {
mode: env.production ? 'production' : 'development',
context: path.join(rootDir, srcDir),
entry: chunks,
output: {
path: path.join(rootDir, buildDir),
filename: '[name].js',
publicPath: env.production ? publicPath : '',
},
devtool: env.production ? false : 'cheap-module-eval-source-map',
devServer: {
contentBase: path.join(rootDir, buildDir),
inline: true,
proxy: {
'/api/v0': 'http://localhost:4000',
},
},
watchOptions: {
ignored: env.watch ? 'node_modules' : '',
aggregateTimeout: 300,
},
stats: env.watch ? statsSettings : 'normal',
module: {
rules: [
{
test: /\.vue$/,
include: [
path.join(rootDir, srcDir),
require.resolve('bootstrap-vue'),
],
loader: 'vue-loader',
},
{
test: /\.js$/,
include: [
path.join(rootDir, srcDir),
require.resolve('bootstrap-vue'),
],
loader: 'babel-loader',
},
{
test: /\.(css|scss)$/,
use: [
env.production ? MiniCssExtractPlugin.loader : 'vue-style-loader',
'css-loader',
{
loader: 'postcss-loader',
options: {
plugins: [
autoprefixer({
browsers: ['>1%', 'last 2 versions', 'not ie < 11'],
}),
],
},
},
{
loader: 'sass-loader',
options: {
includePaths: [
path.join(rootDir, srcDir, stylesDir),
],
},
},
],
},
{
test: /\.(jpg|jpeg|png|gif|webp|svg|eot|otf|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$/,
loader: 'file-loader',
options: {
name: `${assetsDir}/_processed_/[name].[hash:4].[ext]`,
},
},
],
},
optimization: {
runtimeChunk: {
name: '_runtime',
},
splitChunks: {
cacheGroups: {
// we need to figure out if it's worth having a common chunk
// or if each entry chunk should be somewhat self-contained
common: {
chunks: 'initial',
name: '_common',
minChunks: 2,
minSize: 0,
},
vendor: {
test: /node_modules/,
chunks: 'initial',
name: '_vendor',
enforce: true,
},
},
},
},
resolve: {
extensions: ['.js', '.json', '.vue'],
alias: {
'#app': path.join(rootDir, srcDir),
// although we're using single file components that can be pre-compiled,
// we want to dynamically mounting them in the DOM html.
// this is way we need to alias 'vue' to use the runtime + compiler build here.
// see: https://vuejs.org/v2/guide/installation.html#Runtime-Compiler-vs-Runtime-only
vue$: 'vue/dist/vue.esm.js',
},
},
plugins: [
new webpack.DefinePlugin({
PAGES: JSON.stringify(Object.keys(chunks)),
}),
new VueLoaderPlugin(),
...plugHtmlTemplates(),
...plugExtractCss(env),
...plugCopyAssets(),
],
};
};
function plugHtmlTemplates () {
return glob.sync(path.join(rootDir, srcDir, 'pages/**/template.html'))
.map(template => {
const name = path.basename(path.dirname(template));
return {
template,
filename: `${name}.html`,
chunks: ['_runtime', '_vendor', '_styles', '_common', name],
};
})
.map(htmlConfig => new HtmlWebpackPlugin(htmlConfig));
}
function plugExtractCss (env) {
if (!env.production) return [];
return [
new MiniCssExtractPlugin({
filename: '[name].css',
chunkFilename: '[name].css',
}),
];
}
function plugCopyAssets () {
const assetsSrcPath = path.join(rootDir, srcDir, assetsDir);
if (!fs.existsSync(assetsSrcPath)) return [];
return [
new CopyWebpackPlugin([
{ from: assetsSrcPath, to: path.join(rootDir, buildDir, path.basename(assetsDir)) },
// this is required for the icons to be selectable in the backend
{ from: path.join(assetsSrcPath, 'icons/'), to: path.join(rootDir, sitepackageDir, 'Resources/Public/Icons/') },
// this is required for avatars to be available; we must not check them in in fileadmin since they would
// prevent having the dir linked by Deployer during a deployment
{ from: path.join(rootDir, '../packages/users/Resources/Private/Images/Avatars/'), to: path.join(rootDir, buildDir, 'static/avatars/') },
]),
];
}
The question is whether you can improve the performance by using different plugins or summarizing steps...

I have a similar configuration. My configuration built ~33 seconds. I added a cache-loader package and decrease build time to ~17 seconds.
npm install --save-dev cache-loader
config:
rules: [
//rules here
{
test: /\.vue$/,
use: [
{
loader: 'cache-loader',
options: {}
},
{
loader: 'vue-loader',
options: vueLoaderConfig
}
],
},
{
test: /\.js$/,
use: [
{
loader: 'cache-loader',
options: {}
},
{
loader: 'babel-loader'
}
],
include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')]
}
]

Related

Webpack 5 Asset Module (asset/resource) makes all svgs disapper

Webpack is not actually my strength, I bumped into a problem today where I'm completeley stuck on a gigantic project.
Basically I just ran the webpack analyzer and our bundle size is way too big because we have around 200 SVGs in our project build.
I wanted to come up with a simple solution to decrease the bundle size and compress the SVG using webpack since that's what we are using.
After many failures I figured it would be as simple as it is to include
test: /\.(gif|png|jpe?g|svg)$/i,
type: 'asset/resource',
},
I can now see that my bundle is significantly decreased, however ALL my SVG's are hidden when I load up the project.
What could be the reason? Also what are the alternatives to compress SVG's using Webpack 5???
here is the whole webpack config
const path = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
const SpriteLoaderPlugin = require('svg-sprite-loader/plugin');
const { WebpackManifestPlugin } = require('webpack-manifest-plugin');
const hashSubstr = '.[contenthash:8]';
const svgoPlugins = [
{ cleanUpAttrs: true },
{ removeDoctype: true },
{ removeXMLProcInst: true },
{ removeComments: true },
{ removeMetadata: true },
{ removeDesc: true },
{ removeEditorsNSData: true },
{ removeEmptyAttrs: true },
{ removeHiddenElems: true },
{ removeEmptyText: true },
{ removeEmptyContainers: true },
{ cleanupNumericValues: true },
{ moveElemsAttrsToGroup: true },
{ convertColors: { shorthex: true } },
];
module.exports = (env) => ({
entry: ['./scripts/responsive/index.ts', './scripts/pwa/serviceworker.ts'],
output: {
filename: `[name]${!env.development ? hashSubstr : ''}.js`,
globalObject: 'this',
path: path.resolve(__dirname, './bundles/responsive'),
publicPath: '/',
assetModuleFilename: '[hash][ext][query]',
},
mode: !env.development ? 'production' : 'development',
devtool: 'inline-source-map',
optimization: {
minimize: true,
},
module: {
rules: [
// {
// test: /\.(gif|png|jpe?g|svg)$/i,
// type: 'asset/resource',
// },
{
test: /\.(jsx?|tsx?)$/,
loader: 'babel-loader',
options: {
presets: ['#babel/typescript', '#babel/env'],
},
},
{
test: /\.s[ac]ss$/i,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
publicPath: '../',
},
},
{
loader: 'css-loader',
options: {
sourceMap: true,
},
},
{
loader: 'sass-loader',
options: {
sourceMap: true,
},
},
],
},
{
test: /\-colou?r\.svg$/,
type: 'asset/resource',
include: [path.resolve(__dirname, 'Content/responsive/svg')],
use: [
{
loader: 'svg-sprite-loader',
options: {
spriteFilename: 'sprite.svg',
esModule: false,
symbolId: (fileName) => {
return `r-icon-${path.basename(fileName, '.svg')}`;
},
},
},
{
loader: 'svgo-loader',
options: {
plugins: svgoPlugins,
},
},
],
},
{
test: /\.svg$/,
type: 'asset/resource',
exclude: /-colou?r\.svg$/,
include: [path.resolve(__dirname, 'Content/responsive/svg')],
use: [
{
loader: 'svg-sprite-loader',
options: {
spriteFilename: 'sprite.svg',
esModule: false,
symbolId: (fileName) => {
return `r-icon-${path.basename(fileName, '.svg')}`;
},
},
},
{
loader: 'svgo-loader',
options: {
plugins: [
{
removeAttrs: {
attrs: '(?!mask).*:(stroke|fill)',
},
},
...svgoPlugins,
],
},
},
],
},
],
},
//stats: 'verbose',
plugins: [
new ForkTsCheckerWebpackPlugin(),
new WebpackManifestPlugin({
fileName: 'asset-manifest.json',
generate: (seed, files) => {
const manifestFiles = files.reduce((manifest, file) => {
manifest[file.name] = file.path;
return manifest;
}, seed);
const entrypointFiles = files
.filter((x) => x.isInitial && !x.name.endsWith('.map'))
.map((x) => x.path);
return {
files: manifestFiles,
entrypoints: entrypointFiles,
};
},
}),
new MiniCssExtractPlugin({
// Options similar to the same options in webpackOptions.output
// both options are optional
filename: `css/[name]${!env.development ? hashSubstr : ''}.css`,
chunkFilename: `css/[id]${!env.development ? hashSubstr : ''}.css`,
}),
new SpriteLoaderPlugin({
plainSprite: true,
}),
],
resolve: {
extensions: ['.js', '.jsx', '.ts', '.tsx'],
alias: {
Svg: path.resolve(__dirname, './Content/responsive/svg'),
},
},
});
In my case, it seems that when using type: 'asset/resource' the module is exported as commonjs and not default import of esmodule

Webpack 5 SCSS and JS save returns old version of page

I work with webpack 5. Pug works well - after autosave or cmd+S I get new version of page. And it doesn't work so with JS and SCSS: SCSS autosave works well but after cmd+S I get some old version of page(usually everytime the same). With JS both autosave and cmd+S return some old version of page. Can you help me to find a solution? Below I dropped webpack.config.js
const path = require("path");
const fs = require("fs");
const HTMLWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CopyWebpackPlugin = require("copy-webpack-plugin");
const isDev = process.env.NODE_ENV === "development";
const isProd = !isDev;
const PATHS = {
src: path.join(__dirname, "./src"),
dist: path.join(__dirname, "./dist"),
};
const PAGES_DIR = `${PATHS.src}/`;
const PAGES = fs.readdirSync(PAGES_DIR).filter((fileName) => fileName.endsWith(".pug"));
const filename = (ext) => `[name].${ext}`;
const plugins = () => {
const basePlugins = [
...PAGES.map(
(page) =>
new HTMLWebpackPlugin({
template: `${PAGES_DIR}/${page}`,
filename: `./${page.replace(/\.pug/, ".html")}`,
})
),
new MiniCssExtractPlugin({
filename: `./css/${filename("css")}`,
}),
new CopyWebpackPlugin({
patterns: [
{ from: path.resolve(__dirname, "src/assets"), to: path.resolve(`${PATHS.dist}`) },
{ from: path.resolve(__dirname, "src/img"), to: path.resolve(`${PATHS.dist}/img/`) },
],
}),
];
return basePlugins;
};
module.exports = {
context: path.resolve(`${PATHS.src}`),
mode: "development",
entry: "./js/main.js",
output: {
filename: `./js/${filename("js")}`,
path: path.resolve(`${PATHS.dist}`),
publicPath: "",
clean: true,
},
devServer: {
historyApiFallback: true,
static: path.resolve(`${PATHS.dist}`),
open: true,
compress: true,
hot: true,
port: 3000,
},
optimization: {
splitChunks: {
chunks: "all",
},
},
plugins: plugins(),
devtool: isProd ? false : "source-map",
module: {
rules: [
{
test: /\.pug$/,
loader: "pug-loader",
},
{
test: /\.s[ac]ss$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
publicPath: (resourcePath, context) => {
return path.relative(path.dirname(resourcePath), context) + "/";
},
},
},
"css-loader",
{
loader: "postcss-loader",
options: {
postcssOptions: {
plugins: ["postcss-preset-env"],
},
},
},
"sass-loader",
],
},
{
test: /\.js$/,
exclude: /node_modules/,
use: ["babel-loader"],
},
{
test: /\.(?:|gif|png|jpg|jpeg|svg|webp)$/,
use: [
{
loader: "file-loader",
options: {
name: `./img/${filename("[ext]")}`,
},
},
],
},
{
test: /\.(?:|woff2)$/,
use: [
{
loader: "file-loader",
options: {
name: `./fonts/${filename("[ext]")}`,
},
},
],
},
],
},
};
I don't know what to write here. I described my problem above.

How to bundle and minimize JS and CSS files with webpack

I have been trying to use webpack for my project. I have successfully got webpack to compile all of my js into one file correctly. But what i need is for it to also get the css. All of my css is in one file so i figured it would be easy but i cant figure it out. I have tried to split it up into 2 phases CSS_CONFIG and JS_CONFIG
const path = require('path');
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
const TerserPlugin = require("terser-webpack-plugin");
var JS_CONFIG = {
entry: path.join(__dirname, 'src/js/main.js'),
resolve: {
alias: {
'/components': path.resolve(__dirname, 'src/components/'),
'/js': path.resolve(__dirname, 'src/js/'),
'/views': path.resolve(__dirname, 'src/views/'),
},
},
optimization: {
minimizer: [
// For webpack#5 you can use the `...` syntax to extend existing minimizers (i.e. `terser-webpack-plugin`), uncomment the next line
new TerserPlugin(),
//new CssMinimizerPlugin(),
],
},
}
var CSS_CONFIG = {
entry:path.join(__dirname,"src/index.html"),
module: {
rules: [
{
test: /.s?css$/,
use: [],
},
],
},
optimization: {
minimize:true,
minimizer: [
// For webpack#5 you can use the `...` syntax to extend existing minimizers (i.e. `terser-webpack-plugin`), uncomment the next line
// `...`,
//new CssMinimizerPlugin(),
],
},
plugins: [],
}
module.exports = [JS_CONFIG, CSS_CONFIG];
This seems like it should be pretty straightforward with webpack but I must not be grasping somthing. Can anyone help me out?
I believe that your CSS_CONFIG should look more like this:
const path = require("path");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const RemoveEmptyScriptsPlugin = require('webpack-remove-empty-scripts');
const isDevelopment = process.env.NODE_ENV === 'development'
var config = {
module: {},
};
var cssConfig = Object.assign({}, config, {
devtool: 'source-map',
entry: {
main: path.resolve(__dirname, 'public/css/main.scss'),
fonts: path.resolve(__dirname, 'public/css/fonts.scss'),
app: path.resolve(__dirname, 'public/css/app.scss'),
},
output: {
path: path.resolve(__dirname, 'public/css')
},
performance: {
hints: false
},
plugins: isDevelopment ? [] : [
new RemoveEmptyScriptsPlugin(),
new MiniCssExtractPlugin({
filename: '[name].css',
chunkFilename: '[id].css'
}),
],
module: {
rules:[
// Extracts the compiled CSS from the SASS files defined in the entry
{
test: /\.scss$/,
use: isDevelopment ?
[
'style-loader',
{
loader: 'css-loader',
options: { sourceMap: true, importLoaders: 1, modules: false },
},
{
loader: 'postcss-loader',
options: { sourceMap: true }
},
{
loader: 'resolve-url-loader',
},
{
loader: 'sass-loader',
options: { sourceMap: true }
},
]
: [
{
loader: MiniCssExtractPlugin.loader,
options: {
publicPath: (resourcePath, context) => {
// publicPath is the relative path of the resource to the context
// e.g. for ./css/admin/main.css the publicPath will be ../../
// while for ./css/main.css the publicPath will be ../
return path.relative(path.dirname(resourcePath), context) + "/";
},
},
},
{
loader: 'css-loader',
options: {
importLoaders: 2,
modules: false,
url: false,
},
},
{
loader: 'postcss-loader',
options:
{
postcssOptions:
{
plugins: [
require('postcss-import'),
require('postcss-url')({
url: 'copy',
useHash: true,
hashOptions: { append: true },
assetsPath: path.resolve(__dirname, 'public/assets/')
})
]
}
}
},
{
loader: 'resolve-url-loader',
},
{
loader: 'sass-loader',
options: { sourceMap: true }
},
]
},
/* you may or may not need this
{
test: /\.(woff(2)?|ttf|eot|svg)$/,
use: [
{
loader: 'file-loader',
options: {
name: '[name].[ext]',
outputPath: 'fonts/',
esModule: false,
}
}
]
},
*/
],
}
});
use runs the loaders in order that they are put in the array. So 'style-loader' needs to be executed first. Here is a simple way of achieving the desired result.
const path = require('path');
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
const TerserPlugin = require("terser-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const RemoveEmptyScriptsPlugin = require('webpack-remove-empty-scripts');
const isDevelopment = process.env.NODE_ENV === 'development'
var JS_CONFIG = {
entry: {
main: path.resolve(__dirname, 'src/js/main.js'),
css: path.join(__dirname, 'src/css/main.css'),
},
resolve: {
alias: {
'/components': path.resolve(__dirname, 'src/components/'),
'/js': path.resolve(__dirname, 'src/js/'),
'/views': path.resolve(__dirname, 'src/views/'),
},
},
module: {
rules:[
{
test: /\.css$/,
use:['style-loader','css-loader']
},
],
},
};
module.exports = [JS_CONFIG];

Webpack unexpected behavior TypeError: Cannot read property 'call' of undefined

Recently we have updated webpack to v4 and soon noticed unexpected errors from webpack during development, which disappears after rebuild of entire bundle.
Our application build using lazy loading and code splitting, which can cause the issue, though I couldn't find anything related to this in the official documentations.
Here the error we get
react_devtools_backend.js:2273 TypeError: Cannot read property 'call' of undefined
our webpack webpack.config.js file.
const webpack = require('webpack');
const path = require('path');
const glob = require('glob');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const AssetsPlugin = require('assets-webpack-plugin');
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');
// minification plugins
const TerserJSPlugin = require('terser-webpack-plugin');
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
// image optimization plugins
const ImageminPlugin = require("imagemin-webpack-plugin").default;
const imageminGifsicle = require("imagemin-gifsicle");
const imageminPngquant = require("imagemin-pngquant");
const imageminSvgo = require("imagemin-svgo");
const imageminMozjpeg = require('imagemin-mozjpeg');
const env = require('dotenv').config();
const isProd = process.env.NODE_ENV === 'production';
const isDev = !isProd;
const environment = {
NODE_ENV: process.env.NODE_ENV || 'development',
CONFIG: process.env.CONFIG || 'development',
DEBUG: process.env.DEBUG || false,
};
const plugins = () => {
let plugins = [
new CleanWebpackPlugin(['build', 'cachedImages'], {
root: path.resolve(__dirname, '../dist'),
verbose: true,
dry: false,
}),
new webpack.EnvironmentPlugin(Object.assign(environment, env.parsed)),
new MiniCssExtractPlugin('[chunkhash:5].[name].[hash].css'),
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery',
moment: 'moment',
_: 'lodash',
}),
new webpack.ContextReplacementPlugin(/moment[\\\/]locale$/, /^\.\/(en)$/),
new AssetsPlugin({
filename: 'assets.json',
}),
new ImageminPlugin({
cacheFolder: isDev ? path.resolve(__dirname, '../dist/cachedImages') : null,
externalImages: {
context: 'src',
sources: glob.sync('src/assets/img/**/*.*'),
destination: 'dist/img/',
fileName: (filepath) => {
let name = filepath.split(/img(\/|\\)/).pop();
return name;
},
},
plugins: [
imageminGifsicle({
interlaced: false
}),
imageminMozjpeg({
progressive: true,
arithmetic: false
}),
imageminPngquant({
floyd: 0.5,
speed: 2
}),
imageminSvgo({
plugins: [
{ removeTitle: true },
{ convertPathData: false }
]
}),
],
}),
];
if (isProd) {
plugins.push(
new BundleAnalyzerPlugin({
analyzerMode: 'static',
reportFilename: path.resolve(__dirname, 'analysis.html'),
generateStatsFile: false,
logLevel: 'info',
})
);
}
return plugins;
};
const optimization = () => {
let optimizations = {
concatenateModules: true,
splitChunks: {
cacheGroups: {
vendor: {
name: 'vendor',
test: /[\\/]node_modules[\\/](react|react-dom|lodash|moment)[\\/]/,
chunks: 'all',
},
commons: {
chunks: 'async',
}
}
}
};
if (isProd) {
optimizations.minimizer = [
new TerserJSPlugin({
terserOptions: {
compress: {
pure_funcs: ['console.log'],
drop_console: true,
drop_debugger: true
},
warnings: false
},
parallel: true
}),
new OptimizeCSSAssetsPlugin({})
];
}
return optimizations;
};
const fontLoaders = [
{
test: /\.woff(\?v=\d+\.\d+\.\d+)?$/,
use: {
loader: 'url?limit=10000&mimetype=application/font-woff',
}
},
{
test: /\.woff2(\?v=\d+\.\d+\.\d+)?$/,
use: {
loader: 'url?limit=10000&mimetype=application/font-woff',
}
},
{
test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/,
use: {
loader: 'url?limit=10000&mimetype=application/octet-stream',
}
},
{
test: /\.svg(\?v=\d+\.\d+\.\d+)?$/,
use: {
loader: 'url?limit=10000&mimetype=image/svg+xml',
}
},
{
test: /\.eot(\?v=\d+\.\d+\.\d+)?$/,
use: {
loader: 'file',
}
}
];
const config = {
mode: process.env.NODE_ENV,
devtool: isDev ? 'source-map' : '',
context: path.resolve(__dirname, '../src'),
entry: {
bundle: './app.jsx',
embed: './embed.jsx',
styles: './sass_new/main.scss',
vendor: [
'react',
'react-dom',
'redux',
'redux-saga',
'react-redux',
'react-router',
'react-tap-event-plugin',
'lodash',
'moment',
]
},
output: {
publicPath: '/build/',
filename: '[name].[hash].js',
chunkFilename: '[name].[hash].js',
path: path.resolve(__dirname, '../dist/build'),
},
resolve: {
extensions: ['.js', '.jsx', '.json'],
alias: {
config: path.resolve(__dirname, '../config.js'),
utils: path.resolve(__dirname, '../src/utils'),
shared: path.resolve(__dirname, '../src/components/shared'),
services: path.resolve(__dirname, '../src/services'),
store: path.resolve(__dirname, '../src/store'),
constants: path.resolve(__dirname, '../src/constants'),
actions: path.resolve(__dirname, '../src/actions'),
components: path.resolve(__dirname, '../src/components'),
},
},
optimization: optimization(),
plugins: plugins(),
module: {
rules: [
{
test: /\.jsx?$/,
exclude: [/node_modules/, /libs/],
use: {
loader: path.join(__dirname, '../helpers/custom-loader.js'),
options: {
presets: ['#babel/preset-env', '#babel/preset-react'],
plugins: [
'#babel/plugin-proposal-object-rest-spread',
'#babel/plugin-proposal-class-properties',
'#babel/plugin-transform-destructuring',
'#babel/plugin-syntax-dynamic-import',
'#babel/plugin-transform-runtime',
'syntax-async-functions'
]
}
}
},
{
test: /\.scss$/,
use: [
{
loader: MiniCssExtractPlugin.loader
},
'css-loader',
'sass-loader',
]
},
{
test: /\.css$/,
use: [
'css-loader'
]
},
{
test: /\.(jpe?g|png|gif|svg)$/i,
loader: "url-loader",
options: {
name: "[path][name].[ext]"
},
},
...fontLoaders
]
},
watchOptions: {
ignored: /node_modules/,
},
};
module.exports = config;
I have no idea how to fix this, and it's taking a lot of time to rebuild entire app after getting this error.

React + Webpack: "RuntimeError: memory access out of bounds"

I've recently developed a react + webpack application that is deployed using
AWS Amplify. I've been getting a strange error that is logged on Sentry, but can't
find a way to replicate the bug.
RuntimeError: memory access out of bounds
I suspect it has something to do with my webpack configuration, but I don't know whats wrong.
I never used wasm, but it seems to be related to it.
Here is my production level webpack configuration.
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const TerserPlugin = require('terser-webpack-plugin');
const env = require('../environment/prod.env');
const commonPaths = require('./paths');
const webpack = require('webpack');
const SentryWebpackPlugin = require('#sentry/webpack-plugin');
module.exports = {
mode: 'production',
devtool: 'source-map',
output: {
filename: `${commonPaths.jsFolder}/[name].[hash].js`,
path: commonPaths.outputPath,
chunkFilename: `${commonPaths.jsFolder}/[name].[chunkhash].js`,
},
optimization: {
minimizer: [
new TerserPlugin({
parallel: true,
cache: true,
sourceMap: true,
}),
new OptimizeCSSAssetsPlugin(),
],
splitChunks: {
cacheGroups: {
vendors: {
test: /[\\/]node_modules[\\/]/,
name: 'vendors',
chunks: 'initial',
},
async: {
test: /[\\/]node_modules[\\/]/,
name: 'async',
chunks: 'async',
minChunks: 4,
},
},
},
runtimeChunk: true,
},
module: {
rules: [
{
test: /\.scss$/,
use: [
{ loader: 'style-loader' },
{
loader: 'css-loader',
options: {
sourceMap: true,
},
},
{
loader: 'sass-loader',
options: {
sourceMap: true,
},
},
],
},
{
test: /\.css$/,
use: [
{
loader: 'style-loader',
},
{
loader: 'css-loader',
options: {
sourceMap: true,
},
},
],
},
],
},
plugins: [
new webpack.DefinePlugin({
'process.env': env,
}),
new MiniCssExtractPlugin({
filename: `${commonPaths.cssFolder}/[name].css`,
chunkFilename: `${commonPaths.cssFolder}/[name].css`,
}),
],
};
Here is also my common webpack configuration
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ScriptExtHtmlWebpackPlugin = require('script-ext-html-webpack-plugin');
const commonPaths = require('./paths');
module.exports = {
context: commonPaths.srcPath,
entry: commonPaths.entryPath,
output: {
path: commonPaths.outputPath,
filename: 'js/[name].js',
},
resolve: {
extensions: ['.ts', '.js', '.html', '.vue'],
alias: {
'~': commonPaths.srcPath,
},
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
include: commonPaths.srcPath,
exclude: /node_modules/,
loader: 'babel-loader',
options: {
plugins: ['react-hot-loader/babel'],
},
},
{
test: /\.(png|jpg|gif|svg)$/,
use: [
{
loader: 'file-loader',
options: {
name: 'assets/img/[name].[hash:8].[ext]',
publicPath: '/',
},
},
],
},
{
test: /\.(mp3)$/,
use: [
{
loader: 'file-loader',
options: {
name: 'assets/audio/[name].[hash:8].[ext]',
publicPath: '/',
},
},
],
},
{
test: /\.(ttc|ttf|eot)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
use: [
{
loader: 'file-loader',
options: {
name: 'assets/fonts/[name].[hash:8].[ext]',
publicPath: '/',
},
},
],
},
],
},
serve: {
content: commonPaths.entryPath,
dev: {
publicPath: commonPaths.outputPath,
},
open: true,
},
resolve: {
modules: ['src', 'node_modules', 'bower_components', 'shared', '/shared/vendor/modules'],
extensions: ['*', '.js', '.jsx'],
},
plugins: [
new webpack.ProgressPlugin(),
new HtmlWebpackPlugin({
favicon: './icon.png',
template: commonPaths.templatePath,
}),
new ScriptExtHtmlWebpackPlugin({
defaultAttribute: 'async',
}),
],
};
Any help would really help. Thanks.
Try to restart your server and make sure you reinstall node modules.

Categories

Resources