Find out how CommonJS modules are impacting your application tree change


Updated

It appears in:
Fast loading times

En esta publicación, veremos qué es CommonJS y por qué hace que sus paquetes de JavaScriptJavaScript es un lenguaje de programación que funciona en el lado del cliente y con el que las webs pueden ser más funcionales. Incorporación en código HTML El código JavaScript puede ser incrustado en las páginas HTML, para que adquieran funcionalidad. Existen varias opciones. Puede estar entre las etiquetas <SCRIPT> y </SCRIPT>, puede estar contenido en un archivo externo, puede ser un parámetro de las etiquetas HTML, y puede estar plus sean más grandes de lo necesario.

Summary: To ensure that the packager can successfully optimize your application, avoid relying on CommonJS modules and use the ECMAScript module syntax throughout your application.

What is CommonJS?

CommonJS es un estándar de 2009 que estableció convenciones para módulos JavaScript. Inicialmente estaba destinado a ser utilizado fuera del browserUn navegador (además: browser) es una herramienta informática que te permite ver documentos y datos y navegar por la red. Los navegadores pueden mostrar distintos tipos de recursos de información; principalmente documentos HTML, a pesar de todo, además son posibles otros tipos de archivos y contenido multimedia, como PDF, JPEG, MPEG, GIF o el lenguaje de meta marcado. A través el uso de complementos especiales y la configuración respectivo, los plus web, principalmente para aplicaciones del lado del serverLos servidores son ordenadores centrales y potentes dentro del campo de la tecnología de la información que procesan y proporcionan software y archivos en una red. Desde el punto de vista de un cliente, varios ordenadores en una red pueden ponerse en contacto con el servidor central para conseguir la información solicitada. En la arquitectura cliente-servidor, el servidor puede ser un software que proporciona un servicio y se ejecuta en plus.

With CommonJS you can define modules, export their functionality and import them into other modules. For example, the snippet below defines a module that exports five functions: add, subtract, multiply, divideand max:


const { maxBy } = require('lodash-es');
const fns = {
add: (to, b) => to + b,
subtract: (to, b) => to - b,
multiply: (to, b) => to * b,
divide: (to, b) => to / b,
max: arr => maxBy(arr)
};

Object.keys(fns).forEach(fnName => module.exports[fnName] = fns[fnName]);

Later, another module can import and use some or all of these functions:


const { add } = require('./utils');
console.log(add(1, 2));

