Skip to content

Commit 4ae4e5c

Browse files
fix: respected style field from package.json
1 parent e2205af commit 4ae4e5c

9 files changed

+164
-9
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,4 @@ Thumbs.db
1616
.vscode
1717
*.sublime-project
1818
*.sublime-workspace
19+
/test/fixtures/import/import-absolute.css

src/index.js

+1
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ export default function loader(content, map, meta) {
5858
plugins.push(
5959
importParser({
6060
context: this.context,
61+
rootContext: this.rootContext,
6162
filter: getFilter(options.import, this.resourcePath),
6263
resolver,
6364
urlHandler,

src/plugins/postcss-import-parser.js

+20-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import postcss from 'postcss';
22
import valueParser from 'postcss-value-parser';
3-
import { isUrlRequest } from 'loader-utils';
3+
import { isUrlRequest, urlToRequest } from 'loader-utils';
44

55
import { normalizeUrl, resolveRequests } from '../utils';
66

@@ -77,6 +77,13 @@ export default postcss.plugin(pluginName, (options) => (css, result) => {
7777
return;
7878
}
7979

80+
let request;
81+
82+
// May be url is server-relative url, but not //example.com
83+
if (url.charAt(0) === '/' && url.charAt(1) !== '/') {
84+
request = urlToRequest(url, options.rootContext);
85+
}
86+
8087
const isRequestable = isUrlRequest(url);
8188

8289
if (isRequestable) {
@@ -107,7 +114,7 @@ export default postcss.plugin(pluginName, (options) => (css, result) => {
107114

108115
tasks.push(
109116
Promise.resolve(index).then(async (currentIndex) => {
110-
if (isRequestable) {
117+
if (isRequestable || request) {
111118
const importKey = url;
112119
let importName = importsMap.get(importKey);
113120

@@ -117,10 +124,20 @@ export default postcss.plugin(pluginName, (options) => (css, result) => {
117124

118125
const { resolver, context } = options;
119126

127+
const possibleRequest = [url];
128+
129+
if (request) {
130+
possibleRequest.push(request);
131+
}
132+
120133
let resolvedUrl;
121134

122135
try {
123-
resolvedUrl = await resolveRequests(resolver, context, [url]);
136+
resolvedUrl = await resolveRequests(
137+
resolver,
138+
context,
139+
possibleRequest
140+
);
124141
} catch (error) {
125142
throw error;
126143
}

src/utils.js

+6-6
Original file line numberDiff line numberDiff line change
@@ -73,13 +73,17 @@ function getLocalIdent(loaderContext, localIdentName, localName, options) {
7373
}
7474

7575
function normalizeUrl(url, isStringValue) {
76+
const matchNativeWin32Path = /^[A-Z]:[/\\]|^\\\\/i;
77+
7678
let normalizedUrl = url;
7779

7880
if (isStringValue && /\\[\n]/.test(normalizedUrl)) {
7981
normalizedUrl = normalizedUrl.replace(/\\[\n]/g, '');
8082
}
8183

82-
return urlToRequest(decodeURIComponent(unescape(normalizedUrl)));
84+
return matchNativeWin32Path.test(url)
85+
? urlToRequest(url, true)
86+
: urlToRequest(decodeURIComponent(unescape(normalizedUrl)));
8387
}
8488

8589
function getFilter(filter, resourcePath, defaultFilter = null) {
@@ -423,10 +427,6 @@ function getExportCode(
423427
}
424428

425429
async function resolveRequests(resolve, context, possibleRequests) {
426-
if (possibleRequests.length === 0) {
427-
return Promise.reject();
428-
}
429-
430430
return resolve(context, possibleRequests[0])
431431
.then((result) => {
432432
return result;
@@ -438,7 +438,7 @@ async function resolveRequests(resolve, context, possibleRequests) {
438438
throw error;
439439
}
440440

441-
return this.resolveRequests(context, tailPossibleRequests);
441+
return resolveRequests(resolve, context, tailPossibleRequests);
442442
});
443443
}
444444

test/__snapshots__/import-option.test.js.snap

+82
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,88 @@ Array [
152152

153153
exports[`"import" option should keep original order: warnings 1`] = `Array []`;
154154

155+
exports[`"import" option should resolve absolute path: errors 1`] = `Array []`;
156+
157+
exports[`"import" option should resolve absolute path: module 1`] = `
158+
"// Imports
159+
var ___CSS_LOADER_API_IMPORT___ = require(\\"../../../src/runtime/api.js\\");
160+
var ___CSS_LOADER_AT_RULE_IMPORT_0___ = require(\\"-!../../../src/index.js??[ident]!./test.css\\");
161+
exports = ___CSS_LOADER_API_IMPORT___(false);
162+
exports.i(___CSS_LOADER_AT_RULE_IMPORT_0___);
163+
// Module
164+
exports.push([module.id, \\"\\", \\"\\"]);
165+
// Exports
166+
module.exports = exports;
167+
"
168+
`;
169+
170+
exports[`"import" option should resolve absolute path: result 1`] = `
171+
Array [
172+
Array [
173+
"../../src/index.js?[ident]!./import/test.css",
174+
".test {
175+
a: a;
176+
}
177+
",
178+
"",
179+
],
180+
Array [
181+
"./import/import-absolute.css",
182+
"",
183+
"",
184+
],
185+
]
186+
`;
187+
188+
exports[`"import" option should resolve absolute path: warnings 1`] = `Array []`;
189+
190+
exports[`"import" option should resolve server-relative url relative rootContext: errors 1`] = `Array []`;
191+
192+
exports[`"import" option should resolve server-relative url relative rootContext: module 1`] = `
193+
"// Imports
194+
var ___CSS_LOADER_API_IMPORT___ = require(\\"../../../src/runtime/api.js\\");
195+
var ___CSS_LOADER_AT_RULE_IMPORT_0___ = require(\\"-!../../../src/index.js??[ident]!./test.css\\");
196+
exports = ___CSS_LOADER_API_IMPORT___(false);
197+
exports.i(___CSS_LOADER_AT_RULE_IMPORT_0___);
198+
exports.i(___CSS_LOADER_AT_RULE_IMPORT_0___);
199+
// Module
200+
exports.push([module.id, \\".class {\\\\n a: b c d;\\\\n}\\\\n\\", \\"\\"]);
201+
// Exports
202+
module.exports = exports;
203+
"
204+
`;
205+
206+
exports[`"import" option should resolve server-relative url relative rootContext: result 1`] = `
207+
Array [
208+
Array [
209+
"../../src/index.js?[ident]!./import/test.css",
210+
".test {
211+
a: a;
212+
}
213+
",
214+
"",
215+
],
216+
Array [
217+
"../../src/index.js?[ident]!./import/test.css",
218+
".test {
219+
a: a;
220+
}
221+
",
222+
"",
223+
],
224+
Array [
225+
"./import/import-server-relative-url.css",
226+
".class {
227+
a: b c d;
228+
}
229+
",
230+
"",
231+
],
232+
]
233+
`;
234+
235+
exports[`"import" option should resolve server-relative url relative rootContext: warnings 1`] = `Array []`;
236+
155237
exports[`"import" option should respect stype field in package.json: errors 1`] = `Array []`;
156238

157239
exports[`"import" option should respect stype field in package.json: module 1`] = `
+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import css from './import-absolute.css';
2+
3+
__export__ = css;
4+
5+
export default css;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
@import url(/import/test.css);
2+
@import "/import/test.css";
3+
4+
.class {
5+
a: b c d;
6+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import css from './import-server-relative-url.css';
2+
3+
__export__ = css;
4+
5+
export default css;

test/import-option.test.js

+38
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
import path from 'path';
2+
import fs from 'fs';
3+
14
import {
25
compile,
36
getCompiler,
@@ -100,4 +103,39 @@ describe('"import" option', () => {
100103
expect(getWarnings(stats)).toMatchSnapshot('warnings');
101104
expect(getErrors(stats)).toMatchSnapshot('errors');
102105
});
106+
107+
it('should resolve server-relative url relative rootContext', async () => {
108+
const compiler = getCompiler('./import/import-server-relative-url.js');
109+
const stats = await compile(compiler);
110+
111+
expect(
112+
getModuleSource('./import/import-server-relative-url.css', stats)
113+
).toMatchSnapshot('module');
114+
expect(getExecutedCode('main.bundle.js', compiler, stats)).toMatchSnapshot(
115+
'result'
116+
);
117+
expect(getWarnings(stats)).toMatchSnapshot('warnings');
118+
expect(getErrors(stats)).toMatchSnapshot('errors');
119+
});
120+
121+
it('should resolve absolute path', async () => {
122+
// Create the file with absolute path
123+
const fileDirectory = path.resolve(__dirname, 'fixtures', 'import');
124+
const file = path.resolve(fileDirectory, 'import-absolute.css');
125+
const absolutePath = path.resolve(fileDirectory, 'test.css');
126+
127+
fs.writeFileSync(file, `@import "${absolutePath}";`);
128+
129+
const compiler = getCompiler('./import/import-absolute.js');
130+
const stats = await compile(compiler);
131+
132+
expect(
133+
getModuleSource('./import/import-absolute.css', stats)
134+
).toMatchSnapshot('module');
135+
expect(getExecutedCode('main.bundle.js', compiler, stats)).toMatchSnapshot(
136+
'result'
137+
);
138+
expect(getWarnings(stats)).toMatchSnapshot('warnings');
139+
expect(getErrors(stats)).toMatchSnapshot('errors');
140+
});
103141
});

0 commit comments

Comments
 (0)