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-loader
por 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-loader
há 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.