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-loader
con 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-loader
hay 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.