Webpack 5 - Módulos de ativos

Dia bom. Com este post, quero iniciar uma série de artigos sobre os novos recursos do próximo webpack 5. Por que quero falar sobre o webpack? Pelo menos porque participo ativamente de seu desenvolvimento e me aprofundo constantemente em seu interior. Neste post, quero falar sobre os módulos de ativos - um recurso experimental do webpack 5, que permite que você se livre de vários carregadores familiares, mantendo seus benefícios.


Imagine que precisamos montar uma página com fotos e estilos.


Solução Webpack 4


A configuração do webpack 4 para esta tarefa pode ser assim:
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;
}

Conclusão:


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

Com essa abordagem, todos os arquivos svg serão processados ​​usando svgo e usando o carregador de arquivos colocado no diretório com o pacote montado, e o css, usando o css-loader , se transformará em algo assim:


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

Em algum momento, podemos precisar otimizar nossa página e querer incorporar imagens diretamente em css. Para fazer isso, substitua file-loaderpor url-loader :


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

Conclusão:


/dist/main.js

O css compilado será alterado da seguinte maneira:


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

Além disso, podemos incorporar apenas os pequenos do tamanho de svg (por exemplo, até 8kb) e deixar o restante como arquivos separados. Para isso, url-loaderhá uma configuração de limite 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) -.


Obrigado pela atenção.


All Articles