原文地址javascript
webpack loaders 從上手到理解系列
還有這些:vue
簡單來講,file-loader
就是在 JavaScript
代碼裏 import/require
一個文件時,會將該文件生成到輸出目錄,而且在 JavaScript
代碼裏返回該文件的地址。java
file-loader
npm install file-loader --save-dev
複製代碼
webapck
// webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.(png|jpg|gif)$/,
use: [
{
loader: 'file-loader',
options: {},
},
],
},
],
},
};
複製代碼
關於 file-loader
的 options
,這裏就很少說了,見 file-loader options .node
import
(或 require
)import logo from '../assets/image/logo.png';
console.log('logo的值: ', logo); // 打印一下看看 logo 是什麼
複製代碼
簡單三步就搞定了。webpack
webpack
複製代碼
執行 gitwebpack
打包以後,dist
目錄下會生成一個打包好的 bundle.js
,這個就很少說了。
若是使用了 file-loader
, dist
目錄這時候會生成咱們用到的那個文件,在這裏也就是 logo.png
。github
默認狀況下,生成到 dist
目錄的文件不會是原文件名,而是:**[原文件內容的 MD5 哈希值].[原文件擴展名]**
。web
回到上文,console.log(logo)
會打印什麼呢,咱們執 bundle.js
看看:npm
node dist/bundle.js
複製代碼
輸出結果是:json
logo的值: dab1fd6b179f2dd87254d6e0f9f8efab.png
複製代碼
如上所說,會返回文件的地址。
file-loader
的代碼很少,就直接貼在這了:
import path from 'path';
import loaderUtils from 'loader-utils'; // loader 工具包
import validateOptions from 'schema-utils'; // schema 工具包
import schema from './options.json'; // options schema
export default function loader(content) {
// 獲取 webpack 配置裏的 options
const options = loaderUtils.getOptions(this) || {};
// 校驗 options
validateOptions(schema, options, {
name: 'File Loader',
baseDataPath: 'options',
});
// 獲取 context
const context = options.context || this.rootContext;
// 根據 name 配置和 content 內容生成一個文件名
// 默認是 [contenthash].[ext],也就是根據 content 的 hash 來生成文件名
const url = loaderUtils.interpolateName(
this,
options.name || '[contenthash].[ext]',
{
context,
content,
regExp: options.regExp,
}
);
let outputPath = url;
// 若是配置了 outputPath,則須要作一些拼接操做
if (options.outputPath) {
if (typeof options.outputPath === 'function') {
outputPath = options.outputPath(url, this.resourcePath, context);
} else {
outputPath = path.posix.join(options.outputPath, url);
}
}
// __webpack_public_path__ 是 webpack 定義的全局變量,是 output.publicPath 的值
let publicPath = `__webpack_public_path__ + ${JSON.stringify(outputPath)}`;
// 一樣,若是配置了 publicPath,則須要作一些拼接操做
if (options.publicPath) {
if (typeof options.publicPath === 'function') {
publicPath = options.publicPath(url, this.resourcePath, context);
} else {
publicPath = `${ options.publicPath.endsWith('/') ? options.publicPath : `${options.publicPath}/` }${url}`;
}
publicPath = JSON.stringify(publicPath);
}
// 關於 postTransformPublicPath,能夠看一下 https://webpack.js.org/loaders/file-loader/#posttransformpublicpath
if (options.postTransformPublicPath) {
publicPath = options.postTransformPublicPath(publicPath);
}
if (typeof options.emitFile === 'undefined' || options.emitFile) {
// 讓 webpack 生成一個文件
this.emitFile(outputPath, content);
}
// TODO revert to ES2015 Module export, when new CSS Pipeline is in place
// 這裏能夠思考一下爲何返回的是 `module.exports = ${publicPath};`,而不是 publicPath
return `module.exports = ${publicPath};`;
}
// 默認狀況下 webpack 對文件進行 UTF8 編碼,當 loader 須要處理二進制數據的時候,須要設置 raw 爲 true
export const raw = true;
複製代碼