Skip to content

Commit 1cd5be8

Browse files
authored
Merge pull request #202 from bholloway/initial-v5-changes
Initial v5 changes
2 parents e094fa6 + b168dd3 commit 1cd5be8

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+588
-4070
lines changed

.nvmrc

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
8.9
1+
12

package.json

+8-11
Original file line numberDiff line numberDiff line change
@@ -18,30 +18,27 @@
1818
"devDependencies": {
1919
"blue-tape": "^1.0.0",
2020
"compose-function": "^3.0.3",
21-
"cross-env": "^6.0.3",
21+
"cross-env": "^7.0.3",
2222
"enforce-node-version": "^0.1.0",
2323
"es6-promisify": "^6.0.2",
24-
"escape-string-regexp": "^2.0.0",
24+
"escape-string-regexp": "^4.0.0",
2525
"get-value": "^3.0.1",
2626
"has-prop": "^0.1.2",
2727
"joi": "^14.3.1",
2828
"jshint": "^2.10.3",
29-
"micromatch": "^4.0.2",
30-
"ms": "^2.1.2",
31-
"outdent": "^0.7.0",
29+
"micromatch": "^4.0.4",
30+
"ms": "^2.1.3",
31+
"outdent": "^0.8.0",
3232
"promise-compose": "^1.1.2",
3333
"recursive-readdir": "^2.2.2",
34-
"rework": "1.0.1",
35-
"rework-visit": "1.0.0",
36-
"sinon": "^8.0.2",
34+
"sinon": "^10.0.0",
3735
"tap-diff": "^0.1.1",
3836
"vlq": "^1.0.1"
3937
},
4038
"engines": {
41-
"node": ">=8.9"
39+
"node": ">=12"
4240
},
4341
"resolutions": {
44-
"diff": "^3.5.0",
45-
"lodash": "^4.17.21"
42+
"diff": "^4.0.2"
4643
}
4744
}

