Skip to content

Commit a45e129

Browse files
refactor: code
1 parent 8c50aa9 commit a45e129

File tree

5 files changed

+133
-40
lines changed

5 files changed

+133
-40
lines changed

src/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ export default async function loader(content, sourceMap, meta = {}) {
8282
rc.ctx.webpack = this;
8383

8484
try {
85-
config = await loadConfig(options.config, rc.ctx, rc.path);
85+
config = await loadConfig(options.config, rc.ctx, rc.path, this.fs);
8686
} catch (error) {
8787
callback(error);
8888

src/utils.js

Lines changed: 34 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import path from 'path';
2+
23
import Module from 'module';
34

45
import { cosmiconfig } from 'cosmiconfig';
@@ -7,6 +8,16 @@ import importCwd from 'import-cwd';
78
const parentModule = module;
89
const moduleName = 'postcss';
910

11+
const stat = (inputFileSystem, filePath) =>
12+
new Promise((resolve, reject) => {
13+
inputFileSystem.stat(filePath, (err, stats) => {
14+
if (err) {
15+
reject(err);
16+
}
17+
resolve(stats);
18+
});
19+
});
20+
1021
const createContext = (context) => {
1122
const result = {
1223
cwd: process.cwd(),
@@ -160,43 +171,40 @@ function exec(code, loaderContext) {
160171
return module.exports;
161172
}
162173

163-
function loadConfig(config, context, configPath) {
174+
async function loadConfig(config, context, configPath, inputFileSystem) {
164175
if (config === false) {
165176
return {};
166177
}
167178

168-
const searchPlaces = [
169-
`.${moduleName}rc.js`,
170-
`.${moduleName}rc.yaml`,
171-
`.${moduleName}rc.yml`,
172-
`.${moduleName}rc.json`,
173-
`.${moduleName}rc`,
174-
`${moduleName}.config.js`,
175-
`package.json`,
176-
];
177-
const cosmiconfigOptions = { searchPlaces };
178-
let configFilename;
179-
let configDir;
179+
let searchPath = configPath ? path.resolve(configPath) : process.cwd();
180180

181181
if (typeof config === 'string') {
182-
const parsedPath = path.parse(config);
183-
configFilename = parsedPath.base;
184-
configDir = parsedPath.dir;
182+
searchPath = path.resolve(config);
183+
}
184+
185+
let stats;
185186

186-
cosmiconfigOptions.searchPlaces.unshift(configFilename);
187+
try {
188+
stats = await stat(inputFileSystem, searchPath);
189+
} catch (errorIgnore) {
190+
throw new Error(`No PostCSS Config found in: ${searchPath}`);
187191
}
188192

189-
configDir = configDir || configPath || process.cwd();
193+
const explorer = cosmiconfig(moduleName);
190194

191-
return cosmiconfig(moduleName, cosmiconfigOptions)
192-
.search(configDir)
193-
.then((result) => {
194-
if (!result) {
195-
throw new Error(`No PostCSS Config found in: ${configDir}`);
196-
}
195+
let result;
197196

198-
return processResult(createContext(context), result);
199-
});
197+
try {
198+
if (stats.isFile()) {
199+
result = await explorer.load(searchPath);
200+
} else {
201+
result = await explorer.search(searchPath);
202+
}
203+
} catch (errorIgnore) {
204+
throw new Error(`No PostCSS Config found in: ${searchPath}`);
205+
}
206+
207+
return processResult(createContext(context), result);
200208
}
201209

202210
export { exec, loadConfig };

test/config-autoload.test.js

Lines changed: 30 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
/* eslint-disable global-require */
22

33
import path from 'path';
4+
import fs from 'fs';
45

56
import { loadConfig } from '../src/utils';
67

@@ -32,7 +33,8 @@ describe('config-autoload', () => {
3233
const config = await loadConfig(
3334
null,
3435
{},
35-
path.resolve(testDirectory, 'rc')
36+
path.resolve(testDirectory, 'rc'),
37+
fs
3638
);
3739

3840
expected(config);
@@ -60,7 +62,8 @@ describe('config-autoload', () => {
6062
const config = await loadConfig(
6163
null,
6264
ctx,
63-
path.resolve(testDirectory, 'js/object')
65+
path.resolve(testDirectory, 'js/object'),
66+
fs
6467
);
6568

6669
expected(config);
@@ -86,7 +89,8 @@ describe('config-autoload', () => {
8689
const config = await loadConfig(
8790
null,
8891
ctx,
89-
path.resolve(testDirectory, 'js/array')
92+
path.resolve(testDirectory, 'js/array'),
93+
fs
9094
);
9195

9296
expected(config);
@@ -112,23 +116,29 @@ describe('config-autoload', () => {
112116
const config = await loadConfig(
113117
null,
114118
{},
115-
path.resolve(testDirectory, 'pkg')
119+
path.resolve(testDirectory, 'pkg'),
120+
fs
116121
);
117122

118123
expected(config);
119124
});
120125

121126
it('Loading Config - {Error}', async () => {
122127
try {
123-
await loadConfig(null, {}, path.resolve('unresolved'));
128+
await loadConfig(null, {}, path.resolve('unresolved'), fs);
124129
} catch (error) {
125130
expect(error.message).toMatch(/^No PostCSS Config found in: (.*)$/);
126131
}
127132
});
128133

129134
it('Plugin - {Type} - Invalid', async () => {
130135
try {
131-
await loadConfig(null, {}, path.resolve(testDirectory, 'err/plugins'));
136+
await loadConfig(
137+
null,
138+
{},
139+
path.resolve(testDirectory, 'err/plugins'),
140+
fs
141+
);
132142
} catch (error) {
133143
expect(error.message).toMatch(
134144
/^Invalid PostCSS Plugin found at: (.*)\n\n\(@.*\)$/
@@ -141,7 +151,8 @@ describe('config-autoload', () => {
141151
await loadConfig(
142152
null,
143153
{},
144-
path.resolve(testDirectory, 'err/plugins/object')
154+
path.resolve(testDirectory, 'err/plugins/object'),
155+
fs
145156
);
146157
} catch (error) {
147158
expect(error.message).toMatch(/^Loading PostCSS Plugin failed: .*$/m);
@@ -153,7 +164,8 @@ describe('config-autoload', () => {
153164
await loadConfig(
154165
null,
155166
{},
156-
path.resolve(testDirectory, 'err/plugins/object/options')
167+
path.resolve(testDirectory, 'err/plugins/object/options'),
168+
fs
157169
);
158170
} catch (error) {
159171
expect(error.message).toMatch(/^Loading PostCSS Plugin failed: .*$/m);
@@ -165,7 +177,8 @@ describe('config-autoload', () => {
165177
await loadConfig(
166178
null,
167179
{},
168-
path.resolve(testDirectory, 'err/plugins/array')
180+
path.resolve(testDirectory, 'err/plugins/array'),
181+
fs
169182
);
170183
} catch (error) {
171184
expect(error.message).toMatch(/^Cannot find (.*)$/);
@@ -177,7 +190,8 @@ describe('config-autoload', () => {
177190
await loadConfig(
178191
null,
179192
{},
180-
path.resolve(testDirectory, 'err/plugins/array/options')
193+
path.resolve(testDirectory, 'err/plugins/array/options'),
194+
fs
181195
);
182196
} catch (error) {
183197
expect(error.message).toMatch(/^Cannot find (.*)$/);
@@ -191,7 +205,8 @@ describe('Loading Options - {Error}', () => {
191205
await loadConfig(
192206
null,
193207
{},
194-
path.resolve(testDirectory, 'err/options/parser')
208+
path.resolve(testDirectory, 'err/options/parser'),
209+
fs
195210
);
196211
} catch (error) {
197212
expect(error.message).toMatch(/^Loading PostCSS Parser failed: .*$/m);
@@ -203,7 +218,8 @@ describe('Loading Options - {Error}', () => {
203218
await loadConfig(
204219
null,
205220
{},
206-
path.resolve(testDirectory, 'err/options/syntax')
221+
path.resolve(testDirectory, 'err/options/syntax'),
222+
fs
207223
);
208224
} catch (error) {
209225
expect(error.message).toMatch(/^Loading PostCSS Syntax failed: .*$/m);
@@ -215,7 +231,8 @@ describe('Loading Options - {Error}', () => {
215231
await loadConfig(
216232
null,
217233
{},
218-
path.resolve(testDirectory, 'err/options/stringifier')
234+
path.resolve(testDirectory, 'err/options/stringifier'),
235+
fs
219236
);
220237
} catch (error) {
221238
expect(error.message).toMatch(

test/options/__snapshots__/config.test.js.snap

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,23 @@
11
// Jest Snapshot v1, https://goo.gl/fbAQLP
22

3+
exports[`Config Options should work Config - "string" with path directory: css 1`] = `
4+
"a { color: rgba(255, 0, 0, 1.0) }
5+
"
6+
`;
7+
8+
exports[`Config Options should work Config - "string" with path directory: errors 1`] = `Array []`;
9+
10+
exports[`Config Options should work Config - "string" with path directory: warnings 1`] = `Array []`;
11+
12+
exports[`Config Options should work Config - "string" with relative path: css 1`] = `
13+
"a { color: rgba(255, 0, 0, 1.0) }
14+
"
15+
`;
16+
17+
exports[`Config Options should work Config - "string" with relative path: errors 1`] = `Array []`;
18+
19+
exports[`Config Options should work Config - "string" with relative path: warnings 1`] = `Array []`;
20+
321
exports[`Config Options should work Config - "string": css 1`] = `
422
"a { color: rgba(255, 0, 0, 1.0) }
523
"
@@ -36,6 +54,15 @@ exports[`Config Options should work Config - Context - {Object}: errors 1`] = `A
3654

3755
exports[`Config Options should work Config - Context - {Object}: warnings 1`] = `Array []`;
3856

57+
exports[`Config Options should work Config - Object - path file: css 1`] = `
58+
"a { color: rgba(255, 0, 0, 1.0) }
59+
"
60+
`;
61+
62+
exports[`Config Options should work Config - Object - path file: errors 1`] = `Array []`;
63+
64+
exports[`Config Options should work Config - Object - path file: warnings 1`] = `Array []`;
65+
3966
exports[`Config Options should work Config - Path - {String}: css 1`] = `
4067
"a { color: black }
4168
"

test/options/config.test.js

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,47 @@ describe('Config Options', () => {
5050
expect(getErrors(stats)).toMatchSnapshot('errors');
5151
});
5252

53+
it('should work Config - "string" with relative path', async () => {
54+
const compiler = getCompiler('./css/index.js', {
55+
config: 'test/fixtures/css/custom.config.js',
56+
});
57+
const stats = await compile(compiler);
58+
59+
const codeFromBundle = getCodeFromBundle('style.css', stats);
60+
61+
expect(codeFromBundle.css).toMatchSnapshot('css');
62+
expect(getWarnings(stats)).toMatchSnapshot('warnings');
63+
expect(getErrors(stats)).toMatchSnapshot('errors');
64+
});
65+
66+
it('should work Config - "string" with path directory', async () => {
67+
const compiler = getCompiler('./css/index.js', {
68+
config: 'test/fixtures',
69+
});
70+
const stats = await compile(compiler);
71+
72+
const codeFromBundle = getCodeFromBundle('style.css', stats);
73+
74+
expect(codeFromBundle.css).toMatchSnapshot('css');
75+
expect(getWarnings(stats)).toMatchSnapshot('warnings');
76+
expect(getErrors(stats)).toMatchSnapshot('errors');
77+
});
78+
79+
it('should work Config - Object - path file', async () => {
80+
const compiler = getCompiler('./css/index.js', {
81+
config: {
82+
path: path.resolve(__dirname, '../fixtures/css/custom.config.js'),
83+
},
84+
});
85+
const stats = await compile(compiler);
86+
87+
const codeFromBundle = getCodeFromBundle('style.css', stats);
88+
89+
expect(codeFromBundle.css).toMatchSnapshot('css');
90+
expect(getWarnings(stats)).toMatchSnapshot('warnings');
91+
expect(getErrors(stats)).toMatchSnapshot('errors');
92+
});
93+
5394
it('should work Config - {Object}', async () => {
5495
const compiler = getCompiler('./css/index.js', {});
5596
const stats = await compile(compiler);

0 commit comments

Comments
 (0)