UNPKG

5.28 kBJavaScriptView Raw
1"use strict";
2
3const NativeModule = require("module");
4
5const path = require("path");
6/** @typedef {import("webpack").Compilation} Compilation */
7
8/** @typedef {import("webpack").Module} Module */
9
10/** @typedef {import("webpack").LoaderContext<any>} LoaderContext */
11
12/**
13 * @returns {boolean}
14 */
15
16
17function trueFn() {
18 return true;
19}
20/**
21 * @param {Compilation} compilation
22 * @param {string | number} id
23 * @returns {null | Module}
24 */
25
26
27function findModuleById(compilation, id) {
28 const {
29 modules,
30 chunkGraph
31 } = compilation;
32
33 for (const module of modules) {
34 const moduleId = typeof chunkGraph !== "undefined" ? chunkGraph.getModuleId(module) : module.id;
35
36 if (moduleId === id) {
37 return module;
38 }
39 }
40
41 return null;
42}
43/**
44 * @param {LoaderContext} loaderContext
45 * @param {string | Buffer} code
46 * @param {string} filename
47 * @returns {object}
48 */
49
50
51function evalModuleCode(loaderContext, code, filename) {
52 // @ts-ignore
53 const module = new NativeModule(filename, loaderContext); // @ts-ignore
54
55 module.paths = NativeModule._nodeModulePaths(loaderContext.context); // eslint-disable-line no-underscore-dangle
56
57 module.filename = filename; // @ts-ignore
58
59 module._compile(code, filename); // eslint-disable-line no-underscore-dangle
60
61
62 return module.exports;
63}
64/**
65 * @param {string} a
66 * @param {string} b
67 * @returns {0 | 1 | -1}
68 */
69
70
71function compareIds(a, b) {
72 if (typeof a !== typeof b) {
73 return typeof a < typeof b ? -1 : 1;
74 }
75
76 if (a < b) {
77 return -1;
78 }
79
80 if (a > b) {
81 return 1;
82 }
83
84 return 0;
85}
86/**
87 * @param {Module} a
88 * @param {Module} b
89 * @returns {0 | 1 | -1}
90 */
91
92
93function compareModulesByIdentifier(a, b) {
94 return compareIds(a.identifier(), b.identifier());
95}
96
97const MODULE_TYPE = "css/mini-extract";
98const AUTO_PUBLIC_PATH = "__mini_css_extract_plugin_public_path_auto__";
99const ABSOLUTE_PUBLIC_PATH = "webpack:///mini-css-extract-plugin/";
100const BASE_URI = "webpack://";
101const SINGLE_DOT_PATH_SEGMENT = "__mini_css_extract_plugin_single_dot_path_segment__";
102/**
103 * @param {string} str
104 * @returns {boolean}
105 */
106
107function isAbsolutePath(str) {
108 return path.posix.isAbsolute(str) || path.win32.isAbsolute(str);
109}
110
111const RELATIVE_PATH_REGEXP = /^\.\.?[/\\]/;
112/**
113 * @param {string} str
114 * @returns {boolean}
115 */
116
117function isRelativePath(str) {
118 return RELATIVE_PATH_REGEXP.test(str);
119} // TODO simplify for the next major release
120
121/**
122 * @param {LoaderContext} loaderContext
123 * @param {string} request
124 * @returns {string}
125 */
126
127
128function stringifyRequest(loaderContext, request) {
129 if (typeof loaderContext.utils !== "undefined" && typeof loaderContext.utils.contextify === "function") {
130 return JSON.stringify(loaderContext.utils.contextify(loaderContext.context || loaderContext.rootContext, request));
131 }
132
133 const splitted = request.split("!");
134 const {
135 context
136 } = loaderContext;
137 return JSON.stringify(splitted.map(part => {
138 // First, separate singlePath from query, because the query might contain paths again
139 const splittedPart = part.match(/^(.*?)(\?.*)/);
140 const query = splittedPart ? splittedPart[2] : "";
141 let singlePath = splittedPart ? splittedPart[1] : part;
142
143 if (isAbsolutePath(singlePath) && context) {
144 singlePath = path.relative(context, singlePath);
145
146 if (isAbsolutePath(singlePath)) {
147 // If singlePath still matches an absolute path, singlePath was on a different drive than context.
148 // In this case, we leave the path platform-specific without replacing any separators.
149 // @see https://github.com/webpack/loader-utils/pull/14
150 return singlePath + query;
151 }
152
153 if (isRelativePath(singlePath) === false) {
154 // Ensure that the relative path starts at least with ./ otherwise it would be a request into the modules directory (like node_modules).
155 singlePath = `./${singlePath}`;
156 }
157 }
158
159 return singlePath.replace(/\\/g, "/") + query;
160 }).join("!"));
161}
162/**
163 * @param {string} filename
164 * @param {string} outputPath
165 * @param {boolean} enforceRelative
166 * @returns {string}
167 */
168
169
170function getUndoPath(filename, outputPath, enforceRelative) {
171 let depth = -1;
172 let append = ""; // eslint-disable-next-line no-param-reassign
173
174 outputPath = outputPath.replace(/[\\/]$/, "");
175
176 for (const part of filename.split(/[/\\]+/)) {
177 if (part === "..") {
178 if (depth > -1) {
179 // eslint-disable-next-line no-plusplus
180 depth--;
181 } else {
182 const i = outputPath.lastIndexOf("/");
183 const j = outputPath.lastIndexOf("\\");
184 const pos = i < 0 ? j : j < 0 ? i : Math.max(i, j);
185
186 if (pos < 0) {
187 return `${outputPath}/`;
188 }
189
190 append = `${outputPath.slice(pos + 1)}/${append}`; // eslint-disable-next-line no-param-reassign
191
192 outputPath = outputPath.slice(0, pos);
193 }
194 } else if (part !== ".") {
195 // eslint-disable-next-line no-plusplus
196 depth++;
197 }
198 }
199
200 return depth > 0 ? `${"../".repeat(depth)}${append}` : enforceRelative ? `./${append}` : append;
201}
202
203module.exports = {
204 trueFn,
205 findModuleById,
206 evalModuleCode,
207 compareModulesByIdentifier,
208 MODULE_TYPE,
209 AUTO_PUBLIC_PATH,
210 ABSOLUTE_PUBLIC_PATH,
211 BASE_URI,
212 SINGLE_DOT_PATH_SEGMENT,
213 stringifyRequest,
214 getUndoPath
215};
\No newline at end of file