Invoking indexUn index o índice es generalmente un directorio en un orden específico que se usa con fines de orientación. En términos de motores de búsqueda, un índice es la lista de páginas web que es emitido por el motor de búsqueda en respuesta a una solicitud de búsqueda del usuario. Información general La lista que se muestra posteriormente de introducir una solicitud de búsqueda específica se llama SERPs (Search Engine plus.js with do not give will output the number 3 on the console.

Due to the lack of a standardized module system in the browser in the early 2010s, CommonJS also became a popular module format for JavaScript client-side libraries.

How does CommonJS affect the final size of your package?

The size of your server-side JavaScript application is not as critical as it is in the browser, which is why CommonJS was not designed to reduce the size of the production package in mind. At the same time, analysis shows that JavaScript packet size is still the number one reason for slowing down browser applications.

JavaScript groupers and minifiers, such as webpack and terser, realice diferentes optimizaciones para reducir el tamaño de su aplicación. Al analizar su aplicación en el momento de la compilación, intentan eliminar tanto como sea posible del source codeEl código fuente es un programa de PC o página web que se convierte en un lenguaje que es leído por una máquina y se recoge en imagen y función. El código fuente es una parte importante del SEO porque determina la correcta ejecución de una página web. La optimización del código fuente es por ende parte del SEO técnico. Código fuente para páginas web Mientras que el código fuente plus que no está utilizando.

For example, in the snippet above, your final package should only include the add function since this is the only symbol of utils.js what do you matter in index.js.

Let's build the application using the following webpack setting:

const path = require('path');
module.exports = {
entry: 'index.js',
output: {
filename: 'out.js',
path: path.resolve(__dirname, 'dist'),
},
mode: 'production',
};

Here we specify that we want to use production mode optimizations and use index.js as an entry point. After invoking webpack, if we explore the exit size, we will see something like this:

$ CD dist &ampConcepto de AMP¿Qué es el AMP o Accelerated Mobile Pages?El AMP, abreviatura de Accelerated Mobile Pages, es una propuesta que empezó a tomar forma en el año 2016 con la finalidad de mejorar la usabilidad, lectura y, en general, la experiencia de los usuarios de teléfono celular dentro de cualquier página web. Emprendida por Google con un aperturismo total (es de código abierto), lleva en activo desde entonces para facilitar plus;& ls -lah
625K Apr 13 13:04 out.js

Realise package is 625KB. If we look at the output, we will find all the functions of utils.js plus many modules of lodash. Although we do not use lodash in index.js is part of the output, which adds a lot of additional weight to our production assets.

Now let's change the module format to ECMAScript modules and try again. This time, utils.js it would look like this:

export const add = (to, b) => to + b;
export const subtract = (to, b) => to - b;
export const multiply = (to, b) => to * b;
export const divide = (to, b) => to / b;

import { maxBy } desde 'lodash-es';

export const max = arr => maxBy(arr);

Y index.js would mind utils.js using the ECMAScript module syntax:

import { add } desde './utils';

console.log(add(1, 2));

Using the same webpack configuration, we can build our application and open the output file. Now it's 40 bytes with the following exit:

(()=>{"use strict";console.log(1+2)})();

Note that the final package does not contain any of the functions of utils.js that we don't use, and there's no trace of lodash! Even more, terser (the JavaScript minifier that webpack uses) in the add run on console.log.

A fair question you could ask is: Why does using CommonJS make the output packet almost 16,000 times larger?? Of course this is a toy example, actually the size difference may not be that great, but CommonJS will most likely add significant weight to your production build.

CommonJS modules are more difficult to optimize in the general case because they are much more dynamic than ES modules. To ensure that your stitcher and minifier can successfully optimize your application, avoid relying on CommonJS modules and use the ECMAScript module syntax throughout your application.

Note that even if you are using ECMAScript modules in index.jsIf the module you are consuming is a CommonJS module, your application's package size will be affected.

Why does CommonJS enlarge its application?

To answer this question, we will look at the behavior of ModuleConcatenationPlugin in webpack and, after that, discuss static analyzability. This plugin concatenates the scope of all your modules into a single closure and allows your code to have a faster execution time in the browser. Let's see an example:


export const add = (to, b) => to + b;
export const subtract = (to, b) => to - b;


import { add } desde './utils';
const subtract = (to, b) => to - b;

console.log(add(1, 2));

Above, we have an ECMAScript module, which we import into index.js. We also define a subtract function. We can build the project using the same webpack configuration as above, but this time, we will disable minimization:

const path = require('path');

module.exports = {
entry: 'index.js',
output: {
filename: 'out.js',
path: path.resolve(__dirname, 'dist'),
},
optimization: {
minimize: false
},
mode: 'production',
};

Let's see the output produced:

 (() => { 
"use strict";


const add = (to, b) => to + b;
const subtract = (to, b) => to - b;


const index_subtract = (to, b) => to - b;**
console.log(add(1, 2));**

})();

In the above output, all functions are within the same namespace. To avoid collisions, webpack renamed subtract run on index.js to index_subtract.

If a minifier processes the above source code, it will do the following:

  • Delete unused functions subtract and index_subtract
  • Remove all comments and redundant blanks
  • Tilt the body of the add function in the console.log call

This is often referred to by developers removal of unused imports such as tree shaking. Tree shaking was only possible because the web package was able to statically understand (at compile time) what symbols we are importing utils.js and what symbols it exports.

This behavior is enabled by default for ES modules Because they are more statically analyzable, compared to CommonJS.

Let's look at the exact same example, but this time change utils.js to use CommonJS instead of ES modules:


const { maxBy } = require('lodash-es');

const fns = {
add: (to, b) => to + b,
subtract: (to, b) => to - b,
multiply: (to, b) => to * b,
divide: (to, b) => to / b,
max: arr => maxBy(arr)
};

Object.keys(fns).forEach(fnName => module.exports[fnName] = fns[fnName]);

This little update will significantly change the output. Since it is too long to insert on this page, I have only shared a small part:

...
(() => {

"use strict";
var _utils__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(288);
const subtract = (to, b) => to - b;
console.log((0,_utils__WEBPACK_IMPORTED_MODULE_0__ .IH)(1, 2));

})();

Notice that the final package contains some webpack "Runtime": injected code that is responsible for importing / exporting the functionality of the packed modules. This time, instead of placing all the symbols of utils.js and index.js under the same namespace, we dynamically require, at runtime, the add function using __webpack_require__.

This is necessary because with CommonJS we can get the export name from an arbitrary expression. For example, the following code is an absolutely valid construct:

module.exports[localStorage.getItem(Math.random())] = () => { … };

There is no way for the packager to know at compile time what the name of the exported symbol is, as this requires information that is only available at run time, in the context of the user's browser.

In this way, the minifier is unable to understand what exactly is index.js uses its dependencies so you can't get rid of it. We will also observe the exact same behavior for third-party modules. If we import a CommonJS module from node_modules, your build toolchain will not be able to optimize it properly.

Shake trees with CommonJS

CommonJS modules are much more difficult to parse as they are dynamic by definition. For example, the import location in ES modules is always a string literal, compared to CommonJS, where it is an expression.

In some cases, if the library you are using follows specific conventions on how it uses CommonJS, it is possible to remove unused exports at build time using a third party webpack plug. Although this plugin adds support for tree shaking, it doesn't cover all the different ways your dependencies might use CommonJS. This means that you do not get the same guarantees as with ES modules. Also, add an additional cost as part of your build process on top of the default webpack behaviour.

conclusion

To ensure that the packager can successfully optimize your application, avoid relying on CommonJS modules and use the ECMAScript module syntax throughout your application.

Here are some practical tips to verify that you are on the optimal path:

  • Use Rollup.js's nodejs resolution
    pluginConcepto de Plugin¿Qué es un Plugin?Un Plugin es un fragmento o componente de código hecho para ampliar las funciones de un programa o de una herramienta. En el ámbito del marketing digital, especialmente dentro del marketing de contenidos, es algo que se utiliza con mucha frecuencia dentro de entornos como WordPress, puesto que sirven al momento de contar con añadidos que hagan mucho más cómoda y completa la experiencia de plus and set the modulesOnly checkmark to specify that you want to depend only on ECMAScript modules.
  • Use the package is-esm

    to verify that an npm package uses ECMAScript modules.

  • If you are using Angular, by default you will get a warning if it depends on modules that cannot be tree shaken.