Last week, I encountered the biggest work crisis since I joined the company. After the accident, I feel like I’ve suddenly grown up.

background

At 12:30 last week, my colleague reported that there was something wrong with one of our pages. I went to bed early that day, and then my leader woke up at 1:30 and helped me roll back the version in the afternoon.

Bug screen

And then wake up the next day and see those records. Alas, mixed feelings.

I started to check the bugs after I came to the company

This bug is really quite hidden. After checking all morning, I found that it was related to a vendor and the error was reported from vendor. In this page, I try to use Webpack for the first time to split out vendor, put those public, framework-related in this file, including vue, iscroll, etc. Since I thought that the frame would not change for a long time, I wanted to put the vendor file as a long cache on the page, so I didn’t hash the VERSION value of the JS resource. Remembering this, I wondered if the vendor file cache was causing the error. I downloaded the online vendor and ran it in the local page, and an error was reported. Then I run the new local vendor without any error. It seems that there is a problem with the old and new vendor, but I was puzzled at that time, and the error page was not modified in that release. Including these frameworks.

At this moment, the leader came to ask the reason. I replied that the framework had been upgraded, which led to the error. As long as the vendor was updated, it would be all right. But I could not give a more specific explanation, so the leader asked me to check the problem again.

Bug in-depth investigation

Since these two vendors are different, what is the difference? At the beginning, I thought of this. Both vendors are compressed codes that come out after webpack. It depends on the difference between the two files. But there’s no other way in, so we have to go this way. In order to compare the differences between the two, I downloaded a software called Beyond Compare and imported the online vendor and the updated vendor. The e first difference was the number. Oh, my God, what the hell are those numbers. (I’m not really familiar with webpack packaging.)

Gradually there is a dawn. So why is there a block missing? I checked git’s change history. In that release, there were no changes to the current page code, no more or less files, and no changes to package.json. Why is the final packaged vendor less than a small piece? Json: webpack –profile –json > compilation-stat. Json: webpack –profile –json > compilation-stat. This command is used to check why js files are so large.

Using this command, you can view each module in webpack and the moduleId, which is 220 and 219 mentioned above. Switch branches on Git, pack twice before and after code changes, and generate two compilation-stat.json to see the comparison. The output json can be seen as follows:

You can see all the moudule wrapped by WebPack, with the corresponding moduleId. There is also the name attribute, which you can see is the corresponding source file.

Armed with this information, I began to compare the difference between the two packages. I searched every block and finally determined that the updated vendor lacked a module.

The truth

One JS was missing, resulting in a tragedy. But why is axios missing a file? There is no version change in package.json.

Using the NPM ls command, it was discovered that the version number of Axios was indeed different, and that there was a minor update, which caused the new version of Axios to miss a bota.js file.

But we have always added a package-lock.json file to lock the version number, which may be due to the conflict of package-lock file during the development of different people. I then deleted the package-lock file and re-created NPM install to generate it, potentially causing the component to inadvertently upgrade in the process.

Package-lock conflict: checkout the package-lock.json file and then install the required components.

analyse

In fact, all this is because vendor js was used as a resource with no hash value for long cache during development. There are two things wrong with this:

  1. Component files do not change
  2. A different hash is generated each time the file is packaged (the hash does not change until the file changes)

This is due to the long cache. During the process of checking this problem, I gradually learned that it is difficult to ensure that the file is not changed when the moduleId is numeric, which will lead to the change of vendor file even if the component is not modified. That is, a stable moduleId cannot be generated without processing. There are also ways to generate a stable moduleId, which will be used in production later.

In the final analysis, I was still not familiar with Webpack packaging and had a vague understanding of some concepts of Webpack packaging, which resulted in inability to skillfully use some features or even errors. Therefore, I decided to take a closer look at the packaging process and principle of Webpack.