Mirror: Rollup plugin to automatically check the exports of a library for cjs-module-lexer compatibility.
1import { parse, init } from 'cjs-module-lexer';
2import { createFilter } from '@rollup/pluginutils';
3
4function cjsCheck(opts = {}) {
5 const filter = createFilter(opts.include, opts.exclude, {
6 resolve: false
7 });
8
9 return {
10 name: "cjs-check",
11
12 outputOptions(output) {
13 this.enabled = output.format === 'cjs' || output.format === 'umd';
14 return null;
15 },
16
17 async renderChunk(code, chunk) {
18 if (!this.enabled) {
19 return null;
20 } else if (!filter(chunk.fileName)) {
21 return null;
22 } else if (!chunk.exports || !chunk.exports.length) {
23 return null;
24 }
25
26 await init()
27
28 let output;
29 try {
30 output = parse(code);
31 } catch (error) {
32 this.warn(error);
33 return null;
34 }
35
36 const missingReexports = [];
37 const missingExports = [];
38
39 let hasMissing = false;
40 for (const mod of chunk.exports) {
41 if (mod[0] == '*' && !output.reexports.includes(mod.slice(1))) {
42 hasMissing = true;
43 missingReexports.push(mod.slice(1));
44 } else if (mod[0] != '*' && !output.exports.includes(mod)) {
45 hasMissing = true;
46 missingExports.push(mod);
47 }
48 }
49
50 if (hasMissing) {
51 let message = '';
52 if (missingReexports.length) {
53 message += 'The following re-exports are undetected:\n';
54 message += missingReexports.map(x => `- ${x}\n`).join('');
55 }
56
57 if (missingExports.length) {
58 message += 'The following exports are undetected:\n';
59 message += missingExports.map(x => `- ${x}\n`).join('');
60 }
61
62 if (missingExports.length + missingReexports.length >= chunk.exports.length) {
63 message = 'All chunk exports have not been detected. Is the chunk a CommonJS module?'
64 }
65
66 throw new Error(
67 `cjs-module-lexer did not agree with Rollup\'s exports for ${chunk.fileName}.\n${message}`
68 );
69 }
70
71 return null;
72 }
73 };
74}
75
76export default cjsCheck;