Skip to content

Commit c75160c

Browse files
authored
[wip] multi-entry
1 parent 86371f0 commit c75160c

10 files changed

Lines changed: 941 additions & 67 deletions

File tree

_old_getMain.js.bak

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
function replaceName(filename, name) {
2+
return resolve(
3+
dirname(filename),
4+
name + basename(filename).replace(/^[^.]+/, ''),
5+
);
6+
}
7+
8+
/**
9+
* @param {any} exports - package.json "exports" field value
10+
* @param {string} exportPath - the export to look up (eg: '.', './a', './b/c')
11+
* @param {string[]} conditions - conditional export keys to use (note: unlike in resolution, order here *does* define precedence!)
12+
* @param {RegExp|string} [defaultPattern] - only use (resolved) default export filenames that match this pattern
13+
* @param {string} [condition] - (internal) the nearest condition key on the stack
14+
*/
15+
function walk(exports, exportPath, conditions, defaultPattern, condition) {
16+
if (!exports) return;
17+
if (typeof exports === 'string') {
18+
if (
19+
condition === 'default' &&
20+
defaultPattern &&
21+
!exports.match(defaultPattern)
22+
) {
23+
return;
24+
}
25+
return exports;
26+
}
27+
if (Array.isArray(exports)) {
28+
for (const map of exports) {
29+
const r = walk(map, exportPath, conditions, defaultPattern, condition);
30+
if (r) return r;
31+
}
32+
return;
33+
}
34+
const map = exports[exportPath];
35+
if (map) {
36+
const r = walk(map, exportPath, conditions, defaultPattern, condition);
37+
if (r) return r;
38+
}
39+
for (const condition of conditions) {
40+
const map = exports[condition];
41+
if (!map) continue;
42+
const r = walk(map, exportPath, conditions, defaultPattern, condition);
43+
if (r) return r;
44+
}
45+
// return walk(exports['.'] || exports.import || exports.module);
46+
}
47+
48+
function getMain({ options, entry, format }) {
49+
const { pkg } = options;
50+
const pkgMain = options['pkg-main'];
51+
52+
if (!pkgMain) {
53+
return options.output;
54+
}
55+
56+
// package.json export name (see https://nodejs.org/api/packages.html#packages_subpath_exports)
57+
let exportPath = '.';
58+
let mainNoExtension = options.output;
59+
if (options.multipleEntries) {
60+
const commonDir = options.entries
61+
.reduce((acc, entry) => {
62+
entry = dirname(entry).split(sep);
63+
if (!acc) return entry;
64+
if (entry.length < acc.length) acc.length = entry.length;
65+
let last = entry.length - 1;
66+
while (entry[last] !== acc[last]) {
67+
last--;
68+
acc.pop();
69+
}
70+
return acc;
71+
}, undefined)
72+
.join(sep);
73+
console.log('>>>>>', { first: options.entries[0], commonDir });
74+
75+
const isMainEntry = entry.match(
76+
/([\\/])index(\.(umd|cjs|es|m))?\.(mjs|cjs|[tj]sx?)$/,
77+
);
78+
let name = isMainEntry ? mainNoExtension : entry;
79+
mainNoExtension = resolve(dirname(mainNoExtension), basename(name));
80+
if (!isMainEntry) {
81+
exportPath =
82+
'./' +
83+
posix.relative(commonDir, entry.replace(/\.([mc]js|[tj]sx?)$/g, ''));
84+
}
85+
}
86+
mainNoExtension = mainNoExtension.replace(
87+
/(\.(umd|cjs|es|m))?\.(mjs|cjs|[tj]sx?)$/,
88+
'',
89+
);
90+
91+
const mainsByFormat = {};
92+
93+
const MJS = pkg.type === 'module' ? /\.m?js$/i : /\.mjs$/i;
94+
const CJS = pkg.type === 'module' ? /\.cjs$/i : /\.js$/i;
95+
const UMD = /[.-]umd\.c?js$/i;
96+
const CONDITIONS_MJS = ['import', 'module', 'default'];
97+
const CONDITIONS_MODERN = ['modern', 'esmodules', ...CONDITIONS_MJS];
98+
const CONDITIONS_CJS = ['require', 'default'];
99+
const CONDITIONS_UMD = ['umd', 'default'];
100+
101+
mainsByFormat.modern =
102+
walk(pkg.exports, exportPath, CONDITIONS_MODERN, MJS) ||
103+
(pkg.syntax && pkg.syntax.esmodules) ||
104+
pkg.esmodule ||
105+
replaceName('x.modern.js', mainNoExtension);
106+
107+
mainsByFormat.es = walk(pkg.exports, exportPath, CONDITIONS_MJS, MJS);
108+
if (!mainsByFormat.es || mainsByFormat.es === mainsByFormat.modern) {
109+
mainsByFormat.es =
110+
pkg.module && !pkg.module.match(/src\//)
111+
? pkg.module
112+
: pkg['jsnext:main'] || replaceName('x.esm.js', mainNoExtension);
113+
}
114+
115+
mainsByFormat.umd =
116+
walk(pkg.exports, exportPath, CONDITIONS_UMD, UMD) ||
117+
pkg['umd:main'] ||
118+
pkg.unpkg ||
119+
replaceName('x.umd.js', mainNoExtension);
120+
121+
mainsByFormat.cjs = walk(pkg.exports, exportPath, CONDITIONS_CJS, CJS);
122+
if (!mainsByFormat.cjs || mainsByFormat.cjs === mainsByFormat.umd) {
123+
mainsByFormat.cjs =
124+
pkg['cjs:main'] ||
125+
replaceName(pkg.type === 'module' ? 'x.cjs' : 'x.js', mainNoExtension);
126+
}
127+
128+
if (pkg.type === 'module') {
129+
let errors = [];
130+
let filenames = [];
131+
if (mainsByFormat.cjs.endsWith('.js')) {
132+
errors.push('CommonJS');
133+
filenames.push(` "cjs:main": "${mainsByFormat.cjs}",`);
134+
}
135+
if (mainsByFormat.umd.endsWith('.js')) {
136+
errors.push('CommonJS');
137+
const field = pkg['umd:main'] ? 'umd:main' : 'unpkg';
138+
filenames.push(` "${field}": "${mainsByFormat.umd}",`);
139+
}
140+
if (errors.length) {
141+
const warning =
142+
`Warning: A package.json with {"type":"module"} should use .cjs file extensions for` +
143+
` ${errors.join(' and ')} filename${errors.length == 1 ? '' : 's'}:` +
144+
`\n${filenames.join('\n')}`;
145+
stderr(yellow(warning));
146+
}
147+
}
148+
149+
console.log('>> MAIN: ', format, entry, exportPath, mainsByFormat[format]);
150+
151+
return mainsByFormat[format] || mainsByFormat.cjs;
152+
}

package-lock.json

Lines changed: 11 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@
119119
"@babel/plugin-proposal-throw-expressions": "^7.12.1",
120120
"@changesets/changelog-github": "^0.2.7",
121121
"@changesets/cli": "^2.12.0",
122+
"@types/jest": "^26.0.23",
122123
"babel-jest": "^26.6.3",
123124
"cross-env": "^7.0.3",
124125
"directory-tree": "^2.2.5",

src/index.js

Lines changed: 14 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import fs from 'fs';
22
import { resolve, relative, dirname, basename, extname } from 'path';
33
import camelCase from 'camelcase';
44
import escapeStringRegexp from 'escape-string-regexp';
5-
import { blue } from 'kleur';
5+
import { blue, yellow } from 'kleur';
66
import { map, series } from 'asyncro';
77
import glob from 'tiny-glob/sync';
88
import autoprefixer from 'autoprefixer';
@@ -19,7 +19,7 @@ import postcss from 'rollup-plugin-postcss';
1919
import typescript from 'rollup-plugin-typescript2';
2020
import json from '@rollup/plugin-json';
2121
import logError from './log-error';
22-
import { isDir, isFile, stdout, isTruthy, removeScope } from './utils';
22+
import { isDir, isFile, stdout, isTruthy, removeScope, stderr } from './utils';
2323
import { getSizeInfo } from './lib/compressed-size';
2424
import { normalizeMinifyOptions } from './lib/terser';
2525
import {
@@ -29,6 +29,7 @@ import {
2929
} from './lib/option-normalization';
3030
import { getConfigFromPkgJson, getName } from './lib/package-info';
3131
import { shouldCssModules, cssModulesConfig } from './lib/css-modules';
32+
import { computeEntries } from './lib/compute-entries';
3233

3334
// Extensions to use when resolving modules
3435
const EXTENSIONS = ['.ts', '.tsx', '.js', '.jsx', '.es6', '.es', '.mjs'];
@@ -61,8 +62,10 @@ export default async function microbundle(inputOptions) {
6162
options.pkg.name = pkgName;
6263

6364
if (options.sourcemap === 'inline') {
64-
console.log(
65-
'Warning: inline sourcemaps should only be used for debugging purposes.',
65+
stderr(
66+
yellow(
67+
'Warning: inline sourcemaps should only be used for debugging purposes.',
68+
),
6669
);
6770
} else if (options.sourcemap === 'false') {
6871
options.sourcemap = false;
@@ -249,67 +252,6 @@ async function getEntries({ input, cwd }) {
249252
return entries;
250253
}
251254

252-
function replaceName(filename, name) {
253-
return resolve(
254-
dirname(filename),
255-
name + basename(filename).replace(/^[^.]+/, ''),
256-
);
257-
}
258-
259-
function walk(exports) {
260-
if (typeof exports === 'string') return exports;
261-
return walk(exports['.'] || exports.import || exports.module);
262-
}
263-
264-
function getMain({ options, entry, format }) {
265-
const { pkg } = options;
266-
const pkgMain = options['pkg-main'];
267-
268-
if (!pkgMain) {
269-
return options.output;
270-
}
271-
272-
let mainNoExtension = options.output;
273-
if (options.multipleEntries) {
274-
let name = entry.match(
275-
/([\\/])index(\.(umd|cjs|es|m))?\.(mjs|cjs|[tj]sx?)$/,
276-
)
277-
? mainNoExtension
278-
: entry;
279-
mainNoExtension = resolve(dirname(mainNoExtension), basename(name));
280-
}
281-
mainNoExtension = mainNoExtension.replace(
282-
/(\.(umd|cjs|es|m))?\.(mjs|cjs|[tj]sx?)$/,
283-
'',
284-
);
285-
286-
const mainsByFormat = {};
287-
288-
mainsByFormat.es = replaceName(
289-
pkg.module && !pkg.module.match(/src\//)
290-
? pkg.module
291-
: pkg['jsnext:main'] || 'x.esm.js',
292-
mainNoExtension,
293-
);
294-
mainsByFormat.modern = replaceName(
295-
(pkg.exports && walk(pkg.exports)) ||
296-
(pkg.syntax && pkg.syntax.esmodules) ||
297-
pkg.esmodule ||
298-
'x.modern.js',
299-
mainNoExtension,
300-
);
301-
mainsByFormat.cjs = replaceName(
302-
pkg['cjs:main'] || (pkg.type && pkg.type === 'module' ? 'x.cjs' : 'x.js'),
303-
mainNoExtension,
304-
);
305-
mainsByFormat.umd = replaceName(
306-
pkg['umd:main'] || pkg.unpkg || 'x.umd.js',
307-
mainNoExtension,
308-
);
309-
310-
return mainsByFormat[format] || mainsByFormat.cjs;
311-
}
312-
313255
// shebang cache map because the transform only gets run once
314256
const shebang = {};
315257

@@ -417,7 +359,13 @@ function createConfig(options, entry, format, writeMeta) {
417359
let cache;
418360
if (modern) cache = false;
419361

420-
const absMain = resolve(options.cwd, getMain({ options, entry, format }));
362+
const entries = computeEntries({
363+
...options,
364+
entry,
365+
format,
366+
});
367+
const absMain = resolve('.', options.cwd, entries[format] || entries.cjs);
368+
console.log(entries[format], absMain);
421369
const outputDir = dirname(absMain);
422370
const outputEntryFileName = basename(absMain);
423371

0 commit comments

Comments
 (0)