Skip to content

Commit f9ba0ce

Browse files
feat: support absolute paths
1 parent 91bc64b commit f9ba0ce

11 files changed

+206
-6
lines changed

.gitignore

+3
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ npm-debug.log*
88
/local
99
/reports
1010
/node_modules
11+
/test/fixtures/import/import-absolute.css
12+
/test/fixtures/url/url-absolute.css
13+
/test/fixtures/modules/composes/composes-absolute.css
1114

1215
.DS_Store
1316
Thumbs.db

src/utils.js

+5-6
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,10 @@ function defaultGetLocalIdent(
7373
}
7474

7575
function normalizeUrl(url, isStringValue) {
76+
if (matchNativeWin32Path.test(url)) {
77+
return url;
78+
}
79+
7680
let normalizedUrl = url;
7781

7882
if (isStringValue && /\\[\n]/.test(normalizedUrl)) {
@@ -509,11 +513,6 @@ async function resolveRequests(resolve, context, possibleRequests) {
509513
}
510514

511515
function isUrlRequestable(url) {
512-
// Windows absolute paths
513-
if (matchNativeWin32Path.test(url)) {
514-
return false;
515-
}
516-
517516
// Protocol-relative URLs
518517
if (/^\/\//.test(url)) {
519518
return false;
@@ -525,7 +524,7 @@ function isUrlRequestable(url) {
525524
}
526525

527526
// Absolute URLs
528-
if (/^[a-z][a-z0-9+.-]*:/i.test(url)) {
527+
if (/^[a-z][a-z0-9+.-]*:/i.test(url) && !matchNativeWin32Path.test(url)) {
529528
return false;
530529
}
531530

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

+35
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,41 @@ 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+
import ___CSS_LOADER_API_IMPORT___ from \\"../../../src/runtime/api.js\\";
160+
import ___CSS_LOADER_AT_RULE_IMPORT_0___ from \\"-!../../../src/index.js??[ident]!./test.css\\";
161+
var ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(false);
162+
___CSS_LOADER_EXPORT___.i(___CSS_LOADER_AT_RULE_IMPORT_0___);
163+
// Module
164+
___CSS_LOADER_EXPORT___.push([module.id, \\"\\", \\"\\"]);
165+
// Exports
166+
export default ___CSS_LOADER_EXPORT___;
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+
155190
exports[`"import" option should resolve server-relative url relative rootContext: errors 1`] = `Array []`;
156191

157192
exports[`"import" option should resolve server-relative url relative rootContext: module 1`] = `

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

+38
Original file line numberDiff line numberDiff line change
@@ -668,6 +668,44 @@ Array [
668668
669669
exports[`"modules" option should keep order: warnings 1`] = `Array []`;
670670
671+
exports[`"modules" option should resolve absolute path in composes: errors 1`] = `Array []`;
672+
673+
exports[`"modules" option should resolve absolute path in composes: module 1`] = `
674+
"// Imports
675+
import ___CSS_LOADER_API_IMPORT___ from \\"../../../../src/runtime/api.js\\";
676+
import ___CSS_LOADER_ICSS_IMPORT_0___ from \\"-!../../../../src/index.js??[ident]!./imported-simple.css\\";
677+
var ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(false);
678+
___CSS_LOADER_EXPORT___.i(___CSS_LOADER_ICSS_IMPORT_0___, \\"\\", true);
679+
// Module
680+
___CSS_LOADER_EXPORT___.push([module.id, \\"._2Qa8f_r4FS0cuNEBSCJGHl { color: red; }\\", \\"\\"]);
681+
// Exports
682+
___CSS_LOADER_EXPORT___.locals = {
683+
\\"simple\\": \\"_2Qa8f_r4FS0cuNEBSCJGHl \\" + ___CSS_LOADER_ICSS_IMPORT_0___.locals[\\"imported-simple\\"] + \\"\\"
684+
};
685+
export default ___CSS_LOADER_EXPORT___;
686+
"
687+
`;
688+
689+
exports[`"modules" option should resolve absolute path in composes: result 1`] = `
690+
Array [
691+
Array [
692+
"../../src/index.js?[ident]!./modules/composes/imported-simple.css",
693+
"._1LcKtmpK51ikm2OTXu6tSg {
694+
display: block;
695+
}
696+
",
697+
"",
698+
],
699+
Array [
700+
"./modules/composes/composes-absolute.css",
701+
"._2Qa8f_r4FS0cuNEBSCJGHl { color: red; }",
702+
"",
703+
],
704+
]
705+
`;
706+
707+
exports[`"modules" option should resolve absolute path in composes: warnings 1`] = `Array []`;
708+
671709
exports[`"modules" option should resolve package from node_modules with and without tilde: errors 1`] = `Array []`;
672710
673711
exports[`"modules" option should resolve package from node_modules with and without tilde: module 1`] = `

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

+29
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,34 @@
11
// Jest Snapshot v1, https://goo.gl/fbAQLP
22

3+
exports[`"url" option should resolve absolute path: errors 1`] = `Array []`;
4+
5+
exports[`"url" option should resolve absolute path: module 1`] = `
6+
"// Imports
7+
import ___CSS_LOADER_API_IMPORT___ from \\"../../../src/runtime/api.js\\";
8+
import ___CSS_LOADER_GET_URL_IMPORT___ from \\"../../../src/runtime/getUrl.js\\";
9+
import ___CSS_LOADER_URL_IMPORT_0___ from \\"./img.png\\";
10+
var ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(false);
11+
var ___CSS_LOADER_URL_REPLACEMENT_0___ = ___CSS_LOADER_GET_URL_IMPORT___(___CSS_LOADER_URL_IMPORT_0___);
12+
// Module
13+
___CSS_LOADER_EXPORT___.push([module.id, \\"\\\\n.background {background: url(\\" + ___CSS_LOADER_URL_REPLACEMENT_0___ + \\"); }\\", \\"\\"]);
14+
// Exports
15+
export default ___CSS_LOADER_EXPORT___;
16+
"
17+
`;
18+
19+
exports[`"url" option should resolve absolute path: result 1`] = `
20+
Array [
21+
Array [
22+
"./url/url-absolute.css",
23+
"
24+
.background {background: url(/webpack/public/path/img.png); }",
25+
"",
26+
],
27+
]
28+
`;
29+
30+
exports[`"url" option should resolve absolute path: warnings 1`] = `Array []`;
31+
332
exports[`"url" option should throw an error on unresolved import: errors 1`] = `
433
Array [
534
"ModuleBuildError: Module build failed (from \`replaced original path\`):
+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,5 @@
1+
import css from './composes-absolute.css';
2+
3+
__export__ = css;
4+
5+
export default css;

test/fixtures/url/url-absolute.js

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import css from './url-absolute.css';
2+
3+
__export__ = css;
4+
5+
export default css;

test/import-option.test.js

+24
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
import fs from 'fs';
2+
import path from 'path';
3+
14
import {
25
compile,
36
getCompiler,
@@ -149,6 +152,27 @@ describe('"import" option', () => {
149152
expect(getErrors(stats)).toMatchSnapshot('errors');
150153
});
151154

155+
it('should resolve absolute path', async () => {
156+
// Create the file with absolute path
157+
const fileDirectory = path.resolve(__dirname, 'fixtures', 'import');
158+
const file = path.resolve(fileDirectory, 'import-absolute.css');
159+
const absolutePath = path.resolve(fileDirectory, 'test.css');
160+
161+
fs.writeFileSync(file, `@import "${absolutePath}";`);
162+
163+
const compiler = getCompiler('./import/import-absolute.js');
164+
const stats = await compile(compiler);
165+
166+
expect(
167+
getModuleSource('./import/import-absolute.css', stats)
168+
).toMatchSnapshot('module');
169+
expect(getExecutedCode('main.bundle.js', compiler, stats)).toMatchSnapshot(
170+
'result'
171+
);
172+
expect(getWarnings(stats)).toMatchSnapshot('warnings');
173+
expect(getErrors(stats)).toMatchSnapshot('errors');
174+
});
175+
152176
it('should throw an error on unresolved import', async () => {
153177
const compiler = getCompiler('./import/unresolved.js');
154178
const stats = await compile(compiler);

test/modules-option.test.js

+31
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,37 @@ describe('"modules" option', () => {
309309
expect(getErrors(stats)).toMatchSnapshot('errors');
310310
});
311311

312+
it('should resolve absolute path in composes', async () => {
313+
// Create the file with absolute path
314+
const fileDirectory = path.resolve(
315+
__dirname,
316+
'fixtures',
317+
'modules',
318+
'composes'
319+
);
320+
const file = path.resolve(fileDirectory, 'composes-absolute.css');
321+
const absolutePath = path.resolve(fileDirectory, 'imported-simple.css');
322+
323+
fs.writeFileSync(
324+
file,
325+
`.simple { color: red; composes: imported-simple from '${absolutePath}'; }`
326+
);
327+
328+
const compiler = getCompiler('./modules/composes/composes-absolute.js', {
329+
modules: true,
330+
});
331+
const stats = await compile(compiler);
332+
333+
expect(
334+
getModuleSource('./modules/composes/composes-absolute.css', stats)
335+
).toMatchSnapshot('module');
336+
expect(getExecutedCode('main.bundle.js', compiler, stats)).toMatchSnapshot(
337+
'result'
338+
);
339+
expect(getWarnings(stats)).toMatchSnapshot('warnings');
340+
expect(getErrors(stats)).toMatchSnapshot('errors');
341+
});
342+
312343
it('should support resolving in composes preprocessor files with extensions', async () => {
313344
const compiler = getCompiler(
314345
'./modules/composes/composes-preprocessors.js',

test/url-option.test.js

+26
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
import fs from 'fs';
2+
import path from 'path';
3+
14
import {
25
compile,
36
getCompiler,
@@ -67,6 +70,29 @@ describe('"url" option', () => {
6770
expect(getErrors(stats)).toMatchSnapshot('errors');
6871
});
6972

73+
it('should resolve absolute path', async () => {
74+
// Create the file with absolute path
75+
const fileDirectory = path.resolve(__dirname, 'fixtures', 'url');
76+
const file = path.resolve(fileDirectory, 'url-absolute.css');
77+
const absolutePath = path.resolve(fileDirectory, 'img.png');
78+
79+
const code = `\n.background {background: url(${absolutePath}); }`;
80+
81+
fs.writeFileSync(file, code);
82+
83+
const compiler = getCompiler('./url/url-absolute.js');
84+
const stats = await compile(compiler);
85+
86+
expect(getModuleSource('./url/url-absolute.css', stats)).toMatchSnapshot(
87+
'module'
88+
);
89+
expect(getExecutedCode('main.bundle.js', compiler, stats)).toMatchSnapshot(
90+
'result'
91+
);
92+
expect(getWarnings(stats)).toMatchSnapshot('warnings');
93+
expect(getErrors(stats)).toMatchSnapshot('errors');
94+
});
95+
7096
it('should throw an error on unresolved import', async () => {
7197
const compiler = getCompiler('./url/url-unresolved.js');
7298
const stats = await compile(compiler);

0 commit comments

Comments
 (0)