Skip to content

Commit 7c33a9c

Browse files
committed
explicit way to work with paths
1 parent abc214f commit 7c33a9c

File tree

2 files changed

+23
-132
lines changed

2 files changed

+23
-132
lines changed

src/index.js

Lines changed: 22 additions & 131 deletions
Original file line numberDiff line numberDiff line change
@@ -1,145 +1,36 @@
1-
import './guard';
21
import hook from './hook';
3-
import postcss from 'postcss';
4-
import { dirname, join, parse, relative, resolve, sep } from 'path';
52
import { readFileSync } from 'fs';
6-
import isPlainObject from 'lodash.isplainobject';
3+
import { dirname, sep, relative, resolve } from 'path';
4+
import postcss from 'postcss';
75

86
import ExtractImports from 'postcss-modules-extract-imports';
97
import LocalByDefault from 'postcss-modules-local-by-default';
108
import Scope from 'postcss-modules-scope';
119
import Parser from './parser';
1210

13-
let processCss;
14-
let rootDir;
15-
let plugins;
16-
17-
/**
18-
* @param {object} opts
19-
* @param {function} opts.generateScopedName
20-
* @param {function} opts.processCss|.p
21-
* @param {string} opts.rootDir|.root|.d
22-
* @param {array} opts.use|.u
23-
*/
24-
export default function buildOptions(opts = {}) {
25-
if (!isPlainObject(opts)) {
26-
throw new Error('Use plain object');
27-
}
28-
29-
processCss = get(opts, 'processCss|p');
30-
rootDir = get(opts, 'rootDir|root|d');
31-
rootDir = rootDir ? resolve(rootDir) : process.cwd();
32-
33-
const customPlugins = get(opts, 'use|u');
34-
if (Array.isArray(customPlugins)) {
35-
return void (plugins = customPlugins);
36-
}
37-
38-
plugins = [];
39-
40-
plugins.push(
41-
opts.mode
42-
? new LocalByDefault({mode: opts.mode})
43-
: LocalByDefault
44-
);
45-
46-
plugins.push(
47-
opts.createImportedName
48-
? new ExtractImports({createImportedName: opts.createImportedName})
49-
: ExtractImports
50-
);
51-
52-
plugins.push(
53-
opts.generateScopedName
54-
? new Scope({generateScopedName: opts.generateScopedName})
55-
: Scope
56-
);
57-
}
58-
59-
const escapedSeparator = sep.replace(/(.)/g, '\\$1');
60-
const relativePathPattern = new RegExp(`^.{1,2}$|^.{1,2}${escapedSeparator}`);
61-
const tokensByFile = {};
62-
let importNr = 0;
63-
64-
/**
65-
* @param {object} object
66-
* @param {string} keys 'a|b|c'
67-
* @return {*}
68-
*/
69-
function get(object, keys) {
70-
let key;
71-
72-
keys.split('|').some(k => {
73-
if (!object[k]) {
74-
return false;
75-
}
76-
77-
key = k;
78-
return true;
79-
});
11+
let plugins = [ExtractImports, LocalByDefault, Scope];
12+
let rootDir = process.cwd();
8013

81-
return key ? object[key] : null;
14+
export default function (opts = {}) {
15+
plugins = opts.use ? opts.use : [ExtractImports, LocalByDefault, Scope];
16+
rootDir = opts.root ? opts.root : process.cwd();
8217
}
8318

84-
/**
85-
* @param {string} pathname
86-
* @return {boolean}
87-
*/
88-
function isModule(pathname) {
89-
const parsed = parse(pathname);
90-
return !parsed.root && !relativePathPattern.test(parsed.dir);
91-
}
92-
93-
/**
94-
* @param {string} sourceString The file content
95-
* @param {string} sourcePath
96-
* @param {string} trace
97-
* @param {function} pathFetcher
98-
* @return {object}
99-
*/
100-
function load(sourceString, sourcePath, trace, pathFetcher) {
101-
const lazyResult = postcss(plugins.concat(new Parser({ pathFetcher, trace })))
102-
.process(sourceString, {from: sourcePath});
103-
104-
return { injectableSource: lazyResult.css, exportTokens: lazyResult.root.tokens };
105-
}
106-
107-
/**
108-
* @param {string} _newPath
109-
* @param {string} _relativeTo
110-
* @param {string} _trace
111-
* @return {object}
112-
*/
113-
function fetch(_newPath, _relativeTo, _trace) {
19+
function pathFetcher(_newPath, sourcePath, trace) {
11420
const newPath = _newPath.replace(/^["']|["']$/g, '');
115-
const trace = _trace || String.fromCharCode(importNr++);
116-
117-
const relativeDir = dirname(_relativeTo);
118-
const rootRelativePath = resolve(relativeDir, newPath);
119-
let fileRelativePath = resolve(join(rootDir, relativeDir), newPath);
120-
121-
if (isModule(newPath)) {
122-
fileRelativePath = require.resolve(newPath);
123-
}
124-
125-
const tokens = tokensByFile[fileRelativePath];
126-
if (tokens) {
127-
return tokens;
128-
}
129-
130-
const source = readFileSync(fileRelativePath, 'utf-8');
131-
const { exportTokens, injectableSource } = load(source, rootRelativePath, trace, fetch);
132-
133-
tokensByFile[fileRelativePath] = exportTokens;
134-
135-
if (typeof processCss === 'function') {
136-
processCss(injectableSource);
137-
}
138-
139-
return exportTokens;
21+
const filename = /\w/.test(newPath[0])
22+
? require.resolve(newPath)
23+
: resolve(rootDir + dirname(sourcePath), newPath);
24+
const rootRelativePath = sep + relative(rootDir, filename);
25+
const source = readFileSync(filename, 'utf-8');
26+
27+
const result = postcss(plugins.concat(new Parser({ pathFetcher })))
28+
// preprocess
29+
.process(source, {from: rootRelativePath})
30+
.root;
31+
// postprocess
32+
33+
return result.tokens;
14034
}
14135

142-
// setting defaults
143-
buildOptions();
144-
145-
hook(filename => fetch(`.${sep}${relative(rootDir, filename)}`, '/'));
36+
hook(filename => pathFetcher(filename, sep + relative(rootDir, filename)));
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
{
2-
"localName": "_test_cases_non_relative_imports_source__localName _test_cases_non_relative_imports_awesome_theme_oceanic__color"
2+
"localName": "_test_cases_non_relative_imports_source__localName _node_modules_awesome_theme_oceanic__color"
33
}

0 commit comments

Comments
 (0)