How to use loader-utils

Comprehensive loader-utils code examples:

How to use loader-utils.interpolatename:

66
67
68
69
70
71
72
73
74
75

options.classIdPrefix =
    classIdPrefix === true ?
        displayName + '__' :
        typeof classIdPref === 'string' ?
            lutils.interpolatename(context, classIdPrefix) :
            classIdPrefix;

if (params.filters) {
    filters =

How to use loader-utils.slash:

147
148
149
150
151
152
153
154
155
156
compilation.resolvers.context.resolve({}, dirContext, spriteDir, (err, dir) => {
  if (!err) {
    const context = this.options.context
    const spriteName = Path.basename(spriteDir)
    const relativeDir = Path.relative(context, dir)
    const pattern = utils.slash(relativeDir + request.slice(spriteDir.length))
    done(null, pattern, spriteName)
    return
  }
  done(err)

How to use loader-utils.isUrlRequest:

96
97
98
99
100
101
102
103
104
105
	if (typeof importIndex === "number") {
		item.name = "___CSS_LOADER_IMPORT___" + importIndex + "___";
	}
	break;
case "url":
	if (options.url && item.url.replace(/\s/g, '').length && !/^#/.test(item.url) && loaderUtils.isUrlRequest(item.url)) {
		// Strip quotes, they will be re-added if the module needs them
		item.stringType = "";
		delete item.innerSpacingBefore;
		delete item.innerSpacingAfter;

How to use loader-utils.parseString:

67
68
69
70
71
72
73
74
75
76
}

var icss = icssUtils.extractICSS(css);
exports = icss.icssExports;
Object.keys(icss.icssImports).forEach(function(key) {
	var url = loaderUtils.parseString(key);
	Object.keys(icss.icssImports[key]).forEach(function(prop) {
		imports["$" + prop] = importItems.length;
		importItems.push({
			url: url,

How to use loader-utils.getCurrentRequest:

33
34
35
36
37
38
39
40
41
42
}

processCss(content, map, {
	mode: moduleMode ? "local" : "global",
	from: loaderUtils.getRemainingRequest(this).split("!").pop(),
	to: loaderUtils.getCurrentRequest(this).split("!").pop(),
	query: query,
	loaderContext: this,
	sourceMap: sourceMap
}, function(err, result) {

How to use loader-utils.getRemainingRequest:

32
33
34
35
36
37
38
39
40
41
	map = null;
}

processCss(content, map, {
	mode: moduleMode ? "local" : "global",
	from: loaderUtils.getRemainingRequest(this).split("!").pop(),
	to: loaderUtils.getCurrentRequest(this).split("!").pop(),
	query: query,
	loaderContext: this,
	sourceMap: sourceMap

How to use loader-utils.urlToRequest:

170
171
172
173
174
175
176
177
178
179
  preprocessPlugins = rootPlugins.slice(0, oursPluginIndex);
}

const definitionCache = new Map();
async function walkFile(from, dir, requiredDefinitions) {
  const request = importsAsModuleRequests ? urlToRequest(from) : from;
  const resolvedFrom = await resolve(concordContext, dir, request, resolveContext);

  const cached = definitionCache.get(resolvedFrom);
  if (cached) {

How to use loader-utils.parseQuery:

56
57
58
59
60
61
62
63
64

module.exports = function(source) { // source是字符串,包含静态资源的文件内容
  // webpack2 默认使用缓存,启动webpack-dev-server时,只热更新被修改的模块
  // 如果你想要禁止缓存功能,只要传入fasle参数即可
  // this.cacheable(false);  
  const params = loaderUtils.parseQuery(this.query);
  if (typeof params === "object" && params.signStr && typeof params.signStr === "string") {
    source = '<!-- ' + params.signStr + ' -->\n' + source;
  }

How to use loader-utils.getHashDigest:

19
20
21
22
23
24
25
26
27
28
const relativePath = path
  .relative(context.rootContext, context.resourcePath)
  .replace(/\\+/g, '/');

// Generate a hash to make the class name unique.
const hash = loaderUtils.getHashDigest(
  Buffer.from(`filePath:${relativePath}#className:${exportName}`),
  'md5',
  'base64',
  __DEV__ || localIdentNameFollowDev ? 4 : 8,

How to use loader-utils.stringifyRequest:

69
70
71
72
73
74
75
76
77
78
function importItemMatcher(item) {
	var match = result.importItemRegExp.exec(item);
	var idx = +match[1];
	var importItem = result.importItems[idx];
	var importUrl = importUrlPrefix + importItem.url;
	return "\" + require(" + loaderUtils.stringifyRequest(this, importUrl) + ").locals" +
		"[" + JSON.stringify(importItem.export) + "] + \"";
}

cssAsString = cssAsString.replace(result.importItemRegExpG, importItemMatcher.bind(this));

How to use loader-utils.getOptions:

290
291
292
293
294
295
296
297
298
299
```javascript
const loaderUtils = require('loader-utils');

module.exports = function(content) {
leanpub-start-insert
  const { name } = loaderUtils.getOptions(this);
leanpub-end-insert
  const url = loaderUtils.interpolateName(
leanpub-start-delete
    this, '[hash].[ext]', { content }

How to use loader-utils.interpolateName:

21
22
23
24
25
26
27
28
29
30
// 获取options,就是 webpack 中对 file-loader 的配置,比如这里我们配置的是 `name=[name]_[hash].[ext]`
// 获取到的就是这样一个k-v 对象 { name: "[name]_[hash].[ext]" }
const options = loaderUtils.getOptions(this) || {};

// 这是 loaderUtils 的一个方法,可以根据 name 配置和 content 内容 生成一个文件名。为什么需要 文件内容呢?这是为了保证当文件内容没有发生变化的时候,名字中的 [hash] 字段也不会变。可以理解为用文件的内容作了一个hash
let url = loaderUtils.interpolateName(this, options.name, {
  content
})

this.emitFile(url, content) // 告诉webpack,我要创建一个文件,文件名和内容,这样webpack就会帮你在 dist 目录下创建一个对应的文件