Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: resolve from and to from config and options #467

Merged
merged 2 commits into from Sep 7, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
7 changes: 2 additions & 5 deletions src/index.js
Expand Up @@ -74,10 +74,7 @@ export default async function loader(content, sourceMap) {
processOptions.map = { inline: false, annotation: false };

if (sourceMap) {
processOptions.map.prev = normalizeSourceMap(
sourceMap,
this.resourcePath
);
processOptions.map.prev = normalizeSourceMap(sourceMap, this.context);
}
} else if (sourceMap && typeof processOptions.map !== 'undefined') {
if (typeof processOptions.map === 'boolean') {
Expand Down Expand Up @@ -128,7 +125,7 @@ export default async function loader(content, sourceMap) {
let map = result.map ? result.map.toJSON() : undefined;

if (map && useSourceMap) {
map = normalizeSourceMapAfterPostcss(map, this.resourcePath);
map = normalizeSourceMapAfterPostcss(map, this.context);
}

const ast = {
Expand Down
39 changes: 32 additions & 7 deletions src/utils.js
Expand Up @@ -192,18 +192,45 @@ function getPostcssOptions(loaderContext, config, postcssOptions = {}) {

const processOptionsFromConfig = { ...config };

if (processOptionsFromConfig.from) {
processOptionsFromConfig.from = path.resolve(
path.dirname(config.file),
processOptionsFromConfig.from
);
}

if (processOptionsFromConfig.to) {
processOptionsFromConfig.to = path.resolve(
path.dirname(config.file),
processOptionsFromConfig.to
);
}

// No need them for processOptions
delete processOptionsFromConfig.plugins;
delete processOptionsFromConfig.file;

const processOptionsFromOptions = { ...normalizedPostcssOptions };

if (processOptionsFromOptions.from) {
processOptionsFromOptions.from = path.resolve(
loaderContext.rootContext,
processOptionsFromOptions.from
);
}

if (processOptionsFromOptions.to) {
processOptionsFromOptions.to = path.resolve(
loaderContext.rootContext,
processOptionsFromOptions.to
);
}

// No need them for processOptions
delete processOptionsFromOptions.config;
delete processOptionsFromOptions.plugins;

const processOptions = {
// TODO path.resolve
from: file,
to: file,
map: false,
Expand Down Expand Up @@ -272,7 +299,7 @@ function getURLType(source) {
return ABSOLUTE_SCHEME.test(source) ? 'absolute' : 'path-relative';
}

function normalizeSourceMap(map, resourcePath) {
function normalizeSourceMap(map, resourceContext) {
let newMap = map;

// Some loader emit source map as string
Expand All @@ -298,7 +325,7 @@ function normalizeSourceMap(map, resourcePath) {
? path.resolve(sourceRoot, path.normalize(source))
: path.normalize(source);

return path.relative(path.dirname(resourcePath), absoluteSource);
return path.relative(resourceContext, absoluteSource);
}

return source;
Expand All @@ -308,7 +335,7 @@ function normalizeSourceMap(map, resourcePath) {
return newMap;
}

function normalizeSourceMapAfterPostcss(map, resourcePath) {
function normalizeSourceMapAfterPostcss(map, resourceContext) {
const newMap = map;

// result.map.file is an optional property that provides the output filename.
Expand All @@ -329,9 +356,7 @@ function normalizeSourceMapAfterPostcss(map, resourcePath) {

// Do no touch `scheme-relative`, `path-absolute` and `absolute` types
if (sourceType === 'path-relative') {
const dirname = path.dirname(resourcePath);

return path.resolve(dirname, source);
return path.resolve(resourceContext, source);
}

return source;
Expand Down
34 changes: 34 additions & 0 deletions test/__snapshots__/config.test.js.snap
Expand Up @@ -31,6 +31,40 @@ exports[`"config" option should work "String" value (relative path): errors 1`]

exports[`"config" option should work "String" value (relative path): warnings 1`] = `Array []`;

exports[`"config" option should work and resolve "from" and "to" options: css 1`] = `
"a { color: black }

.foo {
float: right;
}
"
`;

exports[`"config" option should work and resolve "from" and "to" options: errors 1`] = `Array []`;

exports[`"config" option should work and resolve "from" and "to" options: source map 1`] = `
Object {
"file": "style.css",
"mappings": "AAAA,IAAI,aAAa;;AAEjB;EACE,YAAY;AACd",
"names": Array [],
"sourceRoot": "",
"sources": Array [
"style.css",
],
"sourcesContent": Array [
"a { color: black }

.foo {
float: right;
}
",
],
"version": 3,
}
`;

exports[`"config" option should work and resolve "from" and "to" options: warnings 1`] = `Array []`;

exports[`"config" option should work with "String" value (absolute path): css 1`] = `
"a { color: rgba(0, 0, 0, 1.0) }

Expand Down
61 changes: 57 additions & 4 deletions test/__snapshots__/postcssOptins.test.js.snap
Expand Up @@ -153,7 +153,7 @@ exports[`"postcssOptions" option should work "Function" value: errors 1`] = `Arr

exports[`"postcssOptions" option should work "Function" value: warnings 1`] = `Array []`;

exports[`"postcssOptions" option should work with "from", "to" and "map" options: css 1`] = `
exports[`"postcssOptions" option should work with "from", "to" and "map" options (absolute paths): css 1`] = `
"a {
color: black;
}
Expand Down Expand Up @@ -200,11 +200,64 @@ a {
"
`;

exports[`"postcssOptions" option should work with "from", "to" and "map" options: errors 1`] = `Array []`;
exports[`"postcssOptions" option should work with "from", "to" and "map" options (absolute paths): errors 1`] = `Array []`;

exports[`"postcssOptions" option should work with "from", "to" and "map" options: map 1`] = `undefined`;
exports[`"postcssOptions" option should work with "from", "to" and "map" options (absolute paths): map 1`] = `undefined`;

exports[`"postcssOptions" option should work with "from", "to" and "map" options: warnings 1`] = `Array []`;
exports[`"postcssOptions" option should work with "from", "to" and "map" options (absolute paths): warnings 1`] = `Array []`;

exports[`"postcssOptions" option should work with "from", "to" and "map" options (relative paths): css 1`] = `
"a {
color: black;
}

a {
color: red;
}

a {
color: green;
}

a {
color: blue;
}

.class {
-x-border-color: blue blue *;
-x-color: * #fafafa;
}

.class-foo {
-z-border-color: blue blue *;
-z-color: * #fafafa;
}

.phone {
&_title {
width: 500px;

@media (max-width: 500px) {
width: auto;
}

body.is_dark & {
color: white;
}
}

img {
display: block;
}
}
"
`;

exports[`"postcssOptions" option should work with "from", "to" and "map" options (relative paths): errors 1`] = `Array []`;

exports[`"postcssOptions" option should work with "from", "to" and "map" options (relative paths): map 1`] = `undefined`;

exports[`"postcssOptions" option should work with "from", "to" and "map" options (relative paths): warnings 1`] = `Array []`;

exports[`"postcssOptions" option should work with the "map" option and generate inlined source maps: css 1`] = `
"a {
Expand Down
8 changes: 2 additions & 6 deletions test/config-autoload.test.js
Expand Up @@ -35,12 +35,8 @@ describe('autoload config', () => {
expect(config.parser).toEqual(false);
expect(config.syntax).toEqual(false);
expect(config.map).toEqual(false);
expect(config.from).toEqual(
'./test/fixtures/config-autoload/pkg/index.css'
);
expect(config.to).toEqual(
'./test/fixtures/config-autoload/pkg/expected/index.css'
);
expect(config.from).toEqual('./index.css');
expect(config.to).toEqual('./index.css');
expect(Object.keys(config.plugins).length).toEqual(2);
expect(config.file).toEqual(
path.resolve(testDirectory, 'pkg', 'package.json')
Expand Down
27 changes: 27 additions & 0 deletions test/config.test.js
Expand Up @@ -191,4 +191,31 @@ describe('"config" option', () => {
expect(getWarnings(stats)).toMatchSnapshot('warnings');
expect(getErrors(stats, true)).toMatchSnapshot('errors');
});

it('should work and resolve "from" and "to" options', async () => {
const compiler = getCompiler('./config-scope/css/index.js', {
postcssOptions: {
config: path.resolve(
__dirname,
'./fixtures/config-scope/from-to/postcss.config.js'
),
},
});
const stats = await compile(compiler);

const { css, sourceMap } = getCodeFromBundle('style.css', stats);

sourceMap.sourceRoot = '';
sourceMap.sources = sourceMap.sources.map((source) => {
expect(path.isAbsolute(source)).toBe(false);
expect(source).toBe(path.normalize(source));

return source.replace(/\\/g, '/');
});

expect(css).toMatchSnapshot('css');
expect(sourceMap).toMatchSnapshot('source map');
expect(getWarnings(stats)).toMatchSnapshot('warnings');
expect(getErrors(stats)).toMatchSnapshot('errors');
});
});
4 changes: 2 additions & 2 deletions test/fixtures/config-autoload/pkg/package.json
Expand Up @@ -5,8 +5,8 @@
"parser": false,
"syntax": false,
"map": false,
"from": "./test/fixtures/config-autoload/pkg/index.css",
"to": "./test/fixtures/config-autoload/pkg/expected/index.css",
"from": "./index.css",
"to": "./index.css",
"plugins": [
"postcss-import",
["postcss-nested", {}]
Expand Down
12 changes: 12 additions & 0 deletions test/fixtures/config-scope/from-to/postcss.config.js
@@ -0,0 +1,12 @@
module.exports = {
from: '../../css/style.css',
to: '../../css/style.css',
map: {
inline: false,
annotation: false,
sourcesContent: true,
},
plugins: [
['postcss-short', { prefix: 'x' }]
]
};
40 changes: 26 additions & 14 deletions test/postcssOptins.test.js
Expand Up @@ -7,7 +7,7 @@ import {
} from './helpers';

describe('"postcssOptions" option', () => {
it('should work with "from", "to" and "map" options', async () => {
it('should work with "from", "to" and "map" options (absolute paths)', async () => {
const compiler = getCompiler('./css/index.js', {
postcssOptions: {
from: '/test/from.css',
Expand All @@ -16,25 +16,37 @@ describe('"postcssOptions" option', () => {
},
});
const stats = await compile(compiler);

const codeFromBundle = getCodeFromBundle('style.css', stats);
const notNormalizecodeFromBundle = getCodeFromBundle(
'style.css',
stats,
false
);

const toIsWork = notNormalizecodeFromBundle.sourceMap.file.endsWith(
'to.css'
);
const toIsWork = codeFromBundle.sourceMap.file.endsWith('to.css');
const fromIsWork =
notNormalizecodeFromBundle.sourceMap.sources.filter((i) =>
i.endsWith('from.css')
).length > 0;
codeFromBundle.sourceMap.sources.filter((i) => i.endsWith('from.css'))
.length > 0;

expect(toIsWork).toBe(true);
expect(fromIsWork).toBe(true);
expect(codeFromBundle.css).toMatchSnapshot('css');
expect(codeFromBundle.map).toMatchSnapshot('map');
expect(getWarnings(stats)).toMatchSnapshot('warnings');
expect(getErrors(stats)).toMatchSnapshot('errors');
});

it('should work with "from", "to" and "map" options (relative paths)', async () => {
const compiler = getCompiler('./css/index.js', {
postcssOptions: {
from: './css/style.css',
to: './css/style.css',
map: { inline: false, annotation: false },
},
});
const stats = await compile(compiler);
const codeFromBundle = getCodeFromBundle('style.css', stats);
const toIsWork = codeFromBundle.sourceMap.file.endsWith('style.css');
const fromIsWork =
codeFromBundle.sourceMap.sources.filter((i) => i.endsWith('style.css'))
.length > 0;

expect(toIsWork).toBe(true);
expect(fromIsWork).toBe(true);
expect(codeFromBundle.css).toMatchSnapshot('css');
expect(codeFromBundle.map).toMatchSnapshot('map');
expect(getWarnings(stats)).toMatchSnapshot('warnings');
Expand Down