webpack-dev-server and WASM HMR - javascript

I'm trying to make a real time shooter game on the web using ThreeJS and Rapier. Rapier is a physics engine written in rust and can be used in JS using the WASM module. Now in development webpack-dev-server and HMR are really a god given tool, if it works. The RAPIER WASM module gets loaded but from the wrong port. My HTTP server runs on http://localhost:8080 but the devserver on -:9000. The fetch mechanism that webpack uses to get the WASM doesn't configure the port for the fetch. Is this a bug or misconfiguration on my end?
My webpack.config.js:
const dotenv = require('dotenv');
dotenv.config();
const path = require('path');
const zlib = require('zlib');
const CompressionPlugin = require('compression-webpack-plugin');
const ThreadsPlugin = require('threads-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const CopyPlugin = require('copy-webpack-plugin');
const WebpackBar = require('webpackbar');
const { WebpackManifestPlugin: ManifestPlugin } = require('webpack-manifest-plugin');
const TerserPlugin = require('terser-webpack-plugin');
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
const DEBUG = process.env.NODE_ENV !== 'production';
const FILENAME = DEBUG ? '[name]' : '[name].[contenthash]';
const CHUNK_FILENAME = DEBUG ? '[name]' : '[id].[contenthash]';
module.exports = {
mode: DEBUG ? 'development' : 'production',
entry: { bundle: path.join(__dirname, 'resources/js/bundle.js') },
output: {
path: path.join(__dirname, 'public'),
filename: FILENAME + '.js',
chunkFilename: CHUNK_FILENAME + '.js',
publicPath: '',
clean: true,
},
module: {
rules: [
{
test: '/\.m?js$/',
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: ['#babel/preset-env']
}
}
},
{ test: /\.(frag|vert)$/, use: 'raw-loader' },
{
test: /\.(sa|sc|c)ss$/,
use: [
MiniCssExtractPlugin.loader,
{ loader: 'css-loader', options: { importLoaders: 2 } },
'postcss-loader',
'sass-loader',
]
},
{ test: /\.(png|svg|jpg|jpeg|webm|gif)$/i, type: 'asset/resource' },
{ test: /\.(woff|woff2|eot|ttf|otf)$/i, type: 'asset/resource' },
{ test: /\.svelte$/, use: { loader: 'svelte-loader', options: {
emitCss: false,
hotReload: DEBUG,
compilerOptions: { dev: DEBUG },
hotOptions: {
preserveLocalState: false,
noReload: false, // prevent reload after fatal error
acceptAccesssors: true,
acceptNamedExports: true
}
} } },
{ test: /node_modules\/svelte\/.*\.mjs$/, resolve: { fullySpecified: false } }
]
},
plugins: [
new CopyPlugin({ patterns: [
// { from: './resources/images', to: 'images' },
{ from: './resources/textures', to: 'textures' },
{ from: './resources/scenes', to: 'scenes' },
] }),
new ManifestPlugin(),
new MiniCssExtractPlugin({
filename: FILENAME + '.css',
chunkFilename: CHUNK_FILENAME + '.css'
}),
// new ThreadsPlugin(),
new WebpackBar(),
].concat(DEBUG ? [] : [
new CompressionPlugin({
filename: '[path][base].gz',
algorithm: 'gzip',
test: /\.(js|css|html|svg)$/,
threshold: 10240,
minRatio: 0.8,
}),
new CompressionPlugin({
filename: '[path][base].br',
algorithm: 'brotliCompress',
test: /\.(js|css|html|svg)$/,
compressionOptions: {
params: {
[zlib.constants.BROTLI_PARAM_QUALITY]: 11,
},
},
threshold: 10240,
minRatio: 0.8,
})
]),
optimization: {
minimize: true,
minimizer: [ new TerserPlugin(), new CssMinimizerPlugin() ],
splitChunks: {
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/,
name: 'vendor',
chunks: 'all'
}
}
}
},
devServer: {
port: 9000,
static: path.join(__dirname, 'public'),
hot: true,
client: {
overlay: {
errors: true,
warnings: false,
},
progress: true,
reconnect: 10,
webSocketURL: {
hostname: 'localhost',
port: 9000,
}
},
compress: true
},
devtool: DEBUG ? 'inline-source-map' : false,
experiments: {
asyncWebAssembly: true
}
};
I've googled a fair bit for solutions but so far I haven't found anything that looks like my particular issue.

