Webpack 5 - Módulos de activos

Buen día. Con esta publicación quiero comenzar una serie de artículos sobre las nuevas características del próximo paquete web 5. ¿Por qué quiero hablar sobre el paquete web? Al menos porque participo activamente en su desarrollo y constantemente profundizo en su interior. En esta publicación, quiero hablar sobre los módulos de activos, una característica experimental de webpack 5, que le permite deshacerse de varios cargadores familiares, mientras mantiene su beneficio.


Imagine que necesitamos armar una página con imágenes y estilos.


Solución Webpack 4


La configuración de webpack 4 para esta tarea puede verse así:
webpack.config.js


module.exports = {
  module: {
    rules: [
      {
        test: /\.svg$/,
        use: [
          'file-loader',
          'svgo-loader'
        ]
      },
      {
        test: /\.css$/,
        use: [
          'style-loader',
          'css-loader'
        ]
      }
    ]
  }
};

src/index.js


import './styles.css';

// ...

src/styles.css


.logo {
  background: url("/images/logo.svg") no-repeat;
  background-size: cover;
  width: 75px;
  height: 65px;
}

Conclusión:


/dist/main.js
/dist/eb4c5fa504857.svg

Con este enfoque, todos los archivos svg se procesarán usando svgo y usando el cargador de archivos ubicado en el directorio con el paquete ensamblado, y css, usando css-loader , se convertirá en algo como esto:


.logo {
  background: url("eb4c5fa504857.svg") no-repeat;
  background-size: cover;
  width: 75px;
  height: 65px;
}

En algún momento, es posible que necesitemos optimizar nuestra página y queramos insertar imágenes directamente en línea en CSS. Para hacer esto, reemplace file-loadercon url-loader :


      {
        test: /\.svg$/,
        use: [
-         'file-loader',
+         'url-loader',
          'svgo-loader'
        ]
      },

Conclusión:


/dist/main.js

El CSS compilado cambiará de la siguiente manera:


-   background: url("eb4c5fa504857.svg") no-repeat;
+   background: url("data:image/svg+xml;base64,....") no-repeat;

Además, es posible que queramos en línea solo los pequeños de tamaño svg (por ejemplo, hasta 8kb), y dejar el resto como archivos separados. Para esto, url-loaderhay una configuración de límite especial:


      {
        test: /\.svg$/,
        use: [
-         'url-loader',
+         'url-loader?limit=8192',
          'svgo-loader'
        ]
      },

, svg- 8, svg , url-loader file-loader.


, webpack 5 Asset Modules, , url-loader file-loader ( url-loader , , limit).


webpack 5


, , Asset Modules. :


module.exports = {
  // ...
+ experiments: {
+   asset: true
+ }
};

.


, svg- asset , file-loader url-loader — , , - :


      {
        test: /\.svg$/,
-       use: [
-         'url-loader?limit=8000',
-         'svgo-loader'
-       ]
+       type: 'asset',
+       use: 'svgo-loader'
      },

, , type: 'asset' : 8 ( ), , .
use .


asset .


asset/inline


url-loader. , type: 'asset/inline' data-url:


      {
        test: /\.svg$/,
-       type: 'asset',
+       type: 'asset/inline',
        use: 'svgo-loader'
      },

, type: 'asset/inline' data-url.
, svg- mini-svg-data-uri, svg data-url, base64, :


+ const miniSVGDataURI = require('mini-svg-data-uri');
// ...
      {
        test: /\.svg$/,
        type: 'asset/inline',
+       generator: {
+         dataUrl(content) {
+           content = content.toString();
+           return miniSVGDataURI(content);
+         }
+       },
        use: 'svgo-loader'
      },

css:


-   background: url("data:image/svg+xml;base64,....") no-repeat;
+   background: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg'....") no-repeat;

data-url.


asset/resource


file-loader. , type: 'asset/resource' :


      {
        test: /\.svg$/,
-       type: 'asset/inline',
+       type: 'asset/resource',
-       generator: {
-         dataUrl(content) {
-           content = content.toString();
-           return miniSVGDataURI(content);
-         }
-       },
        use: 'svgo-loader'
      },


, asset/resource , output.path ( dist), output.assetModuleFilename :


module.exports = {
+ output: {
+   assetModuleFilename: 'assets/[name][ext]'
+ },
  // ...
};

:


/dist/main.js
/dist/assets/logo.svg

[name] [hash] long term caching:


module.exports = {
  output: {
-    assetModuleFilename: 'assets/[name][ext]'
+    assetModuleFilename: 'assets/[hash][ext]'
  },
  // ...
};

:


/dist/main.js
/dist/assets/eb4c5fa504857.svg

, asset-. , svg- dist/icons, asset- dist/assets:


      {
        test: /\.svg$/,
        type: 'asset/resource',
+       generator: {
+         filename: 'icons/[hash][ext]'
+       },
        use: 'svgo-loader'

:


/dist/main.js
/dist/assets/fd441ca8b6d00.png
/dist/icons/eb4c5fa504857.svg

asset/source


raw-loader. , type: 'asset/source' :
file.txt


hello world

webpack.config.js


module.exports = {
       // ...
      {
        test: /\.svg$/,
        type: 'asset/resource',
        generator: {
          filename: 'icons/[hash][ext]'
        },
        use: 'svgo-loader'
      },
+     {
+       test: /\.txt$/,
+       type: 'asset/source'
+     },
      // ...

index.js


import './styles.css';
+ import txt from './file.txt';

+ console.log(txt); // hello world

:


/dist/main.js
/dist/icons/eb4c5fa504857.svg

asset


asset/resource asset/inline, - , . , 8, asset/resource, — asset/inline.


module.exports = {
       // ...
      {
        test: /\.svg$/,
-       type: 'asset/resource',
+       type: 'asset'
-        generator: {
-          filename: 'icons/[hash][ext]'
-        },
        use: 'svgo-loader'
      },
      {
        test: /\.txt$/,
        type: 'asset/source'
      },
      // ...

asset/inline :


      {
        test: /.svg$/,
        type: 'asset',
+       parser: {
+         dataUrlCondition: {
+           maxSize: 20 * 1024 // 20kb
+         }
+       },
        use: 'svgo-loader'
      },

: Asset Modules webpack 5 " ".
.


webpack 5?


. , webpack 5 beta.13, . , webpack 5 ( , production).


P.S


webpack 5 webpack. , , ( webpack) -.


Gracias por la atención.


All Articles