Issue 1:
Bug report

What is the current behavior?

I have an issue after upgrade to webpack 5, we have internal components as npm packages and services that use those components and we have the following issue:

Package A have the following folder structure:

src

theme

default-theme.ts

views

Component.tsx

index.ts

Service has the following folder structure

src

theme

default-theme.ts

exported

ExportedView.tsx

index.ts

After we run build in the service, default-theme of Package A gets replaced by default-theme of the service.

This does not happen if the 2 files have different paths or different name.

This happens with all files that have same name and same path.

What is the expected behavior?

default-theme from the services should not override the package default-theme.

Other relevant information:

webpack version: 5.60.0

Node.js version: 14

Operating System: Mac

Additional tools:

Current webpack configuration:

const webpack = require('webpack');

const { merge } = require('webpack-merge');

const externalsConfig = require('./webpack.externals');

const paths = require('../paths');

const serviceName = require(paths.appPackageJson).name.

const fs = require('fs');

const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');

const DuplicatePackageCheckerPlugin = require(paths.scriptModule(

'duplicate-package-checker-webpack-plugin'

));

let packages = fs.existsSync(paths.localDependencies)

? require(paths.localDependencies).packages

: {};

const svgInlineOptions = {

template: (

{ template },

opts,

{ imports, componentName, props, jsx, exports }

) => template.ast`

${imports}

const ${componentName} = (${props}) => {
return ${jsx};
};

export default ${componentName};
`,

};

module.exports = () => {

const entryPoints = {

bundle: paths.appIndex

};

const commonConfigs = {

entry: entryPoints,

output: {

filename: '[name].js',

path: paths.appBuild,

libraryTarget: 'umd',

chunkFilename: '[name].[contenthash].bundle.js',

devtoolNamespace: serviceName,

library: serviceName

},

context: paths.appPath,

resolve: {

extensions: ['.ts', '.tsx', '.js', '.jsx', '.json', '.webpack.js', '.web.js'],
alias: packages || {},
fallback: {
child_process: false,
fs: false,
crypto: false,
net: false,
tls: false,
tty: require.resolve("tty-browserify"),
"http": require.resolve("stream-http"),
"https": require.resolve("https-browserify"),
path: require.resolve('path-browserify')
}
},

stats: {
// Examine all modules
modulesSpace: Infinity,
// Display bailout reasons
optimizationBailout: true
},
module: {
rules: [
{
test: /\.tsx?$/,
use: [
{
loader: paths.scriptModule('esbuild-loader'),
options: {
loader: 'tsx',
target: 'es2015',
}
}
],
},
{
test: /\.eot(\?.*)?$/,
use: [{
loader: paths.scriptModule('file-loader?name=fonts/[content-hash].[ext]')
}]
},
{
test: /\.css?$/,
use: [{loader:paths.scriptModule('style-loader/useable')},{loader: paths.scriptModule('raw-loader')}
]
},
{
test: /\.svg(\?.*)?$/,
use: [{
loader: paths.scriptModule(
'url-loader?limit=10000&mimetype=image/svg+xml&name=fonts/[content-hash].[ext]'
) }],
exclude: /\.inline.svg$/
},
{
test: /\.inline.svg$/,
use: [
{
loader: paths.scriptModule('@svgr/webpack'),
options: svgInlineOptions
},
],
},
{
test: /\.(jpe?g|png|gif)$/i,
use: [{
loader: paths.scriptModule('url-loader?limit=1000&name=images/[content-hash].[ext]')
}]
},
{
test: /\.scss$/,
use: [{
loader: paths.scriptModule('style-loader/useable'),
},{
loader: paths.scriptModule('css-loader'),
},{
loader: paths.scriptModule('sass-loader')
}
]
},
{
test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/,
loader: paths.scriptModule('url-loader')
},
{
test: /\.(ttf|eot)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
loader: paths.scriptModule('file-loader')
},
{
test: /font-awesome\.config\.js/,
loader: paths.scriptModule('style-loader')
}
]
},
plugins: [
new ForkTsCheckerWebpackPlugin(),
new webpack.LoaderOptionsPlugin({
options: {
tslint: {
failOnHint: true
}
}
}),
new DuplicatePackageCheckerPlugin({
verbose: true,
emitError: false,
showHelp: true,
strict: true
}),
new webpack.ProvidePlugin({
process: 'process/browser'
}),
],
node: {}
};

return merge(externalsConfig, commonConfigs);

};

Issue 2:
While porting a pre-existing application over to webpack I ran into an issue while cleaning up dependencies. The current setup is that 3rd party (vendor) libraries would go in a 'vendor' chunk and application global ones in 'global'. There are various entry points in the application (not single-page) and thus the grouping helps with de-duplication.

To make this work I created a vendor and global entry, hoping to rely on CommonsChunkPlugin to resolve duplicates. This appears to work, but only partially. A test case of my setup is listed below, but the result is that global-1.js, which main.js requires, makes it both in the generated global.js as well as main.js, rather than just in the global.js. If in the config I move the entry of global-1.js to the vendor chunk, it does properly exclude the chunk from the generated main.js.

Files for repro case:

webpack.config.js:

'use strict';

var path = require("path");
var webpack = require("webpack");

module.exports = {
entry: {
vendor: [
"./modules/vendor-1",
"./modules/vendor-2",
],
global: [
"./modules/global-1.js",
"./modules/global-2.js",
],

main: "./main.js",
},
plugins: [
// XXX: there appears to be a bug in webpack here, even though a chunk
// is common to global and main, it makes it into both. The plugin
// only appears to work properly for the first instantiation (vendor).
new webpack.optimize.CommonsChunkPlugin("vendor", "vendor.js", Infinity),
new webpack.optimize.CommonsChunkPlugin("global", "global.js", Infinity),
],
output: {
path: path.join(__dirname, "js"),
filename: "[name].js",
}
};

main.js:

require("./modules/vendor-1")
require("./modules/vendor-2")
require("./modules/global-1.js")

modules/vendor-1.js:

// vendor-1

modules/vendor-2.js:

// vendor-1

modules/global-1.js:

// global-1

modules/global-2.js:

// global-2

global.js output:

webpackJsonp([2],[
/* 0 */
/***/ function(module, exports, __webpack_require__) {

__webpack_require__(3);
module.exports = __webpack_require__(4);

/***/ },
/* 1 */,
/* 2 */,
/* 3 */
/***/ function(module, exports, __webpack_require__) {

// global-1

/***/ },
/* 4 */
/***/ function(module, exports, __webpack_require__) {

// global-2

/***/ }
]);

generated main.js output, note the global-1 section that also appears in the generated global.js:

webpackJsonp([0],[
/* 0 */
/***/ function(module, exports, __webpack_require__) {

__webpack_require__(1)
__webpack_require__(2)
__webpack_require__(3)

/***/ },
/* 1 */,
/* 2 */,
/* 3 */
/***/ function(module, exports, __webpack_require__) {

// global-1

/***/ }
]);