The de-duplication feature in webpack is not functioning properly when the splitChunks cacheGroups commons option is activated

In my lerna project, I have two identical packages named p1 and p2.

Both p1 and p2 utilize a 3rd party package - in this case, eosjs@beta, which is approximately 50KB in size.

When I incorporate p1 into an example react project, the package size increases by 50KB as expected. However, when I add p2, the size grows by another 50KB, which is surprising.

One would assume that since p1 and p2 are using the same 3rd party library, only one reference to that library would be included in the example project compilation. But it appears that's not the case.

Link to example repo: https://github.com/warrick-eosny/sizetest

The increase in package size can be observed as follows:

ls examples/sizetest/build/static/js/ -lah

Before referencing p1

    117K 1.13eeb203.chunk.js     
    1.4K main.2170ea98.chunk.js  
    1.5K runtime~main.229c360f.js  

After referencing p1

    165K 1.75baab58.chunk.js  
    3.7K main.36960386.chunk.js  
    1.5K runtime~main.229c360f.js  

After referencing p1 and p2

    212K 1.57bb37cb.chunk.js  
    6.4K main.491260eb.chunk.js  
    1.5K runtime~main.229c360f.js  

The project in the examples folder was created using:

npx create-react-app sizetest –typescript

Both the p1 and p2 packages were created using:

yo node-typescript-webpack

Why does the example build keep growing? Shouldn't webpack be intelligent enough to include only one reference?

=============== UPDATE ==================

The "removing duplicate code" section here seems like it should solve my problem: https://developers.google.com/web/fundamentals/performance/optimizing-javascript/code-splitting/#spitting_code_by_multiple_entry_points

However, implementing these suggestions did not resolve the issue.

  1. I ran "yarn eject" in the project folder and then added the suggested config: https://github.com/warrick-eosny/sizetest/blob/master/examples/sizetest/config/webpack.config.js#L196-L211
  2. Removed the uglify section for readability purposes
  3. Ran the build again

This approach generated a commons file, but upon inspecting its content:

grep \@module build/static/js/commons.bd2f73cb.chunk.js

It is evident that the code is still duplicated:

 * @module Serialize
 * @module Numeric
 * @module RPC-Error
 * @module Serialize
 * @module Numeric
 * @module RPC-Error
 * @module API
 * @module JSON-RPC
 * @module API
 * @module JSON-RPC

Answer №1

The concept of a monorepo and the tool Lerna are not designed to make implicit "improvements" like what you're suggesting. This could lead to unintended consequences, such as conflicts arising if different packages within the monorepo depend on different versions of eosjs or if each package initializes its own instance of a package class.

Furthermore, deploying packages independently from each other is still possible within a monorepo because they do not rely on the same package reference.

As far as I know, utilizing a monorepo is the only way to achieve your desired outcome. However, keep in mind that while the monorepo centralizes your codebase, moving dependencies like eosjs up to the root level package.json can introduce unexpected challenges. You may need to manually manage this for self-maintained packages in the monorepo or utilize hoisting with Lerna for external packages: https://github.com/lerna/lerna/blob/master/doc/hoist.md

Yarn Workspaces, which Lerna uses under the hood for hoisting, can provide further insight into this process.

It's important to note that Webpack operates independently of Lerna or the concept of a monorepo unless specifically configured to recognize these structures.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Message displaying successful AJAX response

I'm currently updating my AJAX request to make it asynchronous, but I am wondering if there is an equivalent to var response = $.ajax({ in the success function. Previously, my code looked like this: var response = $.ajax({ type : "GET ...

Having trouble with jQuery UI draggable when using jQueryUI version 1.12.1?

Currently, I am diving into the world of jQuery UI. However, I am facing an issue with dragging the boxes that I have created using a combination of HTML and CSS. My setup includes HTML5 and CSS3 alongside jQuery version 1.12.1. Any suggestions or help wou ...

Element with adhesive properties alters its color at a particular location

I need the sticky element to change colors at specific points and then revert back to its original color. The color should be orange initially, green on block 2, and orange again on block 3. For the complete code and to address any issues with jQuery, pl ...

"Make sure to specify Safari input field as an email and mark

I am experiencing an issue with a contact form in my HTML/PHP code. Everything seems to be working fine, but when using the SAFARI browser, the form fails to validate if I try to submit without filling out all input fields. For example, my form includes: ...

