Webpack bundle behaviour different from 5.21.0 and 5.22.0 - javascript

I am doing some upgrades to node a package which uses webpack. The package used to use webpack 5.9 for generating a small bundle, then using eval() was extracting some js code.
This is the webpack conf:
function getBaseWebpackConfig() {
return {
context: path.resolve(__dirname, '../'),
mode: 'development',
entry: "./test/input/icon.js",
devtool: false,
output: {
path: outputDir,
filename: bundleFileName,
publicPath: '',
library: {
type: 'commonjs2',
}
},
module: {
rules: [
{
test: /\.svg/,
exclude: /node_modules/,
loader: svg-loader,
options: {}
}
]
}
}
}
Now, moving to 5.73.0, this behaviour has changed; tests stopped running. After doing some debug, I have found the following.
With webpack < 5.21.2 the bundle starts as:
module.exports =
/******/ (() => { // webpackBootstrap
/******/ var __webpack_modules__ = ({
With webpack > 5.22.0 the bundle starts as:
/******/ (() => { // webpackBootstrap
/******/ var __webpack_modules__ = ({
Essentially, it does not have a top module.exports anymore and this breaks the rest of the code.
I could not find any reason this. The changelog does not give me any clue. Might it be a bug?

I'm not a webpack expert. But, comparing yours with my webpack configs I created recently (using the latest webpack for a PWA app). My settings are inside a module.exports. Maybe that's why module.exports is not in your bundle. e.g.
module.exports = {
context: path.resolve(__dirname, '../'),
mode: 'development',
entry: "./test/input/icon.js",
devtool: false,
output: {
path: outputDir,
filename: bundleFileName,
publicPath: '',
library: {
type: 'commonjs2',
}
},
module: {
rules: [
{
test: /\.svg/,
exclude: /node_modules/,
loader: svg-loader,
options: {}
}
]
}
}
}
Plus I've got three webpack config files common,dev and prod and use merge to combine them.
e.g. my webpack.dev.js
const { merge } = require('webpack-merge');
const common = require('./webpack.common.js');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const ForkTsCheckerNotifierWebpackPlugin = require('fork-ts-checker-notifier-webpack-plugin');
const path = require('path');
module.exports = merge(common, {
mode: 'development',
devtool: 'inline-source-map',
output: {
filename: "[name].bundle.js",
},
module: {
},
plugins: [
new MiniCssExtractPlugin({
filename: "[name].css"
}),
new ForkTsCheckerNotifierWebpackPlugin(),
]
});

Related

Using web-worker in the library, but the chunk file can not be found in react application

There are two separate repo:
Library repo
React Web application
library provide 2 functions
func1 without using web-worker
func2 using web-worker
// func2
export const func2 = () => {
//.....
const worker = new Worker(new URL('./web-worker/worker.ts', import.meta.url));
//.....
}
bundle files from webpack5
then import it in react web application
func1 works fine
but got this error when I calling the func2
below is webpack config for the library
const path = require('path');
const config = {
mode: 'production',
entry: './src/index.ts',
module: {
rules: [
{
test: /.ts$/,
loader: 'babel-loader',
exclude: /node_modules/,
options: {
presets: ['#babel/preset-env', '#babel/preset-typescript'],
},
},
],
},
output: {
filename: "index.js",
path: path.resolve(__dirname, 'dist'),
publicPath: "/",
library: {
type: 'umd',
},
},
resolve: {
extensions: ['.ts', '.js'],
},
devtool: 'source-map',
};
module.exports = config

WebPack output.library.type var is undefined

I am learning WebPack with a shortcode. In the code, we are trying to calculate the cube and square. They will suppose to store in a variable as per the following webpack.config.js.
const webpack = require('webpack');
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const isDevelopment = process.env.NODE_ENV === 'development';
const config = {
entry: './src/index.ts',
output: {
path: path.resolve(__dirname, 'dist'),
library: {
type: 'var',
name: 'testVar'
},
filename: '[name].js'
},
mode: 'production',
plugins: [
new MiniCssExtractPlugin({
// Options similar to the same options in webpackOptions.output
// both options are optional
filename: "[name].css",
chunkFilename: "[id].css",
}),
new webpack.optimize.LimitChunkCountPlugin({
maxChunks: 1,
}),
new HtmlWebpackPlugin({
hash: true,
title: 'Video Player Play Ground',
myPageHeader: 'Sample Video Player',
template: './src/index.html',
filename: 'index.html'
})
],
module: {
rules: [
{
test: /\.s[ac]ss$/i,
exclude: /node_modules/,
use: [
// fallback to style-loader in development
MiniCssExtractPlugin.loader,
"css-loader",
"sass-loader",
],
},
{
test: /\.ts(x)?$/,
loader: 'ts-loader',
exclude: /node_modules/
},
{
test: /\.svg$/,
use: 'file-loader'
}
]
},
resolve: {
extensions: [
'.tsx',
'.ts',
'.js',
'.scss'
]
},
optimization: {
usedExports: true,
runtimeChunk: false,
minimize: false
}
};
module.exports = config;
As shown in the above config, we store the compiled javascript in the variable with the name "testVar".
The above approach working fine when we are using the following command line code "webpack --mode production"
In the final generated javascript file we have a line which equals to
testVar = webpack_exports;
Also, testVar.start is working fine.
But the above approach is not working when we are using the following command line "webpack serve --mode production" or "webpack serve"
When we run a local server, the testVar.start is undefined. I am not sure what I am doing wrong.
Following is the code we are using in the index.html file to call the start function, which we defined in our internal javascript
window.onload = function (){
alert(testVar);
console.log(testVar);
if(testVar.start !== undefined)
{
alert(testVar.start);
console.log(testVar.start);
testVar.start(3,2);
}
else {
alert("Start Function is undefined");
}
}
Also following is the code insight from index.ts and math.ts.
import {cube, square} from './math';
export function start(c:number, s:number) {
console.log(cube(c));
console.log(square(s));
}
export function square(x:number) {
return x * x;
}
export function cube(x:number) {
return x * x * x;
}
enter image description here
Finally, I got it working :-).
I need to add the following line in my webpack.config.js
devServer: {
injectClient: false
},
Following is the reference URL: https://github.com/webpack/webpack-dev-server/issues/2484
Don't forget to Vote it. Thanks.

My JavaScript asynchronous function is executed twice with webpack

My javascript asynchronous function is executed twice but I can't figure out why.
I am using webpack and only one file is loaded on the page this is my articles.js
// articles.js
async function test() {
console.log('test');
}
test().then((items) => {
// code here
}
I have twice "test" in the console
// webpack.config.js
const path = require("path");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
mode: "development",
entry: {
app: "./src/index.js",
articles: "./src/js/pages/articles.js",
},
output: {
filename: "[name].bundle.js",
path: path.resolve(__dirname, "dist"),
},
plugins: [new MiniCssExtractPlugin()],
module: {
rules: [
{
test: /\.s[ac]ss$/i,
use: [
// Translates CSS into CommonJS
MiniCssExtractPlugin.loader,
"css-loader",
// Compiles Sass to CSS
"sass-loader",
],
},
],
},
};
Thanks for your help

module.exports error for webpack backend (node.js)

I'm trying to use webpack to bundle my backend code. It's currently using vanilla node.js where I'm using module.exports.x, and when I run webpack, it also outputs the export line i.e. module.exports.x. Now the problem is when I run nodemon on the file, it gives me the error TypeError: Cannot set property 'x' of undefined.
What's my resolution here?
my config file.
"use strict"
const path = require("path")
// const utils = require("./utils")
// const config = require("../config")
var fs = require("fs")
const NodemonPlugin = require("nodemon-webpack-plugin")
const nodeExternals = require("webpack-node-externals")
function resolve(dir)
{
return path.join(__dirname, "..", dir)
}
module.exports = {
context: path.resolve(__dirname, "../"),
entry: "./src/server/server.js",
output: {
path: path.resolve(__dirname, "../src/server"),
filename: "server-webpack.js",
},
plugins: [
new NodemonPlugin(),
],
resolve: {
extensions: [".js",".ts", ".tsx"],
alias: {
"#": resolve("src"),
"#": resolve("src/server")
}
},
devtool: "#inline-source-map",
module: {
rules: [
{
test: /\.js$/,
loader: "babel-loader",
include: [resolve("src"), resolve("test")]
},
{
test: /\.tsx?$/,
loader: "ts-loader",
},
]
},
externals: [
nodeExternals()
],
target: "node"
}

Require is not defined on reflect-metadata - __webpack_require__ issue

I'm trying to launch my angular app on visual studio but when it starts, it stucks on "Loading..." section.
If i read Chrome's error console i get the following error:
Uncaught ReferenceError: require is not defined at Object. < anonymous > __ webpack_require __
The reflect-metadata contains the following: module.exports = require("reflect-metadata"); , which "require" causes the error.
Here's some of my code...
webpack.config.js
const path = require('path');
const webpack = require('webpack');
const merge = require('webpack-merge');
const AotPlugin = require('#ngtools/webpack').AotPlugin;
const CheckerPlugin = require('awesome-typescript-loader').CheckerPlugin;
var nodeExternals = require('webpack-node-externals');
module.exports = (env) => {
// Configuration in common to both client-side and server-side bundles
const isDevBuild = !(env && env.prod);
const sharedConfig = {
externals: [nodeExternals()], // in order to ignore all modules in node_modules folder
stats: { modules: false },
context: __dirname,
resolve: { extensions: [ '.js', '.ts' ] },
output: {
filename: '[name].js',
publicPath: 'dist/' // Webpack dev middleware, if enabled, handles requests for this URL prefix
},
module: {
rules: [
{ test: /\.ts$/, use: isDevBuild ? ['awesome-typescript-loader?silent=true', 'angular2-template-loader', 'angular2-router-loader'] : '#ngtools/webpack' },
{ test: /\.html$/, use: 'html-loader?minimize=false' },
{ test: /\.css$/, use: [ 'to-string-loader', 'style-loader', isDevBuild ? 'css-loader' : 'css-loader?minimize' ] },
{ test: /\.(png|jpg|jpeg|gif|svg)$/, use: 'url-loader?limit=25000' }
]
},
plugins: [new CheckerPlugin()]
};
// Configuration for client-side bundle suitable for running in browsers
const clientBundleOutputDir = './wwwroot/dist';
const clientBundleConfig = merge(sharedConfig, {
entry: { 'main-client': './ClientApp/boot.browser.ts' },
output: { path: path.join(__dirname, clientBundleOutputDir) },
plugins: [
new webpack.DllReferencePlugin({
context: __dirname,
manifest: require('./wwwroot/dist/vendor-manifest.json')
})
].concat(isDevBuild ? [
// Plugins that apply in development builds only
new webpack.SourceMapDevToolPlugin({
filename: '[file].map', // Remove this line if you prefer inline source maps
moduleFilenameTemplate: path.relative(clientBundleOutputDir, '[resourcePath]') // Point sourcemap entries to the original file locations on disk
})
] : [
// Plugins that apply in production builds only
new webpack.optimize.UglifyJsPlugin(),
new AotPlugin({
tsConfigPath: './tsconfig.json',
entryModule: path.join(__dirname, 'ClientApp/app/app.browser.module#AppModule'),
exclude: ['./**/*.server.ts']
})
])
});
// Configuration for server-side (prerendering) bundle suitable for running in Node
const serverBundleConfig = merge(sharedConfig, {
resolve: { mainFields: ['main'] },
entry: { 'main-server': './ClientApp/boot.server.ts' },
plugins: [
new webpack.DllReferencePlugin({
context: __dirname,
manifest: require('./ClientApp/dist/vendor-manifest.json'),
sourceType: 'commonjs2',
name: './vendor'
})
].concat(isDevBuild ? [] : [
// Plugins that apply in production builds only
new AotPlugin({
tsConfigPath: './tsconfig.json',
entryModule: path.join(__dirname, 'ClientApp/app/app.server.module#AppModule'),
exclude: ['./**/*.browser.ts']
})
]),
output: {
libraryTarget: 'commonjs',
path: path.join(__dirname, './ClientApp/dist')
},
target: 'node',
devtool: 'inline-source-map'
});
return [clientBundleConfig, serverBundleConfig];
};
Searching on the internet, all of the troubleshooting suggests doing something on the systemjs.config file but mine is not an angular-cli app so I can't do it.
UPDATES SECTION
UPDATE #1
Looks like the problem is caused by webpack-node-externals executed in browser mode.
Got to find another way for that.
Got any troubleshooting or potential solution suggestion?
Thanks in advance!
UPDATE #2
I've made it, see my answer below
GOT IT!
The issue was caused by webpack-node-externals used on my common configuration.
See my question and my answer to my own question at the following: Webpack - Excluding node_modules with also keep a separated browser and server management for more details.
So, in a nutshell, the steps that I followed are these:
Installing requireJS ==> http://requirejs.org/docs/node.html
Removing externals: [nodeExternals()], // in order to ignore all modules in node_modules folder from my common webpack configuration and adding it under my server configuration (done before my question, but it's a really important step) [see webpack.config.js content in the question linked right above in this answer or in the snippet below]
Adding target: 'node', before my externals point above, under my server side section (done before my question, but it's a really important step) [see webpack.config.js content in the question linked right above in this answer or in the snippet below]
This makes sure that browser side keeps target:'web' (default target), and target becomes node just for the server.
launched webpack config vendor command manually from powershell webpack --config webpack.config.vendor.js
launched webpack config command manually from powershell webpack --config webpack.config.js
That worked for me! Hope It will works also for anyone else reading this question and encountering this issue!
webpack.config.js content:
const path = require('path');
const webpack = require('webpack');
const merge = require('webpack-merge');
const AotPlugin = require('#ngtools/webpack').AotPlugin;
const CheckerPlugin = require('awesome-typescript-loader').CheckerPlugin;
var nodeExternals = require('webpack-node-externals');
module.exports = (env) => {
// Configuration in common to both client-side and server-side bundles
const isDevBuild = !(env && env.prod);
const sharedConfig = {
//removed from here, moved below.
//externals: [nodeExternals()], // in order to ignore all modules in node_modules folder
stats: { modules: false },
context: __dirname,
resolve: { extensions: [ '.js', '.ts' ] },
output: {
filename: '[name].js',
publicPath: 'dist/' // Webpack dev middleware, if enabled, handles requests for this URL prefix
},
module: {
rules: [
{ test: /\.ts$/, use: isDevBuild ? ['awesome-typescript-loader?silent=true', 'angular2-template-loader', 'angular2-router-loader'] : '#ngtools/webpack' },
{ test: /\.html$/, use: 'html-loader?minimize=false' },
{ test: /\.css$/, use: [ 'to-string-loader', 'style-loader', isDevBuild ? 'css-loader' : 'css-loader?minimize' ] },
{ test: /\.(png|jpg|jpeg|gif|svg)$/, use: 'url-loader?limit=25000' }
]
},
plugins: [new CheckerPlugin()]
};
// Configuration for client-side bundle suitable for running in browsers
const clientBundleOutputDir = './wwwroot/dist';
const clientBundleConfig = merge(sharedConfig, {
entry: { 'main-client': './ClientApp/boot.browser.ts' },
output: { path: path.join(__dirname, clientBundleOutputDir) },
plugins: [
new webpack.DllReferencePlugin({
context: __dirname,
manifest: require('./wwwroot/dist/vendor-manifest.json')
})
].concat(isDevBuild ? [
// Plugins that apply in development builds only
new webpack.SourceMapDevToolPlugin({
filename: '[file].map', // Remove this line if you prefer inline source maps
moduleFilenameTemplate: path.relative(clientBundleOutputDir, '[resourcePath]') // Point sourcemap entries to the original file locations on disk
})
] : [
// Plugins that apply in production builds only
new webpack.optimize.UglifyJsPlugin(),
new AotPlugin({
tsConfigPath: './tsconfig.json',
entryModule: path.join(__dirname, 'ClientApp/app/app.browser.module#AppModule'),
exclude: ['./**/*.server.ts']
})
])
});
// Configuration for server-side (prerendering) bundle suitable for running in Node
const serverBundleConfig = merge(sharedConfig, {
resolve: { mainFields: ['main'] },
entry: { 'main-server': './ClientApp/boot.server.ts' },
plugins: [
new webpack.DllReferencePlugin({
context: __dirname,
manifest: require('./ClientApp/dist/vendor-manifest.json'),
sourceType: 'commonjs2',
name: './vendor'
})
].concat(isDevBuild ? [] : [
// Plugins that apply in production builds only
new AotPlugin({
tsConfigPath: './tsconfig.json',
entryModule: path.join(__dirname, 'ClientApp/app/app.server.module#AppModule'),
exclude: ['./**/*.browser.ts']
})
]),
output: {
libraryTarget: 'commonjs',
path: path.join(__dirname, './ClientApp/dist')
},
//added target and externals HERE, in order to prevent webpack to read node_modules
//this also prevents fake-positives parsing errors
target: 'node',
externals: [nodeExternals()], // in order to ignore all modules in node_modules folder,
devtool: 'inline-source-map'
});
return [clientBundleConfig, serverBundleConfig];
};

Categories

Resources