UNPKG

5.24 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 SINGLE_DOT_PATH_SEGMENT = "__mini_css_extract_plugin_single_dot_path_segment__";
101/**
102 * @param {string} str
103 * @returns {boolean}
104 */
105
106function isAbsolutePath(str) {
107 return path.posix.isAbsolute(str) || path.win32.isAbsolute(str);
108}
109
110const RELATIVE_PATH_REGEXP = /^\.\.?[/\\]/;
111/**
112 * @param {string} str
113 * @returns {boolean}
114 */
115
116function isRelativePath(str) {
117 return RELATIVE_PATH_REGEXP.test(str);
118} // TODO simplify for the next major release
119
120/**
121 * @param {LoaderContext} loaderContext
122 * @param {string} request
123 * @returns {string}
124 */
125
126
127function stringifyRequest(loaderContext, request) {
128 if (typeof loaderContext.utils !== "undefined" && typeof loaderContext.utils.contextify === "function") {
129 return JSON.stringify(loaderContext.utils.contextify(loaderContext.context || loaderContext.rootContext, request));
130 }
131
132 const splitted = request.split("!");
133 const {
134 context
135 } = loaderContext;
136 return JSON.stringify(splitted.map(part => {
137 // First, separate singlePath from query, because the query might contain paths again
138 const splittedPart = part.match(/^(.*?)(\?.*)/);
139 const query = splittedPart ? splittedPart[2] : "";
140 let singlePath = splittedPart ? splittedPart[1] : part;
141
142 if (isAbsolutePath(singlePath) && context) {
143 singlePath = path.relative(context, singlePath);
144
145 if (isAbsolutePath(singlePath)) {
146 // If singlePath still matches an absolute path, singlePath was on a different drive than context.
147 // In this case, we leave the path platform-specific without replacing any separators.
148 // @see https://github.com/webpack/loader-utils/pull/14
149 return singlePath + query;
150 }
151
152 if (isRelativePath(singlePath) === false) {
153 // Ensure that the relative path starts at least with ./ otherwise it would be a request into the modules directory (like node_modules).
154 singlePath = `./${singlePath}`;
155 }
156 }
157
158 return singlePath.replace(/\\/g, "/") + query;
159 }).join("!"));
160}
161/**
162 * @param {string} filename
163 * @param {string} outputPath
164 * @param {boolean} enforceRelative
165 * @returns {string}
166 */
167
168
169function getUndoPath(filename, outputPath, enforceRelative) {
170 let depth = -1;
171 let append = ""; // eslint-disable-next-line no-param-reassign
172
173 outputPath = outputPath.replace(/[\\/]$/, "");
174
175 for (const part of filename.split(/[/\\]+/)) {
176 if (part === "..") {
177 if (depth > -1) {
178 // eslint-disable-next-line no-plusplus
179 depth--;
180 } else {
181 const i = outputPath.lastIndexOf("/");
182 const j = outputPath.lastIndexOf("\\");
183 const pos = i < 0 ? j : j < 0 ? i : Math.max(i, j);
184
185 if (pos < 0) {
186 return `${outputPath}/`;
187 }
188
189 append = `${outputPath.slice(pos + 1)}/${append}`; // eslint-disable-next-line no-param-reassign
190
191 outputPath = outputPath.slice(0, pos);
192 }
193 } else if (part !== ".") {
194 // eslint-disable-next-line no-plusplus
195 depth++;
196 }
197 }
198
199 return depth > 0 ? `${"../".repeat(depth)}${append}` : enforceRelative ? `./${append}` : append;
200}
201
202module.exports = {
203 trueFn,
204 findModuleById,
205 evalModuleCode,
206 compareModulesByIdentifier,
207 MODULE_TYPE,
208 AUTO_PUBLIC_PATH,
209 ABSOLUTE_PUBLIC_PATH,
210 SINGLE_DOT_PATH_SEGMENT,
211 stringifyRequest,
212 getUndoPath
213};
\No newline at end of file