Skip to content

Commit

Permalink
feat: support absolute paths
Browse files Browse the repository at this point in the history
  • Loading branch information
evilebottnawi authored Jul 29, 2020
1 parent 91bc64b commit f9ba0ce
Show file tree
Hide file tree
Showing 11 changed files with 206 additions and 6 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ npm-debug.log*
/local
/reports
/node_modules
/test/fixtures/import/import-absolute.css
/test/fixtures/url/url-absolute.css
/test/fixtures/modules/composes/composes-absolute.css

.DS_Store
Thumbs.db
Expand Down
11 changes: 5 additions & 6 deletions src/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,10 @@ function defaultGetLocalIdent(
}

function normalizeUrl(url, isStringValue) {
if (matchNativeWin32Path.test(url)) {
return url;
}

let normalizedUrl = url;

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

function isUrlRequestable(url) {
// Windows absolute paths
if (matchNativeWin32Path.test(url)) {
return false;
}

// Protocol-relative URLs
if (/^\/\//.test(url)) {
return false;
Expand All @@ -525,7 +524,7 @@ function isUrlRequestable(url) {
}

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

Expand Down
35 changes: 35 additions & 0 deletions test/__snapshots__/import-option.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,41 @@ Array [

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

exports[`"import" option should resolve absolute path: errors 1`] = `Array []`;

exports[`"import" option should resolve absolute path: module 1`] = `
"// Imports
import ___CSS_LOADER_API_IMPORT___ from \\"../../../src/runtime/api.js\\";
import ___CSS_LOADER_AT_RULE_IMPORT_0___ from \\"-!../../../src/index.js??[ident]!./test.css\\";
var ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(false);
___CSS_LOADER_EXPORT___.i(___CSS_LOADER_AT_RULE_IMPORT_0___);
// Module
___CSS_LOADER_EXPORT___.push([module.id, \\"\\", \\"\\"]);
// Exports
export default ___CSS_LOADER_EXPORT___;
"
`;

exports[`"import" option should resolve absolute path: result 1`] = `
Array [
Array [
"../../src/index.js?[ident]!./import/test.css",
".test {
a: a;
}
",
"",
],
Array [
"./import/import-absolute.css",
"",
"",
],
]
`;

exports[`"import" option should resolve absolute path: warnings 1`] = `Array []`;

exports[`"import" option should resolve server-relative url relative rootContext: errors 1`] = `Array []`;

exports[`"import" option should resolve server-relative url relative rootContext: module 1`] = `
Expand Down
38 changes: 38 additions & 0 deletions test/__snapshots__/modules-option.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -668,6 +668,44 @@ Array [
exports[`"modules" option should keep order: warnings 1`] = `Array []`;
exports[`"modules" option should resolve absolute path in composes: errors 1`] = `Array []`;
exports[`"modules" option should resolve absolute path in composes: module 1`] = `
"// Imports
import ___CSS_LOADER_API_IMPORT___ from \\"../../../../src/runtime/api.js\\";
import ___CSS_LOADER_ICSS_IMPORT_0___ from \\"-!../../../../src/index.js??[ident]!./imported-simple.css\\";
var ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(false);
___CSS_LOADER_EXPORT___.i(___CSS_LOADER_ICSS_IMPORT_0___, \\"\\", true);
// Module
___CSS_LOADER_EXPORT___.push([module.id, \\"._2Qa8f_r4FS0cuNEBSCJGHl { color: red; }\\", \\"\\"]);
// Exports
___CSS_LOADER_EXPORT___.locals = {
\\"simple\\": \\"_2Qa8f_r4FS0cuNEBSCJGHl \\" + ___CSS_LOADER_ICSS_IMPORT_0___.locals[\\"imported-simple\\"] + \\"\\"
};
export default ___CSS_LOADER_EXPORT___;
"
`;
exports[`"modules" option should resolve absolute path in composes: result 1`] = `
Array [
Array [
"../../src/index.js?[ident]!./modules/composes/imported-simple.css",
"._1LcKtmpK51ikm2OTXu6tSg {
display: block;
}
",
"",
],
Array [
"./modules/composes/composes-absolute.css",
"._2Qa8f_r4FS0cuNEBSCJGHl { color: red; }",
"",
],
]
`;
exports[`"modules" option should resolve absolute path in composes: warnings 1`] = `Array []`;
exports[`"modules" option should resolve package from node_modules with and without tilde: errors 1`] = `Array []`;
exports[`"modules" option should resolve package from node_modules with and without tilde: module 1`] = `
Expand Down
29 changes: 29 additions & 0 deletions test/__snapshots__/url-option.test.js.snap
Original file line number Diff line number Diff line change
@@ -1,5 +1,34 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`"url" option should resolve absolute path: errors 1`] = `Array []`;

exports[`"url" option should resolve absolute path: module 1`] = `
"// Imports
import ___CSS_LOADER_API_IMPORT___ from \\"../../../src/runtime/api.js\\";
import ___CSS_LOADER_GET_URL_IMPORT___ from \\"../../../src/runtime/getUrl.js\\";
import ___CSS_LOADER_URL_IMPORT_0___ from \\"./img.png\\";
var ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(false);
var ___CSS_LOADER_URL_REPLACEMENT_0___ = ___CSS_LOADER_GET_URL_IMPORT___(___CSS_LOADER_URL_IMPORT_0___);
// Module
___CSS_LOADER_EXPORT___.push([module.id, \\"\\\\n.background {background: url(\\" + ___CSS_LOADER_URL_REPLACEMENT_0___ + \\"); }\\", \\"\\"]);
// Exports
export default ___CSS_LOADER_EXPORT___;
"
`;

exports[`"url" option should resolve absolute path: result 1`] = `
Array [
Array [
"./url/url-absolute.css",
"
.background {background: url(/webpack/public/path/img.png); }",
"",
],
]
`;

exports[`"url" option should resolve absolute path: warnings 1`] = `Array []`;

exports[`"url" option should throw an error on unresolved import: errors 1`] = `
Array [
"ModuleBuildError: Module build failed (from \`replaced original path\`):
Expand Down
5 changes: 5 additions & 0 deletions test/fixtures/import/import-absolute.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import css from './import-absolute.css';

__export__ = css;

export default css;
5 changes: 5 additions & 0 deletions test/fixtures/modules/composes/composes-absolute.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import css from './composes-absolute.css';

__export__ = css;

export default css;
5 changes: 5 additions & 0 deletions test/fixtures/url/url-absolute.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import css from './url-absolute.css';

__export__ = css;

export default css;
24 changes: 24 additions & 0 deletions test/import-option.test.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import fs from 'fs';
import path from 'path';

import {
compile,
getCompiler,
Expand Down Expand Up @@ -149,6 +152,27 @@ describe('"import" option', () => {
expect(getErrors(stats)).toMatchSnapshot('errors');
});

it('should resolve absolute path', async () => {
// Create the file with absolute path
const fileDirectory = path.resolve(__dirname, 'fixtures', 'import');
const file = path.resolve(fileDirectory, 'import-absolute.css');
const absolutePath = path.resolve(fileDirectory, 'test.css');

fs.writeFileSync(file, `@import "${absolutePath}";`);

const compiler = getCompiler('./import/import-absolute.js');
const stats = await compile(compiler);

expect(
getModuleSource('./import/import-absolute.css', stats)
).toMatchSnapshot('module');
expect(getExecutedCode('main.bundle.js', compiler, stats)).toMatchSnapshot(
'result'
);
expect(getWarnings(stats)).toMatchSnapshot('warnings');
expect(getErrors(stats)).toMatchSnapshot('errors');
});

it('should throw an error on unresolved import', async () => {
const compiler = getCompiler('./import/unresolved.js');
const stats = await compile(compiler);
Expand Down
31 changes: 31 additions & 0 deletions test/modules-option.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,37 @@ describe('"modules" option', () => {
expect(getErrors(stats)).toMatchSnapshot('errors');
});

it('should resolve absolute path in composes', async () => {
// Create the file with absolute path
const fileDirectory = path.resolve(
__dirname,
'fixtures',
'modules',
'composes'
);
const file = path.resolve(fileDirectory, 'composes-absolute.css');
const absolutePath = path.resolve(fileDirectory, 'imported-simple.css');

fs.writeFileSync(
file,
`.simple { color: red; composes: imported-simple from '${absolutePath}'; }`
);

const compiler = getCompiler('./modules/composes/composes-absolute.js', {
modules: true,
});
const stats = await compile(compiler);

expect(
getModuleSource('./modules/composes/composes-absolute.css', stats)
).toMatchSnapshot('module');
expect(getExecutedCode('main.bundle.js', compiler, stats)).toMatchSnapshot(
'result'
);
expect(getWarnings(stats)).toMatchSnapshot('warnings');
expect(getErrors(stats)).toMatchSnapshot('errors');
});

it('should support resolving in composes preprocessor files with extensions', async () => {
const compiler = getCompiler(
'./modules/composes/composes-preprocessors.js',
Expand Down
26 changes: 26 additions & 0 deletions test/url-option.test.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import fs from 'fs';
import path from 'path';

import {
compile,
getCompiler,
Expand Down Expand Up @@ -67,6 +70,29 @@ describe('"url" option', () => {
expect(getErrors(stats)).toMatchSnapshot('errors');
});

it('should resolve absolute path', async () => {
// Create the file with absolute path
const fileDirectory = path.resolve(__dirname, 'fixtures', 'url');
const file = path.resolve(fileDirectory, 'url-absolute.css');
const absolutePath = path.resolve(fileDirectory, 'img.png');

const code = `\n.background {background: url(${absolutePath}); }`;

fs.writeFileSync(file, code);

const compiler = getCompiler('./url/url-absolute.js');
const stats = await compile(compiler);

expect(getModuleSource('./url/url-absolute.css', stats)).toMatchSnapshot(
'module'
);
expect(getExecutedCode('main.bundle.js', compiler, stats)).toMatchSnapshot(
'result'
);
expect(getWarnings(stats)).toMatchSnapshot('warnings');
expect(getErrors(stats)).toMatchSnapshot('errors');
});

it('should throw an error on unresolved import', async () => {
const compiler = getCompiler('./url/url-unresolved.js');
const stats = await compile(compiler);
Expand Down

0 comments on commit f9ba0ce

Please sign in to comment.