Combining Typescript files with identical namespaces into a single file using Webpack 2

Recently, I've started using Webpack and bundling typescript files into a single file. Below is the setup I have where I aim to create a single JS file with all my typescript bundled together. tsconfig.json: { "compilerOptions": { "allowSynthe ...

Assign a predetermined value to a dropdown list within a FormGroup

I have received 2 sets of data from my API: { "content": [{ "id": 1, "roleName": "admin", }, { "id": 2, "roleName": "user", }, { "id": 3, "roleName": "other", } ], "last": true, "totalEleme ...

Ways to tally the amount of views on a post

Currently, I am in the process of developing a website that features posts. I have included a 'Read more' link which expands the content upon clicking, similar to Quora. However, I am facing an issue - I need to track the total number of times th ...

Is there a way to incorporate arguments into my discord.js commands?

Hey there! I'm looking to enhance my Discord commands by adding arguments, such as !ban {username}. Any tips or guidance on the best approach for this would be amazing! const Bot = new Discord.Bot({ intents: ["GUILD_MESSAGES", "GUIL ...

The element type provided is incorrect: it should be a string or a class/function, but an object was given instead

Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object. I'm currently working on an application using React JS with Spring Boot. I have successfully configured webpack, but ...

Encountered an unforeseen character 'u' in the initial position of the JSON while attempting to create a plugin

I seem to be encountering some issues with my code. Whenever I attempt to run the script in the developer kit, an error is thrown: unexpected token u in JSON at position 0... funciones.js $(document).ready(function (){ $("#btn1").click(funct ...

Encountering issues with installing traceur using NPM on macOS, errors are being thrown

https://github.com/tejas-manohar/itnerary-civic-hacking -- I recently downloaded this git repository to my local machine. After installing the grunt-cli globally, I tried running npm run nss (a script provided by the original server template author - check ...

Encountered a RangeError with NPM due to an invalid triggerAsyncId while trying to install Node.js 12.6.0 on Windows 10

Encountering a challenge after installing Nodejs v12.6.0 on Windows 10 Pro. Node version retrieval works fine, but attempting to check the NPM version returns an error. As a result, I am unable to run my Node application on this machine due to this issue. ...

in node.js, virtual machine scripts can import modules using the require function

I am currently developing a command-line interface using node.js that runs an external script > myapp build "path/to/script.js" myapp is a node.js application that executes the script provided as a command-line argument. In simple terms, it performs ...

Can someone explain how to use JavaScript to make table data fill the entire row in a table?

After clicking the button, the layout of the table changes. I want to keep the original table layout even after the JavaScript function runs. I am still learning about JavaScript. function toggle(button) { if(document.getElementById("1").value=="Show ...

The command `npm run build` encountered an error with an unknown option: `C:librarymy-app ode_modulesabel-preset-react-appindex.js

I have been struggling to successfully build my react package for publishing. Despite checking multiple resources, including stackoverflow and other websites, I am unable to find a solution that works for me. Here is an excerpt from my package.json: { " ...

AngularJS $cookies version 1.6.9 experiencing functionality issues

I recently implemented AngularJS $cookies 1.6.9 in my website to handle cookie management. To test it out, I attempted a basic cookie set like this: $cookies.put('myCookieTest', 'test'); var cookie = $cookies.get('myCookieTest&apo ...

Insert a design layout into a text entry box

Currently developing an application with AngularJS and seeking a solution for adding a "template" to an HTML input field similar to a placeholder. Specifically, I have a date-field requiring user input in the format of dd/MM/yyyy or through a datepicker se ...

Issue: Unable to locate element with the specified selector: #email

const puppeteer = require('puppeteer'); (async () => { const browser = await puppeteer.launch(); const page = await browser.newPage(); await page.goto('https://discord.com/register'); await page.screenshot({path: 'b.png ...

Steps for setting up an npm package without an internet connection

I am currently setting up a network that does not have an internet connection and need to integrate angular-cli using npm. I have obtained a zip file of angular-cli and am utilizing the most recent node and npm versions. When trying to install angular-cli ...

What is the proper procedure for entering data in the correct sequence using JavaScript?

I am currently utilizing Node.js to send data to a SQL Server table. Within the code, there is a for loop that calls a function triggering an insert statement (which will eventually transition to being a stored procedure). This loop iterates through variou ...