In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-18 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/03 Report--
The main content of this article is to explain "how CommonJS leads to the increase in size after packaging". Interested friends may wish to take a look. The method introduced in this paper is simple, fast and practical. Let's let the editor take you to learn "how CommonJS leads to an increase in volume after packaging".
What is CommonJS?
CommonJS is a modular standard for JavaScript released in 2009, initially intended for use outside browsers, mainly for server-side applications.
You can use CommonJS to define modules and export some modules from them. For example, the following code defines a module that exports five functions: add, subtract, multiply, divide, max:
/ / utils.js const {maxBy} = require ('lodash-es'); const fns = {add: (a, b) = > a + b, subtract: (a, b) = > a-b, multiply: (a, b) = > a * b, divide: (a, b) = > a / b, max: arr = > maxBy (arr)}; Object.keys (fns) .forEach (fnName = > module.exports [fnName] = fns [fnName])
Other modules can import some of the functions of this module.
/ / index.js const {add} = require ('. / utils'); console.log (add (1,2))
Running index.js through node outputs the number 3 on the console.
In 2010, due to the lack of standardized modularity in browsers, CommonJS became a popular modular standard for JavaScript clients at that time.
How does CommonJS affect the package?
Server-side JavaScript programs are not as sensitive to code size as they are in browsers, which is why reducing the production package size is not considered when designing CommonJS. At the same time, the research table shows that the volume of JavaScript code is still an important factor affecting the page loading speed.
JavaScript's packaging tools (webpack, terser) make a number of optimizations to reduce the size of the resulting package. When they build, they will analyze your code and delete parts that will not be used as much as possible. For example, in the above code, the resulting package should contain only the add function, because this is the only part of index.js that is imported from utils.js.
Let's package the application with the following webpack configuration:
Const path = require ('path'); module.exports = {entry:' index.js', output: {filename: 'out.js', path: path.resolve (_ _ dirname,' dist'),}, mode: 'production',}
We need to specify the mode of webpack as production and use index.js as the entry. After running webpack, a file is output: dist/out.js, whose size can be counted as follows:
$cd dist & & ls-lah 625K Apr 13 13:04 out.js
The packaged files are as high as 625 KB. If you look at the out.js file, you will see that all the modules imported by utils.js into lodash are packaged into the output file, although we do not use any method of lodash in index.js, but this has a huge impact on our package.
Now let's change the modularization scheme of the code to the code in the ESM,utils.js section as follows:
Export const add = (a, b) = > a + b; export const subtract = (a, b) = > a-b; export const multiply = (a, b) = > a * b; export const divide = (a, b) = > a / b; import {maxBy} from 'lodash-es'; export const max = arr = > maxBy (arr)
Index.js is also changed to ESM to import modules from utils.js:
Import {add} from'. / utils'; console.log (add (1,2))
Using the same webpack configuration, after the construction is completed, we open out.js with only 40 bytes, and the output is as follows:
(() = > {"use strict"; console.log (1x2)}) ()
It is worth noting that the final output does not contain any code for utils.js, and lodash disappears. And terser (the compression tool used by webpack) inlines the add function directly into the console.log.
Some children may ask (Li Yongle syntax is used here), why the use of CommonJS will cause the output file to be 16000 times larger? Of course, this is just a case to show the difference between CommonJS and ESM, and there won't be such a big difference, but the use of CommonJS will definitely result in a larger package.
In general, the size of the CommonJS module is more difficult to optimize because it is more dynamic than the ES module. To ensure that the build and compression tools optimize your code successfully, avoid using CommonJS modules.
Of course, if you only use ESM's modular solution in utils.js, and index.js still maintains CommonJS, then the package will still be affected.
Why does CommonJS make the package larger?
To answer this question, we need to study the behavior of webpack's ModuleConcatenationPlugin and see how it is statically analyzed. The plug-in puts all the modules in a closure, which makes your code execute faster in the browser. Let's look at the following code:
/ / utils.js export const add = (a, b) = > a + b; export const subtract = (a, b) = > a-bbank / index.js import {add} from'. / utils'; const subtract = (a, b) = > a-b; console.log (add (1,2))
We have a new ESM module (utils.js), which we import into index.js, and we redefine a subtract function. Next, use the previous webpack configuration to build the project, but this time, I will disable the compression configuration.
Const path = require ('path'); module.exports = {entry:' index.js', output: {filename: 'out.js', path: path.resolve (_ _ dirname,' dist'),}, + optimization: {+ minimize: false +}, mode: 'production',}
The output out.js is as follows:
/ * / () = > {/ / webpackBootstrap / * / "use strict"; / / CONCATENATED MODULE:. / utils.js** const add = (a, b) = > a + b; const subtract = (a, b) = > a-b; / / CONCATENATED MODULE:. / index.js** const index_subtract = (a, b) = > a-b; console.log (add (1,2)); / * /}) ()
In the output code, all the functions are in one namespace, and to prevent conflicts, webpack renames the subtract function in index.js to the index_subtract function.
If the compression configuration is enabled, it does the following:
Hongmeng official Strategic Cooperation to build HarmonyOS Technology Community
Delete unused subtract and index_subtract functions
Delete all comments and spaces
Direct inline add function in console.log
Some developers will refer to this act of deleting unused code as "tree-shaking". Webpack can statically analyze utils.js by exporting and importing symbols (in the process of building), which makes tree-shaking feasible. When using ESM, this behavior is turned on by default because it is easier to analyze statically than CommonJS.
Let's look at another example, this time changing utils.js to a CommonJS module instead of an ESM module.
/ / utils.js const {maxBy} = require ('lodash-es'); const fns = {add: (a, b) = > a + b, subtract: (a, b) = > a-b, multiply: (a, b) = > a * b, divide: (a, b) = > a / b, max: arr = > maxBy (arr)}; Object.keys (fns) .forEach (fnName = > module.exports [fnName] = fns [fnName])
This small change obviously affects the output code. Because the output text is too large, we only show a small part of it.
() (() = > {"use strict"; / * harmony import * / var _ utils__WEBPACK_IMPORTED_MODULE_0__ = _ _ webpack_require__ (288); const subtract = (a, b) = > a-b; console.log (()
As you can see, the resulting code contains some webpack runtime code, which is responsible for the module's import and export capabilities. This time, all the variables of utils.js and index.js are not put under the same namespace, and the dynamically introduced modules are imported through _ _ webpack_require__.
When using CommonJS, we can construct the export name from any expression. For example, the following code also works:
Module.exports [(Math.random ())] = () = > {… }
This makes it impossible for the build tool to know the exported variable name at build time, because this name can only be determined when the user's browser is running. The compression tool does not know exactly which part of the module index.js uses, so it cannot tree-shaking correctly. If we import the CommonJS module from node_modules, your build tool will not be able to optimize it correctly.
Using Tree-shaking with CommonJS
Because CommonJS's modular solutions are dynamic, it is particularly difficult to analyze them. Compared to the CommonJS that imports the module through expressions, the import of the ESM module always uses static string text.
In some cases, if the library you are using follows some of the conventions of CommonJS, you can use a third-party webpack plug-in: webpack-common-shake, which removes unused modules during the build process. Although the plug-in adds CommonJS's support for tree-shaking, it doesn't cover all CommonJS dependencies, which means you can't get the same effect as ESM.
In addition, this is not the default behavior of webpack, it will add additional cost to your build time.
At this point, I believe you have a deeper understanding of "how CommonJS leads to the increase in volume after packaging". You might as well do it in practice. Here is the website, more related content can enter the relevant channels to inquire, follow us, continue to learn!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.