W3Cschool
恭喜您成為首批注冊用戶
獲得88經(jīng)驗(yàn)值獎(jiǎng)勵(lì)
資源模塊(asset module)是一種模塊類型,它允許使用資源文件(字體,圖標(biāo)等)而無需配置額外 loader。
在 webpack 5 之前,通常使用:
raw-loader
? 將文件導(dǎo)入為字符串url-loader
? 將文件作為 data URI 內(nèi)聯(lián)到 bundle 中file-loader
? 將文件發(fā)送到輸出目錄資源模塊類型(asset module type),通過添加 4 種新的模塊類型,來替換所有這些 loader:
asset/resource
? 發(fā)送一個(gè)單獨(dú)的文件并導(dǎo)出 URL。之前通過使用 ?file-loader
? 實(shí)現(xiàn)。asset/inline
? 導(dǎo)出一個(gè)資源的 data URI。之前通過使用 ?url-loader
? 實(shí)現(xiàn)。asset/source
? 導(dǎo)出資源的源代碼。之前通過使用 ?raw-loader
? 實(shí)現(xiàn)。asset
? 在導(dǎo)出一個(gè) data URI 和發(fā)送一個(gè)單獨(dú)的文件之間自動(dòng)選擇。之前通過使用 ?url-loader
?,并且配置資源體積限制實(shí)現(xiàn)。當(dāng)在 webpack 5 中使用舊的 assets loader(如 ?file-loader
?/?url-loader
?/?raw-loader
? 等)和 asset 模塊時(shí),你可能想停止當(dāng)前 asset 模塊的處理,并再次啟動(dòng)處理,這可能會(huì)導(dǎo)致 asset 重復(fù),你可以通過將 asset 模塊的類型設(shè)置為 ?'javascript/auto'
? 來解決。
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.(png|jpg|gif)$/i,
use: [
{
loader: 'url-loader',
options: {
limit: 8192,
}
},
],
+ type: 'javascript/auto'
},
]
},
}
如需從 asset loader 中排除來自新 URL 處理的 asset,請?zhí)砑?nbsp;?dependency: { not: ['url'] }
? 到 loader 配置中。
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.(png|jpg|gif)$/i,
+ dependency: { not: ['url'] },
use: [
{
loader: 'url-loader',
options: {
limit: 8192,
},
},
],
},
],
}
}
webpack.config.js
const path = require('path');
module.exports = {
entry: './src/index.js',
output: {
filename: 'main.js',
path: path.resolve(__dirname, 'dist')
},
+ module: {
+ rules: [
+ {
+ test: /\.png/,
+ type: 'asset/resource'
+ }
+ ]
+ },
};
src/index.js
import mainImage from './images/main.png';
img.src = mainImage; // '/dist/151cfcfa1bd74779aadb.png'
所有 ?.png
? 文件都將被發(fā)送到輸出目錄,并且其路徑將被注入到 bundle 中,除此之外,你可以為它們自定義 ?outputPath
? 和 ?publicPath
? 屬性。
默認(rèn)情況下,?asset/resource
? 模塊以 ?[hash][ext][query]
? 文件名發(fā)送到輸出目錄。
可以通過在 webpack 配置中設(shè)置 ?output.assetModuleFilename
? 來修改此模板字符串:
webpack.config.js
const path = require('path');
module.exports = {
entry: './src/index.js',
output: {
filename: 'main.js',
path: path.resolve(__dirname, 'dist'),
+ assetModuleFilename: 'images/[hash][ext][query]'
},
module: {
rules: [
{
test: /\.png/,
type: 'asset/resource'
}
]
},
};
另一種自定義輸出文件名的方式是,將某些資源發(fā)送到指定目錄:
const path = require('path');
module.exports = {
entry: './src/index.js',
output: {
filename: 'main.js',
path: path.resolve(__dirname, 'dist'),
+ assetModuleFilename: 'images/[hash][ext][query]'
},
module: {
rules: [
{
test: /\.png/,
type: 'asset/resource'
- }
+ },
+ {
+ test: /\.html/,
+ type: 'asset/resource',
+ generator: {
+ filename: 'static/[hash][ext][query]'
+ }
+ }
]
},
};
使用此配置,所有 ?html
? 文件都將被發(fā)送到輸出目錄中的 ?static
? 目錄中。
?Rule.generator.filename
? 與 ?output.assetModuleFilename
? 相同,并且僅適用于 ?asset
? 和 ?asset/resource
? 模塊類型。
webpack.config.js
const path = require('path');
module.exports = {
entry: './src/index.js',
output: {
filename: 'main.js',
path: path.resolve(__dirname, 'dist'),
- assetModuleFilename: 'images/[hash][ext][query]'
},
module: {
rules: [
{
- test: /\.png/,
- type: 'asset/resource'
+ test: /\.svg/,
+ type: 'asset/inline'
- },
+ }
- {
- test: /\.html/,
- type: 'asset/resource',
- generator: {
- filename: 'static/[hash][ext][query]'
- }
- }
]
}
};
src/index.js
- import mainImage from './images/main.png';
+ import metroMap from './images/metro.svg';
- img.src = mainImage; // '/dist/151cfcfa1bd74779aadb.png'
+ block.style.background = `url(${metroMap})`; // url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDo...vc3ZnPgo=)
所有 ?.svg
? 文件都將作為 data URI 注入到 bundle 中。
webpack 輸出的 data URI,默認(rèn)是呈現(xiàn)為使用 Base64 算法編碼的文件內(nèi)容。
如果要使用自定義編碼算法,則可以指定一個(gè)自定義函數(shù)來編碼文件內(nèi)容:
webpack.config.js
const path = require('path');
+ const svgToMiniDataURI = require('mini-svg-data-uri');
module.exports = {
entry: './src/index.js',
output: {
filename: 'main.js',
path: path.resolve(__dirname, 'dist')
},
module: {
rules: [
{
test: /\.svg/,
type: 'asset/inline',
+ generator: {
+ dataUrl: content => {
+ content = content.toString();
+ return svgToMiniDataURI(content);
+ }
+ }
}
]
},
};
現(xiàn)在,所有 ?.svg
? 文件都將通過 ?mini-svg-data-uri
? 包進(jìn)行編碼。
webpack.config.js
const path = require('path');
- const svgToMiniDataURI = require('mini-svg-data-uri');
module.exports = {
entry: './src/index.js',
output: {
filename: 'main.js',
path: path.resolve(__dirname, 'dist')
},
module: {
rules: [
{
- test: /\.svg/,
- type: 'asset/inline',
- generator: {
- dataUrl: content => {
- content = content.toString();
- return svgToMiniDataURI(content);
- }
- }
+ test: /\.txt/,
+ type: 'asset/source',
}
]
},
};
src/example.txt
Hello world
src/index.js
- import metroMap from './images/metro.svg';
+ import exampleText from './example.txt';
- block.style.background = `url(${metroMap}); // url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDo...vc3ZnPgo=)
+ block.textContent = exampleText; // 'Hello world'
所有 .txt 文件將原樣注入到 bundle 中。
當(dāng)使用 ?new URL('./path/to/asset', import.meta.url)
?,webpack 也會(huì)創(chuàng)建資源模塊。
src/index.js
const logo = new URL('./logo.svg', import.meta.url);
根據(jù)你配置中 ?target
? 的不同,webpack 會(huì)將上述代碼編譯成不同結(jié)果:
// target: web
new URL(
__webpack_public_path__ + 'logo.svg',
document.baseURI || self.location.href
);
// target: webworker
new URL(__webpack_public_path__ + 'logo.svg', self.location);
// target: node, node-webkit, nwjs, electron-main, electron-renderer, electron-preload, async-node
new URL(
__webpack_public_path__ + 'logo.svg',
require('url').pathToFileUrl(__filename)
);
自 webpack 5.38.0 起,Data URLs 也支持在 ?new URL()
? 中使用了:
src/index.js
const url = new URL('data:,', import.meta.url);
console.log(url.href === 'data:,');
console.log(url.protocol === 'data:');
console.log(url.pathname === ',');
webpack.config.js
const path = require('path');
module.exports = {
entry: './src/index.js',
output: {
filename: 'main.js',
path: path.resolve(__dirname, 'dist')
},
module: {
rules: [
{
+ test: /\.txt/,
+ type: 'asset',
}
]
},
};
現(xiàn)在,webpack 將按照默認(rèn)條件,自動(dòng)地在 ?resource
? 和 ?inline
? 之間進(jìn)行選擇:小于 8kb 的文件,將會(huì)視為 ?inline
? 模塊類型,否則會(huì)被視為 ?resource
? 模塊類型。
可以通過在 webpack 配置的 module rule 層級中,設(shè)置 ?Rule.parser.dataUrlCondition.maxSize
? 選項(xiàng)來修改此條件:
webpack.config.js
const path = require('path');
module.exports = {
entry: './src/index.js',
output: {
filename: 'main.js',
path: path.resolve(__dirname, 'dist')
},
module: {
rules: [
{
test: /\.txt/,
type: 'asset',
+ parser: {
+ dataUrlCondition: {
+ maxSize: 4 * 1024 // 4kb
+ }
+ }
}
]
},
};
還可以 指定一個(gè)函數(shù) 來決定是否 inline 模塊。
在 asset 模塊和 webpack 5 之前,可以使用內(nèi)聯(lián)語法與上述傳統(tǒng)的 loader 結(jié)合使用。
現(xiàn)在建議去掉所有的內(nèi)聯(lián) loader 的語法,使用資源查詢條件來模仿內(nèi)聯(lián)語法的功能。
示例,將 ?raw-loader
? 替換為 ?asset/source
? 類型:
- import myModule from 'raw-loader!my-module';
+ import myModule from 'my-module?raw';
webpack 相關(guān)配置:
module: {
rules: [
// ...
+ {
+ resourceQuery: /raw/,
+ type: 'asset/source',
+ }
]
},
如果你想把原始資源排除在其他 loader 的處理范圍以外,請使用使用取反的正則:
module: {
rules: [
// ...
+ {
+ test: /\.m?js$/,
+ resourceQuery: { not: [/raw/] },
+ use: [ ... ]
+ },
{
resourceQuery: /raw/,
type: 'asset/source',
}
]
},
或者使用 ?oneOf
? 的規(guī)則列表。此處只應(yīng)用第一個(gè)匹配規(guī)則:
module: {
rules: [
// ...
+ { oneOf: [
{
resourceQuery: /raw/,
type: 'asset/source',
},
+ {
+ test: /\.m?js$/,
+ use: [ ... ]
+ },
+ ] }
]
},
對于像服務(wù)器端渲染這樣的用例,若是希望禁止生成資源,可以通過在? Rule.generator
? 下使用? emit
? 選項(xiàng)來實(shí)現(xiàn)。
module.exports = {
// …
module: {
rules: [
{
test: /\.png$/i,
type: 'asset/resource',
generator: {
emit: false,
},
},
],
},
};
Copyright©2021 w3cschool編程獅|閩ICP備15016281號-3|閩公網(wǎng)安備35020302033924號
違法和不良信息舉報(bào)電話:173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號
聯(lián)系方式:
更多建議: