UNPKG

3.88 kBJavaScriptView Raw
1import * as colors from 'kleur/colors';
2import path from 'path';
3function autoDetectExports(fileLoc) {
4 try {
5 return Object.keys(require(fileLoc));
6 }
7 catch (err) {
8 console.error(colors.red(`✘ Could not auto-detect exports for ${colors.bold(fileLoc)}\n${err.message}`));
9 }
10}
11/**
12 * rollup-plugin-wrap-install-targets
13 *
14 * How it works:
15 * 1. An array of "install targets" are passed in, describing all known imports + metadata.
16 * 2. If isTreeshake: Known imports are marked for tree-shaking by appending 'snowpack-wrap:' to the input value.
17 * 3. If autoDetectPackageExports match: Also mark for wrapping, and use automatic export detection.
18 * 4. On load, we return a false virtual file for all "snowpack-wrap:" inputs.
19 * a. That virtual file contains only `export ... from 'ACTUAL_FILE_PATH';` exports
20 * b. Rollup uses those exports to drive its tree-shaking algorithm.
21 * c. Rollup uses those exports to inform its "namedExports" for Common.js entrypoints.
22 */
23export function rollupPluginWrapInstallTargets(isTreeshake, autoDetectPackageExports, installTargets) {
24 const installTargetsByFile = {};
25 function isAutoDetect(normalizedFileLoc) {
26 return autoDetectPackageExports.some((p) => normalizedFileLoc.includes(`node_modules/${p}${p.endsWith('index.js') ? '' : '/'}`));
27 }
28 return {
29 name: 'snowpack:wrap-install-targets',
30 // Mark some inputs for tree-shaking.
31 options(inputOptions) {
32 const input = inputOptions.input;
33 for (const [key, val] of Object.entries(input)) {
34 installTargetsByFile[val] = installTargets.filter((imp) => imp.specifier === key);
35 if (isTreeshake &&
36 installTargetsByFile[val].length > 0 &&
37 !installTargetsByFile[val].some((imp) => imp.namespace || imp.all)) {
38 input[key] = `snowpack-wrap:${val}`;
39 }
40 if (!isTreeshake) {
41 const normalizedFileLoc = val.split(path.win32.sep).join(path.posix.sep);
42 if (isAutoDetect(normalizedFileLoc)) {
43 input[key] = `snowpack-wrap:${val}`;
44 }
45 }
46 }
47 return inputOptions;
48 },
49 resolveId(source) {
50 if (source.startsWith('snowpack-wrap:')) {
51 return source;
52 }
53 return null;
54 },
55 load(id) {
56 if (!id.startsWith('snowpack-wrap:')) {
57 return null;
58 }
59 const fileLoc = id.substring('snowpack-wrap:'.length);
60 // Reduce all install targets into a single "summarized" install target.
61 const treeshakeSummary = installTargetsByFile[fileLoc].reduce((summary, imp) => {
62 summary.default = summary.default || imp.default;
63 summary.namespace = summary.namespace || imp.namespace;
64 summary.named = [...summary.named, ...imp.named];
65 return summary;
66 });
67 let uniqueNamedImports = Array.from(new Set(treeshakeSummary.named));
68 const normalizedFileLoc = fileLoc.split(path.win32.sep).join(path.posix.sep);
69 if (!isTreeshake && isAutoDetect(normalizedFileLoc)) {
70 uniqueNamedImports = autoDetectExports(fileLoc) || uniqueNamedImports;
71 }
72 const result = `
73 ${treeshakeSummary.namespace ? `export * from '${normalizedFileLoc}';` : ''}
74 ${treeshakeSummary.default
75 ? `import __pika_web_default_export_for_treeshaking__ from '${normalizedFileLoc}'; export default __pika_web_default_export_for_treeshaking__;`
76 : ''}
77 ${`export {${uniqueNamedImports.join(',')}} from '${normalizedFileLoc}';`}
78 `;
79 return result;
80 },
81 };
82}