Related

web worker not able to communicate in webpack

I am using webpack and this is my webpack config file
const webpack = require("webpack");
const path = require("path");
const lazPerf = require("laz-perf");
console.log(lazPerf);
module.exports = {
entry: "./src/index.js",
output: {
filename: "bundle.js",
path: path.resolve(__dirname, "docs"),
},
resolve: {
fallback: {
fs: false,
},
},
module: {
rules: [
{
test: /\.css$/,
use: ["style-loader", "css-loader"],
},
{
test: /\.worker\.js$/,
exclude: /node_modules/,
use: "worker-loader",
},
],
},
devServer: {
port: 8080,
static: path.resolve(__dirname, "docs"),
hot: true,
},
mode: "development",
devtool: "cheap-module-source-map",
plugins: [
// commonjs({ include: /node_modules\/laz-perf/ }),
new webpack.DefinePlugin({
tree: {
leafCapacity: 16,
bufferCapacity: 16,
},
}),
],
};
And in index.js
this is my code:
import Worker from "./worker/fetcher.worker.js";
const fetchWorker = new Worker();
fetchWorker.postMessage("hello");
and this is fetcher.worker.js
onmessage = function (message) {
console.log(message);
};
this is my directory structure
I am not able to communicate and get that console from fetcher worker !!
Any help, please

Webpack does not load manifest.json file in production build

I'm creating a PWA react application in which I configure the manifest.json file and serviceWroker.js file.
In the development mode, it works fine but when I create production build using webpack, manifest.json file does not load in the Build folder.
Does anyone know what's the issue?
Here is my webpack.config.js file
const path = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const WebpackRTLPlugin = require('webpack-rtl-plugin');
const WebpackMessages = require('webpack-messages');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const TerserPlugin = require('terser-webpack-plugin');
const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
const del = require('del');
const webpack = require('webpack');
// theme name
const themeName = 'metronic';
// global variables
const rootPath = path.resolve(__dirname);
const distPath = rootPath + '/src';
const mainConfig = function() {
const isEnvDevelopment = false;
const isEnvProduction = true;
return {
mode: 'production',
stats: 'errors-only',
performance: {
hints: false
},
externals: [ 'jspdf', 'jspdf-autotable' ],
entry: './src/index.js',
output: {
// main output path in assets folder
path: path.resolve(__dirname, 'dist'),
// output path based on the entries' filename
// filename: '[name].js',
filename: isEnvProduction
? 'static/js/[name].[contenthash:8].js'
: isEnvDevelopment && 'static/js/bundle.js',
// TODO: remove this when upgrading to webpack 5
futureEmitAssets: true,
// There are also additional JS chunk files if you use code splitting.
chunkFilename: isEnvProduction
? 'static/js/[name].[contenthash:8].chunk.js'
: isEnvDevelopment && 'static/js/[name].chunk.js',
// We inferred the "public path" (such as / or /my-project) from homepage.
// We use "/" in development.
publicPath: '/artbot/app/'
},
resolve: { extensions: [ '.scss', '.css','.mjs','.jsx', '.js', '.json' ] },
optimization: {
minimize: true,
namedChunks: true,
nodeEnv: 'production',
removeAvailableModules: true,
removeEmptyChunks: true,
mergeDuplicateChunks: true,
minimizer: [ new OptimizeCssAssetsPlugin(), new TerserPlugin({ cache: true }) ],
splitChunks: {
chunks: "all"
}
},
plugins: [
// webpack log message
new WebpackMessages({
name: themeName,
logger: (str) => console.log(`>> ${str}`)
}),
new BundleAnalyzerPlugin(),
new webpack.optimize.AggressiveMergingPlugin(),
new HtmlWebpackPlugin({
title: 'Custom Template',
template: 'public/index.html',
minify: {
removeComments: true,
collapseWhitespace: true,
removeAttributeQuotes: true
}
}),
// create css file
new MiniCssExtractPlugin({
filename: 'static/css/[name].css'
}),
new WebpackRTLPlugin({
filename: 'static/css/[name].rtl.css',
minify: true
}),
{
apply: (compiler) => {
// hook name
compiler.hooks.afterEmit.tap('AfterEmitPlugin', (compilation) => {
(async () => {
await del.sync(distPath + '/sass/*.js', { force: true });
})();
});
}
}
],
module: {
rules: [
{
test: /\.(js|mjs|jsx|ts|tsx)$/,
// exclude: /#babel(?:\/|\\{1,2})runtime/,
exclude: /node_modules/,
loader: require.resolve('babel-loader'),
options: {
babelrc: true,
plugins: [
[
require.resolve('babel-plugin-named-asset-import'),
{
loaderMap: {
svg: {
ReactComponent: '#svgr/webpack?-svgo,+titleProp,+ref![path]'
}
}
}
]
]
}
},
{
test: /\.css$/,
loader: 'css-loader'
},
{
test: /\.scss$/,
use: [
MiniCssExtractPlugin.loader,
'css-loader',
{
loader: 'resolve-url-loader',
options: {
removeCR: true
}
},
{
loader: 'sass-loader',
options: {
sourceMap: true
}
}
]
},
{
test: /\.(png|jpg|svg)$/,
loader: 'file-loader',
options: {
limit: 10000,
name: 'static/media/[name].[hash:8].[ext]',
esModule: false
}
//loader: 'url-loader?limit=8192'
},
{
test: /\.(woff2|eot|ttf|woff)$/,
loader: 'url-loader'
},
{
test: /\.json$/,
loader: 'file-loader',
type: 'javascript/auto',
exclude: /node_modules/,
options: {
name: 'static/json/[name].[hash:8].[ext]'
}
},
{
test: /\.html$/i,
loader: 'html-loader'
}
]
}
};
};
module.exports = function() {
return [ mainConfig() ];
};

