-
Notifications
You must be signed in to change notification settings - Fork 20
/
Copy pathindex.js
118 lines (110 loc) Β· 3.63 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
const fs = require("fs");
const crypto = require("crypto");
const crossSpawn = require("cross-spawn");
const path = require("path");
const stripIndent = require("common-tags/lib/stripIndent");
const THIS_FILE = fs.readFileSync(__filename);
module.exports = {
getCacheKey: (fileData, filename, configString, options) => {
// Jest 27 passes a single options bag which contains `configString` rather than as a separate argument
if (!options) {
options = configString;
configString = options.configString;
}
const { instrument } = options;
return (
crypto
.createHash("md5")
.update(THIS_FILE)
.update("\0", "utf8")
.update(fileData)
.update("\0", "utf8")
.update(filename)
.update("\0", "utf8")
.update(configString)
.update("\0", "utf8")
.update(JSON.stringify(options.transformerConfig))
// TODO load postcssrc (the config) sync and make it part of the cache
// key
// .update("\0", "utf8")
// .update(getPostCssConfig(filename))
.update("\0", "utf8")
.update(instrument ? "instrument" : "")
.digest("hex")
);
},
process: (src, filename, config, options) => {
// skip when plain CSS is used
// You can pass config to the transformer in jest.config.js like so:
// "^.+\\.css$": ["jest-transform-css", { modules: true }]
// to enable css module transformation.
const useModules =
config &&
config.transformerConfig &&
((typeof config.transformerConfig.modules === "boolean" &&
config.transformerConfig.modules));
if (!useModules) {
return {
code: stripIndent`
const styleInject = require('style-inject');
styleInject(${JSON.stringify(src)});
module.exports = {};
`,
};
}
// The "process" function of this Jest transform must be sync,
// but postcss is async. So we spawn a sync process to do an sync
// transformation!
// https://twitter.com/kentcdodds/status/1043194634338324480
const postcssRunner = JSON.stringify(path.join(__dirname, "postcss-runner.js"));
const result = crossSpawn.sync("node", [
"-e",
stripIndent`
require(${postcssRunner})(
${JSON.stringify({
src,
filename,
transformConfig: config.transformerConfig,
// options
})}
)
.then(out => { console.log(JSON.stringify(out)) })
`,
]);
// check for errors of postcss-runner.js
const error = result.stderr.toString();
if (error) throw error;
// read results of postcss-runner.js from stdout
let css;
let tokens;
try {
// we likely logged something to the console from postcss-runner
// in order to debug, and hence the parsing fails!
const parsed = JSON.parse(result.stdout.toString());
css = parsed.css;
tokens = parsed.tokens;
if (Array.isArray(parsed.warnings))
parsed.warnings.forEach((warning) => {
console.warn(warning);
});
} catch (error) {
// we forward the logs and return no mappings
console.error(result.stderr.toString());
console.log(result.stdout.toString());
return {
code: stripIndent`
console.error("transform-css: Failed to load '${filename}'");
module.exports = {};
`,
};
}
// Finally, inject the styles to the document
return {
code: stripIndent`
const styleInject = require('style-inject');
styleInject(${JSON.stringify(css)});
module.exports = ${JSON.stringify(tokens)};
`,
};
},
};