packages/resolve-url-loader-filesearch/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
},
2828
"homepage": "https://github.com/bholloway/resolve-url-loader",
2929
"engines": {
30-
"node": ">=8.9"
30+
"node": ">=12"
3131
},
3232
"files": [
3333
"index.js",

packages/resolve-url-loader/index.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ var valueProcessor = require('./lib/value-processor'),
2020
const DEPRECATED_OPTIONS = {
2121
engine: [
2222
'DEP_RESOLVE_URL_LOADER_OPTION_ENGINE',
23-
'the "engine" option is deprecated, "postcss" engine is the default, using "rework" engine is not advised'
23+
'the "engine" option is deprecated, "postcss" engine is the default, there are no other available engines'
2424
],
2525
keepQuery: [
2626
'DEP_RESOLVE_URL_LOADER_OPTION_KEEP_QUERY',

packages/resolve-url-loader/lib/engine/postcss.js

+90-81
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,14 @@
44
*/
55
'use strict';
66

7-
var os = require('os'),
8-
path = require('path'),
9-
postcss = require('postcss');
7+
const os = require('os');
8+
const path = require('path');
9+
const postcss = require('postcss');
1010

11-
var fileProtocol = require('../file-protocol');
12-
var algerbra = require('../position-algerbra');
11+
const fileProtocol = require('../file-protocol');
12+
const algerbra = require('../position-algerbra');
1313

14-
var ORPHAN_CR_REGEX = /\r(?!\n)(.|\n)?/g;
14+
const ORPHAN_CR_REGEX = /\r(?!\n)(.|\n)?/g;
1515

1616
/**
1717
* Process the given CSS content into reworked CSS content.
@@ -24,66 +24,96 @@ var ORPHAN_CR_REGEX = /\r(?!\n)(.|\n)?/g;
2424
*/
2525
function process(sourceFile, sourceContent, params) {
2626
// #107 libsass emits orphan CR not considered newline, postcss does consider newline (content vs source-map mismatch)
27-
var correctedContent = params.removeCR && (os.EOL !== '\r') ?
27+
const correctedContent = params.removeCR && (os.EOL !== '\r') ?
2828
sourceContent.replace(ORPHAN_CR_REGEX, ' $1') :
2929
sourceContent;
3030

31-
/**
32-
* Plugin for postcss that follows SASS transpilation.
33-
*/
34-
const postcssPlugin = {
35-
postcssPlugin: 'postcss-resolve-url',
36-
Declaration: (declaration) => {
37-
var prefix,
38-
isValid = declaration.value && (declaration.value.indexOf('url') >= 0);
39-
if (isValid) {
40-
prefix = declaration.prop + declaration.raws.between;
41-
declaration.value = params.transformDeclaration(declaration.value, getPathsAtChar);
42-
}
31+
// IMPORTANT - prepend file protocol to all sources to avoid problems with source map
32+
const plugin = Object.assign(
33+
() => ({
34+
postcssPlugin: 'postcss-resolve-url',
35+
prepare: () => {
36+
const visited = new Set();
37+
38+
/**
39+
* Given an apparent position find the directory of the original file.
40+
*
41+
* @param startPosApparent {{line: number, column: number}}
42+
* @returns {false|string} Directory of original file or false on invalid
43+
*/
44+
const positionToOriginalDirectory = (startPosApparent) => {
45+
// reverse the original source-map to find the original source file before transpilation
46+
const startPosOriginal =
47+
!!params.sourceMapConsumer &&
48+
params.sourceMapConsumer.originalPositionFor(startPosApparent);
4349

44-
/**
45-
* Create a hash of base path strings.
46-
*
47-
* Position in the declaration is supported by postcss at the position of the url() statement.
48-
*
49-
* @param {number} index Index in the declaration value at which to evaluate
50-
* @throws Error on invalid source map
51-
* @returns {{subString:string, value:string, property:string, selector:string}} Hash of base path strings
52-
*/
53-
function getPathsAtChar(index) {
54-
var subString = declaration.value.slice(0, index),
55-
posSelector = algerbra.sanitise(declaration.parent.source.start),
56-
posProperty = algerbra.sanitise(declaration.source.start),
57-
posValue = algerbra.add([posProperty, algerbra.strToOffset(prefix)]),
58-
posSubString = algerbra.add([posValue, algerbra.strToOffset(subString)]);
50+
// we require a valid directory for the specified file
51+
const directory =
52+
!!startPosOriginal &&
53+
!!startPosOriginal.source &&
54+
fileProtocol.remove(path.dirname(startPosOriginal.source));
5955

60-
var result = {
61-
subString: positionToOriginalDirectory(posSubString),
62-
value : positionToOriginalDirectory(posValue),
63-
property : positionToOriginalDirectory(posProperty),
64-
selector : positionToOriginalDirectory(posSelector)
56+
return directory;
6557
};
6658

67-
var isValid = [result.subString, result.value, result.property, result.selector].every(Boolean);
68-
if (isValid) {
69-
return result;
70-
}
71-
else if (params.sourceMapConsumer) {
72-
throw new Error(
73-
'source-map information is not available at url() declaration ' +
74-
(ORPHAN_CR_REGEX.test(sourceContent) ? '(found orphan CR, try removeCR option)' : '(no orphan CR found)')
75-
);
76-
} else {
77-
throw new Error('a valid source-map is not present (ensure preceding loaders output a source-map)');
78-
}
59+
return {
60+
Declaration: (declaration) => {
61+
var prefix,
62+
isValid = declaration.value && (declaration.value.indexOf('url') >= 0) && !visited.has(declaration);
63+
if (isValid) {
64+
prefix = declaration.prop + declaration.raws.between;
65+
declaration.value = params.transformDeclaration(declaration.value, getPathsAtChar);
66+
visited.add(declaration);
67+
}
68+
69+
/**
70+
* Create a hash of base path strings.
71+
*
72+
* Position in the declaration is supported by postcss at the position of the url() statement.
73+
*
74+
* @param {number} index Index in the declaration value at which to evaluate
75+
* @throws Error on invalid source map
76+
* @returns {{subString:string, value:string, property:string, selector:string}} Hash of base path strings
77+
*/
78+
function getPathsAtChar(index) {
79+
var subString = declaration.value.slice(0, index),
80+
posSelector = algerbra.sanitise(declaration.parent.source.start),
81+
posProperty = algerbra.sanitise(declaration.source.start),
82+
posValue = algerbra.add([posProperty, algerbra.strToOffset(prefix)]),
83+
posSubString = algerbra.add([posValue, algerbra.strToOffset(subString)]);
84+
85+
var result = {
86+
subString: positionToOriginalDirectory(posSubString),
87+
value : positionToOriginalDirectory(posValue),
88+
property : positionToOriginalDirectory(posProperty),
89+
selector : positionToOriginalDirectory(posSelector)
90+
};
91+
92+
var isValid = [result.subString, result.value, result.property, result.selector].every(Boolean);
93+
if (isValid) {
94+
return result;
95+
}
96+
else if (params.sourceMapConsumer) {
97+
throw new Error(
98+
'source-map information is not available at url() declaration ' + (
99+
ORPHAN_CR_REGEX.test(sourceContent) ?
100+
'(found orphan CR, try removeCR option)' :
101+
'(no orphan CR found)'
102+
)
103+
);
104+
} else {
105+
throw new Error('a valid source-map is not present (ensure preceding loaders output a source-map)');
106+
}
107+
}
108+
}
109+
};
79110
}
80-
}
81-
}
111+
}),
112+
{ postcss: true }
113+
);
82114

83-
// prepend file protocol to all sources to avoid problems with source map
84-
return postcss([
85-
postcssPlugin
86-
])
115+
// IMPORTANT - prepend file protocol to all sources to avoid problems with source map
116+
return postcss([plugin])
87117
.process(correctedContent, {
88118
from: fileProtocol.prepend(sourceFile),
89119
map : params.outputSourceMap && {
@@ -93,31 +123,10 @@ function process(sourceFile, sourceContent, params) {
93123
sourcesContent: true // #98 sourcesContent missing from output map
94124
}
95125
})
96-
.then(result => ({
97-
content: result.css,
98-
map : params.outputSourceMap ? fileProtocol.remove(result.map.toJSON()) : null
126+
.then(({css, map}) => ({
127+
content: css,
128+
map : params.outputSourceMap ? fileProtocol.remove(map.toJSON()) : null
99129
}));
100-
101-
/**
102-
* Given an apparent position find the directory of the original file.
103-
*
104-
* @param startPosApparent {{line: number, column: number}}
105-
* @returns {false|string} Directory of original file or false on invalid
106-
*/
107-
function positionToOriginalDirectory(startPosApparent) {
108-
// reverse the original source-map to find the original source file before transpilation
109-
var startPosOriginal =
110-
!!params.sourceMapConsumer &&
111-
params.sourceMapConsumer.originalPositionFor(startPosApparent);
112-
113-
// we require a valid directory for the specified file
114-
var directory =
115-
!!startPosOriginal &&
116-
!!startPosOriginal.source &&
117-
fileProtocol.remove(path.dirname(startPosOriginal.source));
118-
119-
return directory;
120-
}
121130
}
122131

123132
module.exports = process;

0 commit comments

Comments
 (0)