Wepack url-loader is ignoring CSS backgrounds

Im trying to use url-loader to convert file URLs into inline data URLs for my CSS backgrounds. When I run the build command, it generates the CSS & JS files without any error but the background image URLs remain unchanged in the CSS output.
Here's my webpack config:
const path = require("path");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const UglifyJsPlugin = require("uglifyjs-webpack-plugin");
const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin");
const ManifestPlugin = require('webpack-manifest-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
module.exports = (env, argv) => ({
entry: {
app: ['./app/Resources/js/app.js', './app/Resources/scss/app.scss']
},
output: {
path: path.join(__dirname, "/web/build"),
filename: argv.mode === 'production' ? '[name].[hash].js' : '[name].js'
},
optimization: {
minimizer: [
new UglifyJsPlugin({
cache: true,
parallel: true,
sourceMap: false // set to true if you want JS source maps
}),
new OptimizeCSSAssetsPlugin({
cssProcessorPluginOptions: {
preset: ['default', { discardComments: { removeAll: true } }],
},
})
]
},
devServer: {
contentBase: './web',
port: 9000,
disableHostCheck: true
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader"
},
resolve: {
extensions: ['.js']
}
},
{
test: /\.scss$/,
resolve: {
extensions: ['.scss']
},
use: [
{
loader: MiniCssExtractPlugin.loader
},
{
loader: "css-loader"
},
{
loader: "sass-loader",
options: {
sassOptions: {
outputStyle: 'expanded',
includePaths: ['./node_modules/foundation-sites/scss']
}
}
}
]
},
{
test: /\.(gif|png|jpe?g|svg)$/i,
use: [
{
loader: 'url-loader',
options: {
limit: 8192
},
}
],
}
]
},
plugins: [
new MiniCssExtractPlugin({
filename: argv.mode === 'production' ? '[name].[contenthash].css' : '[name].css'
}),
new ManifestPlugin(),
new CleanWebpackPlugin()
],
});
My CSS is just a standard SCSS file:
.icon { background:url('path/to/icon.svg'); }
In the final output, I'd expect path/to/icon.svg to be replaced by a data URL. What am I doing wrong?

