UNPKG

3.04 kBJavaScriptView Raw
1/*
2 MIT License http://www.opensource.org/licenses/mit-license.php
3 Author Ivan Kopeykin @vankop
4*/
5
6"use strict";
7
8const makeSerializable = require("../util/makeSerializable");
9const NullDependency = require("./NullDependency");
10
11/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
12/** @typedef {import("../Dependency")} Dependency */
13/** @typedef {import("../Dependency").ExportsSpec} ExportsSpec */
14/** @typedef {import("../DependencyTemplate").CssDependencyTemplateContext} DependencyTemplateContext */
15/** @typedef {import("../ModuleGraph")} ModuleGraph */
16
17class CssLocalIdentifierDependency extends NullDependency {
18 /**
19 * @param {string} name name
20 * @param {[number, number]} range range
21 * @param {string=} prefix prefix
22 */
23 constructor(name, range, prefix = "") {
24 super();
25 this.name = name;
26 this.range = range;
27 this.prefix = prefix;
28 }
29
30 get type() {
31 return "css local identifier";
32 }
33
34 /**
35 * Returns the exported names
36 * @param {ModuleGraph} moduleGraph module graph
37 * @returns {ExportsSpec | undefined} export names
38 */
39 getExports(moduleGraph) {
40 const name = this.name;
41 return {
42 exports: [
43 {
44 name,
45 canMangle: true
46 }
47 ],
48 dependencies: undefined
49 };
50 }
51
52 serialize(context) {
53 const { write } = context;
54 write(this.name);
55 write(this.range);
56 write(this.prefix);
57 super.serialize(context);
58 }
59
60 deserialize(context) {
61 const { read } = context;
62 this.name = read();
63 this.range = read();
64 this.prefix = read();
65 super.deserialize(context);
66 }
67}
68
69const escapeCssIdentifier = (str, omitUnderscore) => {
70 const escaped = `${str}`.replace(
71 // cspell:word uffff
72 /[^a-zA-Z0-9_\u0081-\uffff-]/g,
73 s => `\\${s}`
74 );
75 return !omitUnderscore && /^(?!--)[0-9-]/.test(escaped)
76 ? `_${escaped}`
77 : escaped;
78};
79
80CssLocalIdentifierDependency.Template = class CssLocalIdentifierDependencyTemplate extends (
81 NullDependency.Template
82) {
83 /**
84 * @param {Dependency} dependency the dependency for which the template should be applied
85 * @param {ReplaceSource} source the current replace source which can be modified
86 * @param {DependencyTemplateContext} templateContext the context object
87 * @returns {void}
88 */
89 apply(
90 dependency,
91 source,
92 { module, moduleGraph, chunkGraph, runtime, runtimeTemplate, cssExports }
93 ) {
94 const dep = /** @type {CssLocalIdentifierDependency} */ (dependency);
95 const used = moduleGraph
96 .getExportInfo(module, dep.name)
97 .getUsedName(dep.name, runtime);
98 const moduleId = chunkGraph.getModuleId(module);
99 const identifier =
100 dep.prefix +
101 (runtimeTemplate.outputOptions.uniqueName
102 ? runtimeTemplate.outputOptions.uniqueName + "-"
103 : "") +
104 (used ? moduleId + "-" + used : "-");
105 source.replace(
106 dep.range[0],
107 dep.range[1] - 1,
108 escapeCssIdentifier(identifier, dep.prefix)
109 );
110 if (used) cssExports.set(used, identifier);
111 }
112};
113
114makeSerializable(
115 CssLocalIdentifierDependency,
116 "webpack/lib/dependencies/CssLocalIdentifierDependency"
117);
118
119module.exports = CssLocalIdentifierDependency;