adding directory with webpack

I decided to give webpack a shot and am using a starter kit for a small project. I'm not sure where I am going wrong but I want to add a new directory of files and access them like any other build.In this case it is the folder "particles.js-master". When I add a directory I cannot seem to access anything in the folder. I'm assuming I have to add an output or the like to the webpack config? Any advice would be greatly appreciated, thanks :)
here is my project structure
webpack:
const path = require('path');
const webpack = require('webpack');
const HtmlWebPackPlugin = require('html-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const PreloadWebpackPlugin = require('preload-webpack-plugin');
const CssUrlRelativePlugin = require('css-url-relative-plugin');
const glob = require('glob');
const IS_DEV = process.env.NODE_ENV === 'dev';
const config = {
mode: IS_DEV ? 'development' : 'production',
devtool: IS_DEV ? 'eval' : 'source-map',
entry: './src/js/index.js',
output: {
filename: 'js/[name].[hash].js',
path: path.resolve(__dirname, 'dist'),
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader',
},
{
test: /\.scss$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
hmr: IS_DEV,
},
},
'css-loader',
'sass-loader',
],
},
{
test: /\.(gif|png|jpe?g|svg)$/i,
use: [
{
loader: 'url-loader',
options: {
limit: 8192,
name: '[name].[ext]',
fallback: 'file-loader',
outputPath: 'public/images',
},
},
{
loader: 'image-webpack-loader',
options: {
mozjpeg: {
progressive: true,
quality: 65,
},
pngquant: {
quality: '65-90',
speed: 4,
},
gifsicle: {
interlaced: false,
},
webp: {
quality: 75,
},
},
},
],
},
],
},
plugins: [
new CleanWebpackPlugin(),
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery',
'windows.jQuery': 'jquery',
}),
new CopyWebpackPlugin([
{
from: './src/public',
to: 'public',
},
]),
new MiniCssExtractPlugin({
filename: IS_DEV ? 'css/[name].css' : 'css/[name].[contenthash].css',
chunkFilename: 'css/[id].css',
}),
new webpack.HashedModuleIdsPlugin(),
new PreloadWebpackPlugin({
include: 'initial',
}),
new CssUrlRelativePlugin(),
],
devServer: {
contentBase: path.join(__dirname, 'src'),
},
optimization: {
runtimeChunk: 'single',
splitChunks: {
cacheGroups: {
vendor: {
test: /node_modules/,
chunks: 'initial',
name: 'vendor',
priority: 10,
enforce: true,
},
},
},
minimizer: [],
},
};
if (!IS_DEV) {
const TerserPlugin = require('terser-webpack-plugin');
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
config.optimization.minimizer.push(
new TerserPlugin(),
new OptimizeCSSAssetsPlugin({})
);
}
const files = glob.sync('./src/*.html');
files.forEach(file => {
config.plugins.push(
new HtmlWebPackPlugin({
filename: path.basename(file),
template: file,
favicon: path.resolve(__dirname, './src/public/icon.ico'),
minify: !IS_DEV,
})
);
});
module.exports = config;

Webpack is creating test and snapshot bundles

I've recently tried to add proper code splitting for the first time to one of my projects.
It's worked, however I think it's worked a little TOO well!
When I run bundle-analyser, my dist folder contains a bunch of other bundles that contain snapshots and test files and I can't find any information that would explain why this is happening!
here is my webpack.config.base.js
const path = require('path');
const postcssNested = require('postcss-nested');
const postcssSimpleVars = require('postcss-simple-vars');
const postcssPresetEnv = require('postcss-preset-env');
const postcssImport = require('postcss-import');
const postcssFor = require('postcss-for');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ExtractCssPluginConfig = new ExtractTextPlugin({
filename: '[name].[hash].css',
disable: false,
});
const HtmlWebpackPluginConfig = new HtmlWebpackPlugin({
template: './src/index.html',
filename: 'index.html',
inject: 'body',
});
module.exports = {
entry: {
main: './src/index.jsx',
},
output: {
path: path.resolve('_dist'),
chunkFilename: '[name].[hash].bundle.min.js',
filename: '[name].[hash].min.js',
publicPath: '/',
},
module: {
rules: [
{
test: /\.(js|jsx)?$/,
loader: 'babel-loader',
exclude: /node_modules\/(?!(dom7|ssr-window|swiper)\/).*/,
},
{
test: /\.css$/,
loader: 'style-loader',
},
{
test: /\.css$/,
loader: 'css-loader',
query: {
modules: true,
importLoaders: 1,
localIdentName: '[path]___[name]__[local]___[hash:base64:5]',
},
},
{
test: /\.css$/,
loader: 'postcss-loader',
options: {
plugins: () => [
postcssNested,
postcssImport,
postcssFor,
postcssPresetEnv({
browsers: '>1%',
autoprefixer: {
grid: true,
browsers: ['>1%'],
},
insertBefore: {
'all-property': postcssSimpleVars,
},
}),
],
},
},
{
test: /\.(png|jp(e*)g|svg)$/,
use: [{
loader: 'url-loader',
options: {
limit: 8000,
name: 'images/[hash]-[name].[ext]',
},
}],
},
{
test: /\.(woff|woff2|ttf|eot|otf)$/,
use: 'file-loader?name=fonts/[name].[ext]',
},
{
test: /\.(pdf)$/,
use: [{
loader: 'url-loader',
options: { limit: 8000, name: 'documents/[hash]-[name].[ext]' },
}],
},
],
},
resolve: {
extensions: ['.js', '.jsx', '.css', '.svg'],
modules: [path.resolve('./node_modules')],
alias: {
Pages: path.resolve(__dirname, 'src/pages/'),
Sections: path.resolve(__dirname, 'src/sections/'),
Components: path.resolve(__dirname, 'src/components/'),
Images: path.resolve(__dirname, 'src/images/'),
Downloads: path.resolve(__dirname, 'src/downloads/'),
Services: path.resolve(__dirname, 'src/services/'),
Enum: path.resolve(__dirname, 'src/enum/'),
Data: path.resolve(__dirname, 'src/data/'),
Utils: path.resolve(__dirname, 'src/utils/'),
Config: path.resolve(__dirname, 'src/config/'),
},
},
plugins: [
ExtractCssPluginConfig,
HtmlWebpackPluginConfig,
],
};
and here is my webpack.config.build.js
const webpack = require('webpack');
const merge = require('webpack-merge');
const WebpackCleanupPlugin = require('webpack-cleanup-plugin');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const baseConfig = require('./webpack.config.base');
const WebpackCleanupPluginConfig = new WebpackCleanupPlugin({
exclude: ['webpack.stats.json'],
quiet: true,
});
const CopyWebpackPluginConfig = new CopyWebpackPlugin([
{ from: './src/documents', to: './documents' },
]);
module.exports = () => {
const DefinePluginConfig = new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'production'),
});
return (
merge(baseConfig, {
optimization: {
runtimeChunk: 'single',
splitChunks: {
cacheGroups: {
commons: {
test: /[\\/]node_modules[\\/]/,
name: 'vendors',
chunks: 'initial',
enforce: true,
},
},
},
noEmitOnErrors: true,
concatenateModules: true,
minimizer: [
new UglifyJsPlugin({
cache: true,
parallel: true,
sourceMap: false,
}),
],
},
plugins: [
DefinePluginConfig,
WebpackCleanupPluginConfig,
CopyWebpackPluginConfig,
],
})
);
};
I've tried adding a regex that matches any files with .test.js/jsx and .snap to my module.rules object but that did nothing.
Any help would be greatly appreciated!
If your test files are in a different directory, you might want to consider adding exclude property within the modules rules for js files.
Refer the following document: https://webpack.js.org/configuration/module/?_sm_au_=iVVKrMW7ZsbHQPbq#rule-exclude
or the following example: https://webpack.js.org/configuration/?_sm_au_=iVVKrMW7ZsbHQPbq#options
Another solution would be to use the IgnorePlugin. Docs for IgnorePlugin here: https://webpack.js.org/plugins/ignore-plugin/?_sm_au_=iVVKrMW7ZsbHQPbq

Categories