Comparing version 3.3.0 to 3.3.1
998
dist/cli.js
@@ -1,282 +0,13 @@ | ||
Object.defineProperty(exports, '__esModule', { value: true }); | ||
#!/usr/bin/env node | ||
var path = require('path'); | ||
var arg = require('arg'); | ||
var fs = require('fs/promises'); | ||
var path = require('path'); | ||
var rollup = require('rollup'); | ||
var pluginWasm = require('@rollup/plugin-wasm'); | ||
var rollupPluginSwc3 = require('rollup-plugin-swc3'); | ||
var commonjs = require('@rollup/plugin-commonjs'); | ||
var shebang = require('rollup-plugin-preserve-shebang'); | ||
var json = require('@rollup/plugin-json'); | ||
var pluginNodeResolve = require('@rollup/plugin-node-resolve'); | ||
var replace = require('@rollup/plugin-replace'); | ||
var prettyBytes = require('pretty-bytes'); | ||
var module$1 = require('module'); | ||
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; } | ||
var path__default = /*#__PURE__*/_interopDefault(path); | ||
var arg__default = /*#__PURE__*/_interopDefault(arg); | ||
var fs__default = /*#__PURE__*/_interopDefault(fs); | ||
var path__default = /*#__PURE__*/_interopDefault(path); | ||
var commonjs__default = /*#__PURE__*/_interopDefault(commonjs); | ||
var shebang__default = /*#__PURE__*/_interopDefault(shebang); | ||
var json__default = /*#__PURE__*/_interopDefault(json); | ||
var replace__default = /*#__PURE__*/_interopDefault(replace); | ||
var prettyBytes__default = /*#__PURE__*/_interopDefault(prettyBytes); | ||
function chunkSizeCollector() { | ||
const sizes = new Map(); | ||
function addSize(name, size) { | ||
sizes.set(name, size); | ||
} | ||
return { | ||
plugin: (cwd)=>{ | ||
return { | ||
name: 'collect-sizes', | ||
augmentChunkHash () { | ||
// Do nothing, but use the hook to keep the plugin instance alive | ||
}, | ||
renderChunk (code, chunk, options) { | ||
const dir = options.dir || options.file && path__default.default.dirname(options.file); | ||
let fileName = chunk.fileName; | ||
if (dir) { | ||
const filePath = path__default.default.join(dir, fileName); | ||
fileName = filePath.startsWith(cwd) ? path__default.default.relative(cwd, filePath) : filePath; | ||
} | ||
addSize(fileName, code.length); | ||
return null; | ||
} | ||
}; | ||
}, | ||
getSizeStats () { | ||
const sizeStats = []; | ||
sizes.forEach((size, name)=>{ | ||
sizeStats.push([ | ||
name, | ||
prettyBytes__default.default(size), | ||
size | ||
]); | ||
}); | ||
return sizeStats; | ||
} | ||
}; | ||
} | ||
function getTypings(pkg) { | ||
return pkg.types || pkg.typings; | ||
} | ||
function getDistPath(distPath, cwd) { | ||
return path.resolve(cwd, distPath); | ||
} | ||
// Reached the end of the export path | ||
function isExportLike(field) { | ||
if (typeof field === 'string') return true; | ||
return Object.entries(field).every(// Every value is string and key is not start with '.' | ||
// TODO: check key is ExportType | ||
([key, value])=>typeof value === 'string' && !key.startsWith('.')); | ||
} | ||
function constructFullExportCondition(value, packageType) { | ||
const isCommonjs = packageType === 'commonjs'; | ||
let result; | ||
if (typeof value === 'string') { | ||
// TODO: determine cjs or esm by "type" field in package.json | ||
result = { | ||
[isCommonjs ? 'require' : 'import']: value | ||
}; | ||
} else { | ||
// TODO: valid export condition, warn if it's not valid | ||
const keys = Object.keys(value); | ||
result = {}; | ||
keys.forEach((key)=>{ | ||
// Filter out nullable value | ||
if (key in value && value[key]) { | ||
result[key] = value[key]; | ||
} | ||
}); | ||
} | ||
return result; | ||
} | ||
function joinRelativePath(...segments) { | ||
let result = path.join(...segments); | ||
// If the first segment starts with './', ensure the result does too. | ||
if (segments[0] === '.' && !result.startsWith('./')) { | ||
result = './' + result; | ||
} | ||
return result; | ||
} | ||
function findExport(name, value, paths, packageType) { | ||
// TODO: handle export condition based on package.type | ||
if (isExportLike(value)) { | ||
paths[name] = constructFullExportCondition(value, packageType); | ||
return; | ||
} | ||
Object.keys(value).forEach((subpath)=>{ | ||
const nextName = joinRelativePath(name, subpath); | ||
const nestedValue = value[subpath]; | ||
findExport(nextName, nestedValue, paths, packageType); | ||
}); | ||
} | ||
/** | ||
* | ||
* Convert package.exports field to paths mapping | ||
* Example | ||
* | ||
* Input: | ||
* { | ||
* ".": { | ||
* "sub": { | ||
* "import": "./sub.js", | ||
* "require": "./sub.cjs", | ||
* "types": "./sub.d.ts | ||
* } | ||
* } | ||
* } | ||
* | ||
* Output: | ||
* { | ||
* "./sub": { | ||
* "import": "./sub.js", | ||
* "require": "./sub.cjs", | ||
* "types": "./sub.d.ts, | ||
* } | ||
* } | ||
* | ||
*/ function parseExport(exportsCondition, packageType) { | ||
const paths = {}; | ||
if (typeof exportsCondition === 'string') { | ||
paths['.'] = constructFullExportCondition(exportsCondition, packageType); | ||
} else if (typeof exportsCondition === 'object') { | ||
Object.keys(exportsCondition).forEach((key)=>{ | ||
const value = exportsCondition[key]; | ||
findExport(key, value, paths, packageType); | ||
}); | ||
} | ||
return paths; | ||
} | ||
/** | ||
* Get package exports paths | ||
* | ||
* Example: | ||
* | ||
* ```json | ||
* { | ||
* "exports": { | ||
* ".": { | ||
* "require": "./dist/index.cjs", | ||
* "module": "./dist/index.esm.js", | ||
* "default": "./dist/index.esm.js" | ||
* }, | ||
* "./foo": { | ||
* "require": "./dist/foo.cjs", | ||
* "module": "./dist/foo.esm.js", | ||
* "default": "./dist/foo.esm.js" | ||
* } | ||
* } | ||
* | ||
* ``` | ||
* | ||
* will be parsed to: | ||
* | ||
* ```js | ||
* { | ||
* '.': { | ||
* main: './dist/index.cjs', | ||
* module: './dist/index.esm.js', | ||
* export: './dist/index.esm.js' | ||
* }, | ||
* './foo': { | ||
* main: './dist/foo.cjs', | ||
* module: './dist/foo.esm.js', | ||
* export: './dist/foo.esm.js' | ||
* } | ||
* | ||
* | ||
* pkg.main and pkg.module will be added to ['.'] if exists | ||
*/ function getExportPaths(pkg) { | ||
const pathsMap = {}; | ||
const packageType = getPackageType(pkg); | ||
const { exports: exportsConditions } = pkg; | ||
if (exportsConditions) { | ||
const paths = parseExport(exportsConditions, packageType); | ||
Object.assign(pathsMap, paths); | ||
} | ||
// main export '.' from main/module/typings | ||
const defaultMainExport = constructFullExportCondition({ | ||
[packageType === 'commonjs' ? 'require' : 'import']: pkg.main, | ||
module: pkg.module, | ||
types: getTypings(pkg) | ||
}, packageType); | ||
// Merge the main export into '.' paths | ||
const mainExport = Object.assign({}, pathsMap['.'], defaultMainExport); | ||
// main export is not empty | ||
if (Object.keys(mainExport).length > 0) { | ||
pathsMap['.'] = mainExport; | ||
} | ||
return pathsMap; | ||
} | ||
function getPackageType(pkg) { | ||
return pkg.type || 'commonjs'; | ||
} | ||
function constructDefaultExportCondition(value, packageType) { | ||
const objValue = typeof value === 'string' ? { | ||
[packageType === 'commonjs' ? 'require' : 'import']: value, | ||
types: getTypings(value) | ||
} : value; | ||
return constructFullExportCondition(objValue, packageType); | ||
} | ||
function isEsmExportName(name) { | ||
return [ | ||
'import', | ||
'module', | ||
'react-native', | ||
'react-server', | ||
'edge-light' | ||
].includes(name); | ||
} | ||
function isCjsExportName(name) { | ||
return [ | ||
'require', | ||
'main', | ||
'node', | ||
'default' | ||
].includes(name); | ||
} | ||
function getExportConditionDist(pkg, parsedExportCondition, cwd) { | ||
const dist = []; | ||
const existed = new Set(); | ||
const exportTypes = Object.keys(parsedExportCondition.export); | ||
for (const key of exportTypes){ | ||
if (key === 'types') { | ||
continue; | ||
} | ||
const relativePath = parsedExportCondition.export[key]; | ||
const distFile = getDistPath(relativePath, cwd); | ||
let format = 'esm'; | ||
if (isEsmExportName(key)) { | ||
format = 'esm'; | ||
} else if (isCjsExportName(key)) { | ||
format = 'cjs'; | ||
} | ||
// Deduplicate the same path jobs | ||
// TODO: detect conflicts paths but with different format | ||
if (existed.has(distFile)) { | ||
continue; | ||
} | ||
existed.add(distFile); | ||
dist.push({ | ||
format, | ||
file: distFile | ||
}); | ||
} | ||
if (dist.length === 0) { | ||
// TODO: Deprecate this warning and behavior in v3 | ||
console.error(`Doesn't fin any exports in ${pkg.name}, using default dist path dist/index.js`); | ||
dist.push({ | ||
format: 'esm', | ||
file: getDistPath('dist/index.js', cwd) | ||
}); | ||
} | ||
return dist; | ||
} | ||
function asyncGeneratorStep$3(gen, resolve, reject, _next, _throw, key, arg) { | ||
function asyncGeneratorStep$1(gen, resolve, reject, _next, _throw, key, arg) { | ||
try { | ||
@@ -295,3 +26,3 @@ var info = gen[key](arg); | ||
} | ||
function _async_to_generator$3(fn) { | ||
function _async_to_generator$1(fn) { | ||
return function() { | ||
@@ -302,6 +33,6 @@ var self = this, args = arguments; | ||
function _next(value) { | ||
asyncGeneratorStep$3(gen, resolve, reject, _next, _throw, "next", value); | ||
asyncGeneratorStep$1(gen, resolve, reject, _next, _throw, "next", value); | ||
} | ||
function _throw(err) { | ||
asyncGeneratorStep$3(gen, resolve, reject, _next, _throw, "throw", err); | ||
asyncGeneratorStep$1(gen, resolve, reject, _next, _throw, "throw", err); | ||
} | ||
@@ -316,2 +47,12 @@ _next(undefined); | ||
} | ||
const formatDuration = (duration)=>duration >= 1000 ? `${duration / 1000}s` : `${duration}ms`; | ||
function hasPackageJson(cwd) { | ||
return _hasPackageJson.apply(this, arguments); | ||
} | ||
function _hasPackageJson() { | ||
_hasPackageJson = _async_to_generator$1(function*(cwd) { | ||
return yield fileExists(path__default.default.resolve(cwd, 'package.json')); | ||
}); | ||
return _hasPackageJson.apply(this, arguments); | ||
} | ||
function getPackageMeta(cwd) { | ||
@@ -321,3 +62,3 @@ return _getPackageMeta.apply(this, arguments); | ||
function _getPackageMeta() { | ||
_getPackageMeta = _async_to_generator$3(function*(cwd) { | ||
_getPackageMeta = _async_to_generator$1(function*(cwd) { | ||
const pkgFilePath = path__default.default.resolve(cwd, 'package.json'); | ||
@@ -349,3 +90,3 @@ let targetPackageJson = {}; | ||
function _fileExists() { | ||
_fileExists = _async_to_generator$3(function*(filePath) { | ||
_fileExists = _async_to_generator$1(function*(filePath) { | ||
try { | ||
@@ -363,46 +104,6 @@ yield fs__default.default.access(filePath); | ||
} | ||
// . -> pkg name | ||
// ./lite -> <pkg name>/lite | ||
function getExportPath(pkg, cwd, exportName) { | ||
const name = pkg.name || path__default.default.basename(cwd); | ||
if (exportName === '.' || !exportName) return name; | ||
return path__default.default.join(name, exportName); | ||
} | ||
const isNotNull = (n)=>Boolean(n); | ||
const SRC = 'src' // resolve from src/ directory | ||
; | ||
function resolveSourceFile(cwd, filename) { | ||
return path__default.default.resolve(cwd, SRC, filename); | ||
} | ||
// Map '.' -> './index.[ext]' | ||
// Map './lite' -> './lite.[ext]' | ||
// Return undefined if no match or if it's package.json exports | ||
function getSourcePathFromExportPath(cwd, exportPath) { | ||
return _getSourcePathFromExportPath.apply(this, arguments); | ||
} | ||
function _getSourcePathFromExportPath() { | ||
_getSourcePathFromExportPath = _async_to_generator$3(function*(cwd, exportPath) { | ||
const exts = [ | ||
'js', | ||
'cjs', | ||
'mjs', | ||
'jsx', | ||
'ts', | ||
'tsx' | ||
]; | ||
for (const ext of exts){ | ||
// ignore package.json | ||
if (exportPath.endsWith('package.json')) return; | ||
if (exportPath === '.') exportPath = './index'; | ||
const filename = resolveSourceFile(cwd, `${exportPath}.${ext}`); | ||
if (yield fileExists(filename)) { | ||
return filename; | ||
} | ||
} | ||
return; | ||
}); | ||
return _getSourcePathFromExportPath.apply(this, arguments); | ||
} | ||
function asyncGeneratorStep$2(gen, resolve, reject, _next, _throw, key, arg) { | ||
var version = "3.3.1"; | ||
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { | ||
try { | ||
@@ -421,3 +122,3 @@ var info = gen[key](arg); | ||
} | ||
function _async_to_generator$2(fn) { | ||
function _async_to_generator(fn) { | ||
return function() { | ||
@@ -428,6 +129,6 @@ var self = this, args = arguments; | ||
function _next(value) { | ||
asyncGeneratorStep$2(gen, resolve, reject, _next, _throw, "next", value); | ||
asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); | ||
} | ||
function _throw(err) { | ||
asyncGeneratorStep$2(gen, resolve, reject, _next, _throw, "throw", err); | ||
asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); | ||
} | ||
@@ -438,526 +139,165 @@ _next(undefined); | ||
} | ||
function _extends$1() { | ||
_extends$1 = Object.assign || function(target) { | ||
for(var i = 1; i < arguments.length; i++){ | ||
var source = arguments[i]; | ||
for(var key in source){ | ||
if (Object.prototype.hasOwnProperty.call(source, key)) { | ||
target[key] = source[key]; | ||
} | ||
} | ||
} | ||
return target; | ||
}; | ||
return _extends$1.apply(this, arguments); | ||
const helpMessage = ` | ||
Usage: bunchee [options] | ||
Options: | ||
-v, --version output the version number | ||
-w, --watch watch src files changes | ||
-m, --minify compress output. default: false | ||
-o, --output <file> specify output filename | ||
-f, --format <format> type of output (esm, amd, cjs, iife, umd, system), default: esm | ||
-h, --help output usage information | ||
--external <mod> specify an external dependency, separate by comma | ||
--no-external do not bundle external dependencies | ||
--target <target> js features target: swc target es versions. default: es2016 | ||
--runtime <runtime> build runtime (nodejs, browser). default: browser | ||
--env <env> inlined process env variables, separate by comma. default: NODE_ENV | ||
--cwd <cwd> specify current working directory | ||
--sourcemap enable sourcemap generation, default: false | ||
--dts determine if need to generate types, default: false | ||
`; | ||
function help() { | ||
logger.log(helpMessage); | ||
} | ||
const minifyOptions = { | ||
compress: true, | ||
format: { | ||
comments: 'some', | ||
wrapFuncArgs: false, | ||
preserveAnnotations: true | ||
}, | ||
mangle: { | ||
toplevel: true | ||
} | ||
}; | ||
// This can also be passed down as stats from top level | ||
const sizeCollector = chunkSizeCollector(); | ||
function getBuildEnv(envs) { | ||
if (!envs.includes('NODE_ENV')) { | ||
envs.push('NODE_ENV'); | ||
} | ||
const envVars = envs.reduce((acc, key)=>{ | ||
const value = process.env[key]; | ||
if (typeof value !== 'undefined') { | ||
acc['process.env.' + key] = JSON.stringify(value); | ||
} | ||
return acc; | ||
}, {}); | ||
return envVars; | ||
function lintPackage(cwd) { | ||
return _lintPackage.apply(this, arguments); | ||
} | ||
function buildInputConfig(entry, pkg, options, cwd, { tsConfigPath , tsCompilerOptions }, dtsOnly) { | ||
var _options_external; | ||
const externals = options.noExternal ? [] : [ | ||
pkg.peerDependencies, | ||
pkg.dependencies, | ||
pkg.peerDependenciesMeta | ||
].filter((n)=>Boolean(n)).map((o)=>Object.keys(o)).reduce((a, b)=>a.concat(b), []).concat(((_options_external = options.external) != null ? _options_external : []).concat(pkg.name ? [ | ||
pkg.name | ||
] : [])); | ||
const { useTypescript , runtime , target: jscTarget , minify } = options; | ||
const hasSpecifiedTsTarget = Boolean((tsCompilerOptions == null ? void 0 : tsCompilerOptions.target) && tsConfigPath); | ||
const sizePlugin = sizeCollector.plugin(cwd); | ||
const commonPlugins = [ | ||
shebang__default.default(), | ||
sizePlugin | ||
]; | ||
const plugins = (dtsOnly ? [ | ||
...commonPlugins, | ||
useTypescript && require('rollup-plugin-dts').default({ | ||
compilerOptions: _extends$1({}, tsCompilerOptions, { | ||
declaration: true, | ||
noEmit: false, | ||
noEmitOnError: true, | ||
emitDeclarationOnly: true, | ||
checkJs: false, | ||
declarationMap: false, | ||
skipLibCheck: true, | ||
preserveSymlinks: false, | ||
target: 'esnext', | ||
module: 'esnext', | ||
incremental: false, | ||
jsx: tsCompilerOptions.jsx || 'react' | ||
}) | ||
}) | ||
] : [ | ||
...commonPlugins, | ||
replace__default.default({ | ||
values: getBuildEnv(options.env || []), | ||
preventAssignment: true | ||
}), | ||
pluginNodeResolve.nodeResolve({ | ||
preferBuiltins: runtime === 'node', | ||
extensions: [ | ||
'.mjs', | ||
'.cjs', | ||
'.js', | ||
'.json', | ||
'.node', | ||
'.jsx' | ||
] | ||
}), | ||
commonjs__default.default({ | ||
include: /node_modules\// | ||
}), | ||
json__default.default(), | ||
pluginWasm.wasm(), | ||
rollupPluginSwc3.swc({ | ||
include: /\.(m|c)?[jt]sx?$/, | ||
exclude: 'node_modules', | ||
tsconfig: tsConfigPath, | ||
jsc: _extends$1({}, !hasSpecifiedTsTarget && { | ||
target: jscTarget | ||
}, { | ||
loose: true, | ||
externalHelpers: false, | ||
parser: { | ||
syntax: useTypescript ? 'typescript' : 'ecmascript', | ||
[useTypescript ? 'tsx' : 'jsx']: true, | ||
privateMethod: true, | ||
classPrivateProperty: true, | ||
exportDefaultFrom: true | ||
} | ||
}, minify && { | ||
minify: _extends$1({}, minifyOptions, { | ||
sourceMap: options.sourcemap | ||
}) | ||
}), | ||
sourceMaps: options.sourcemap, | ||
inlineSourcesContent: false | ||
}) | ||
]).filter(isNotNull); | ||
return { | ||
input: entry, | ||
external (id) { | ||
return externals.some((name)=>id === name || id.startsWith(name + '/')); | ||
}, | ||
plugins, | ||
treeshake: { | ||
propertyReadSideEffects: false | ||
}, | ||
onwarn (warning, warn) { | ||
const code = warning.code || ''; | ||
// Some may not have types, like CLI binary | ||
if (dtsOnly && code === 'EMPTY_BUNDLE') return; | ||
if ([ | ||
'MIXED_EXPORTS', | ||
'PREFER_NAMED_EXPORTS', | ||
'UNRESOLVED_IMPORT', | ||
'THIS_IS_UNDEFINED' | ||
].includes(code)) return; | ||
// If the circular dependency warning is from node_modules, ignore it | ||
if (code === 'CIRCULAR_DEPENDENCY' && /Circular dependency: node_modules/.test(warning.message)) { | ||
return; | ||
} | ||
warn(warning); | ||
function _lintPackage() { | ||
_lintPackage = _async_to_generator(function*(cwd) { | ||
// Not package.json detected, skip package linting | ||
if (!(yield hasPackageJson(cwd))) { | ||
return; | ||
} | ||
}; | ||
} | ||
function hasEsmExport(exportPaths, tsCompilerOptions) { | ||
let hasEsm = false; | ||
for(const key in exportPaths){ | ||
const exportInfo = exportPaths[key]; | ||
const exportNames = Object.keys(exportInfo); | ||
if (exportNames.some((name)=>isEsmExportName(name))) { | ||
hasEsm = true; | ||
break; | ||
} | ||
} | ||
return Boolean(hasEsm || (tsCompilerOptions == null ? void 0 : tsCompilerOptions.esModuleInterop)); | ||
} | ||
function buildOutputConfigs(pkg, exportPaths, options, exportCondition, cwd, { tsCompilerOptions }, dtsOnly) { | ||
const { format } = options; | ||
// Add esm mark and interop helper if esm export is detected | ||
const useEsModuleMark = hasEsmExport(exportPaths, tsCompilerOptions); | ||
const typings = getTypings(pkg); | ||
const file = options.file && path.resolve(cwd, options.file); | ||
const dtsDir = typings ? path.dirname(path.resolve(cwd, typings)) : path.resolve(cwd, 'dist'); | ||
// file base name without extension | ||
const name = file ? file.replace(new RegExp(`${path.extname(file)}$`), '') : undefined; | ||
// TODO: simplify dts file name detection | ||
const dtsFile = exportCondition.export['types'] ? path.resolve(cwd, exportCondition.export['types']) : file ? name + '.d.ts' : (exportCondition == null ? void 0 : exportCondition.name) ? path.resolve(dtsDir, (exportCondition.name === '.' ? 'index' : exportCondition.name) + '.d.ts') : typings && path.resolve(cwd, typings); | ||
// If there's dts file, use `output.file` | ||
const dtsPathConfig = dtsFile ? { | ||
file: dtsFile | ||
} : { | ||
dir: dtsDir | ||
}; | ||
return _extends$1({ | ||
name: pkg.name || name | ||
}, dtsOnly ? dtsPathConfig : { | ||
file: file | ||
}, { | ||
format, | ||
exports: 'named', | ||
esModule: useEsModuleMark || 'if-default-prop', | ||
interop: 'auto', | ||
freeze: false, | ||
strict: false, | ||
sourcemap: options.sourcemap | ||
}); | ||
} | ||
// build configs for each entry from package exports | ||
function buildEntryConfig(pkg, entryPath, exportPaths, bundleConfig, cwd, tsOptions, dtsOnly) { | ||
return _buildEntryConfig.apply(this, arguments); | ||
} | ||
function _buildEntryConfig() { | ||
_buildEntryConfig = _async_to_generator$2(function*(pkg, entryPath, exportPaths, bundleConfig, cwd, tsOptions, dtsOnly) { | ||
const configs = Object.keys(exportPaths).map(/*#__PURE__*/ _async_to_generator$2(function*(entryExport) { | ||
// TODO: improve the source detection | ||
const source = (yield getSourcePathFromExportPath(cwd, entryExport)) || entryPath; | ||
if (!source) return undefined; | ||
const exportCondition = { | ||
source, | ||
name: entryExport, | ||
export: exportPaths[entryExport] | ||
}; | ||
const entry = resolveSourceFile(cwd, source); | ||
const rollupConfig = buildConfig(entry, pkg, exportPaths, bundleConfig, exportCondition, cwd, tsOptions, dtsOnly); | ||
return rollupConfig; | ||
})); | ||
return (yield Promise.all(configs)).filter((n)=>Boolean(n)); | ||
}); | ||
return _buildEntryConfig.apply(this, arguments); | ||
} | ||
function buildConfig(entry, pkg, exportPaths, bundleConfig, exportCondition, cwd, tsOptions, dtsOnly) { | ||
const { file } = bundleConfig; | ||
const useTypescript = Boolean(tsOptions.tsConfigPath); | ||
const options = _extends$1({}, bundleConfig, { | ||
useTypescript | ||
}); | ||
const inputOptions = buildInputConfig(entry, pkg, options, cwd, tsOptions, dtsOnly); | ||
const outputExports = getExportConditionDist(pkg, exportCondition, cwd); | ||
let outputConfigs = []; | ||
// Generate dts job - single config | ||
if (dtsOnly) { | ||
outputConfigs = [ | ||
buildOutputConfigs(pkg, exportPaths, _extends$1({}, bundleConfig, { | ||
format: 'es', | ||
useTypescript | ||
}), exportCondition, cwd, tsOptions, dtsOnly) | ||
]; | ||
} else { | ||
// multi outputs with specified format | ||
outputConfigs = outputExports.map((exportDist)=>{ | ||
return buildOutputConfigs(pkg, exportPaths, _extends$1({}, bundleConfig, { | ||
file: exportDist.file, | ||
format: exportDist.format, | ||
useTypescript | ||
}), exportCondition, cwd, tsOptions, dtsOnly); | ||
const { publint } = yield import('publint'); | ||
const { printMessage } = yield import('publint/utils'); | ||
const messages = yield publint({ | ||
pkgDir: cwd, | ||
level: 'error' | ||
}); | ||
// CLI output option is always prioritized | ||
if (file) { | ||
var _outputExports_; | ||
const fallbackFormat = (_outputExports_ = outputExports[0]) == null ? void 0 : _outputExports_.format; | ||
outputConfigs = [ | ||
buildOutputConfigs(pkg, exportPaths, _extends$1({}, bundleConfig, { | ||
file, | ||
format: bundleConfig.format || fallbackFormat, | ||
useTypescript | ||
}), exportCondition, cwd, tsOptions, dtsOnly) | ||
]; | ||
const pkg = yield getPackageMeta(cwd); | ||
for (const message of messages){ | ||
console.log(printMessage(message, pkg)); | ||
} | ||
} | ||
return { | ||
input: inputOptions, | ||
output: outputConfigs, | ||
exportName: exportCondition.name || '.' | ||
}; | ||
} | ||
function asyncGeneratorStep$1(gen, resolve, reject, _next, _throw, key, arg) { | ||
try { | ||
var info = gen[key](arg); | ||
var value = info.value; | ||
} catch (error) { | ||
reject(error); | ||
return; | ||
} | ||
if (info.done) { | ||
resolve(value); | ||
} else { | ||
Promise.resolve(value).then(_next, _throw); | ||
} | ||
} | ||
function _async_to_generator$1(fn) { | ||
return function() { | ||
var self = this, args = arguments; | ||
return new Promise(function(resolve, reject) { | ||
var gen = fn.apply(self, args); | ||
function _next(value) { | ||
asyncGeneratorStep$1(gen, resolve, reject, _next, _throw, "next", value); | ||
} | ||
function _throw(err) { | ||
asyncGeneratorStep$1(gen, resolve, reject, _next, _throw, "throw", err); | ||
} | ||
_next(undefined); | ||
}); | ||
}; | ||
} | ||
let hasLoggedTsWarning = false; | ||
function resolveTypescript(cwd) { | ||
let ts; | ||
const m = new module$1.Module('', undefined); | ||
m.paths = module$1.Module._nodeModulePaths(cwd); | ||
try { | ||
ts = m.require('typescript'); | ||
} catch (_) { | ||
console.error(_); | ||
if (!hasLoggedTsWarning) { | ||
hasLoggedTsWarning = true; | ||
exit('Could not load TypeScript compiler. Try to install `typescript` as dev dependency'); | ||
} | ||
} | ||
return ts; | ||
} | ||
function resolveTsConfig(cwd) { | ||
return _resolveTsConfig.apply(this, arguments); | ||
} | ||
function _resolveTsConfig() { | ||
_resolveTsConfig = _async_to_generator$1(function*(cwd) { | ||
let tsCompilerOptions = {}; | ||
let tsConfigPath; | ||
const ts = resolveTypescript(cwd); | ||
tsConfigPath = path.resolve(cwd, 'tsconfig.json'); | ||
if (yield fileExists(tsConfigPath)) { | ||
const basePath = tsConfigPath ? path.dirname(tsConfigPath) : cwd; | ||
const tsconfigJSON = ts.readConfigFile(tsConfigPath, ts.sys.readFile).config; | ||
tsCompilerOptions = ts.parseJsonConfigFileContent(tsconfigJSON, ts.sys, basePath).options; | ||
} else { | ||
tsConfigPath = undefined; | ||
return null; | ||
} | ||
return { | ||
tsCompilerOptions, | ||
tsConfigPath | ||
}; | ||
}); | ||
return _resolveTsConfig.apply(this, arguments); | ||
return _lintPackage.apply(this, arguments); | ||
} | ||
function logSizeStats() { | ||
const stats = sizeCollector.getSizeStats(); | ||
const maxLength = Math.max(...stats.map(([filename])=>filename.length)); | ||
stats.forEach(([filename, prettiedSize])=>{ | ||
const padding = ' '.repeat(maxLength - filename.length); | ||
const action = filename.endsWith('.d.ts') ? 'Typed' : 'Built'; | ||
logger.log(` ✓ ${action} ${filename}${padding} - ${prettiedSize}`); | ||
function parseCliArgs(argv) { | ||
let args; | ||
args = arg__default.default({ | ||
'--cwd': String, | ||
'--dts': Boolean, | ||
'--output': String, | ||
'--format': String, | ||
'--watch': Boolean, | ||
'--minify': Boolean, | ||
'--help': Boolean, | ||
'--version': Boolean, | ||
'--runtime': String, | ||
'--target': String, | ||
'--sourcemap': Boolean, | ||
'--env': String, | ||
'--external': String, | ||
'--no-external': Boolean, | ||
'-h': '--help', | ||
'-v': '--version', | ||
'-w': '--watch', | ||
'-o': '--output', | ||
'-f': '--format', | ||
'-m': '--minify' | ||
}, { | ||
permissive: true, | ||
argv | ||
}); | ||
} | ||
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { | ||
try { | ||
var info = gen[key](arg); | ||
var value = info.value; | ||
} catch (error) { | ||
reject(error); | ||
return; | ||
} | ||
if (info.done) { | ||
resolve(value); | ||
} else { | ||
Promise.resolve(value).then(_next, _throw); | ||
} | ||
} | ||
function _async_to_generator(fn) { | ||
return function() { | ||
var self = this, args = arguments; | ||
return new Promise(function(resolve, reject) { | ||
var gen = fn.apply(self, args); | ||
function _next(value) { | ||
asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); | ||
} | ||
function _throw(err) { | ||
asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); | ||
} | ||
_next(undefined); | ||
}); | ||
const source = args._[0]; | ||
const parsedArgs = { | ||
source, | ||
format: args['--format'], | ||
file: args['--output'], | ||
watch: args['--watch'], | ||
minify: args['--minify'], | ||
sourcemap: !!args['--sourcemap'], | ||
cwd: args['--cwd'], | ||
dts: args['--dts'], | ||
help: args['--help'], | ||
version: args['--version'], | ||
runtime: args['--runtime'], | ||
target: args['--target'], | ||
external: !!args['--no-external'] ? null : args['--external'], | ||
env: args['--env'] | ||
}; | ||
return parsedArgs; | ||
} | ||
function _extends() { | ||
_extends = Object.assign || function(target) { | ||
for(var i = 1; i < arguments.length; i++){ | ||
var source = arguments[i]; | ||
for(var key in source){ | ||
if (Object.prototype.hasOwnProperty.call(source, key)) { | ||
target[key] = source[key]; | ||
} | ||
} | ||
} | ||
return target; | ||
}; | ||
return _extends.apply(this, arguments); | ||
function run(args) { | ||
return _run.apply(this, arguments); | ||
} | ||
function _object_without_properties_loose(source, excluded) { | ||
if (source == null) return {}; | ||
var target = {}; | ||
var sourceKeys = Object.keys(source); | ||
var key, i; | ||
for(i = 0; i < sourceKeys.length; i++){ | ||
key = sourceKeys[i]; | ||
if (excluded.indexOf(key) >= 0) continue; | ||
target[key] = source[key]; | ||
} | ||
return target; | ||
} | ||
function assignDefault(options, name, defaultValue) { | ||
if (!(name in options) || options[name] == null) { | ||
options[name] = defaultValue; | ||
} | ||
} | ||
function hasMultiEntryExport(exportPaths) { | ||
const exportKeys = Object.keys(exportPaths).filter((key)=>key !== './package.json'); | ||
return exportKeys.length > 0 && exportKeys.every((name)=>name.startsWith('.')); | ||
} | ||
function bundle(entryPath) { | ||
return _bundle.apply(this, arguments); | ||
} | ||
function _bundle() { | ||
_bundle = _async_to_generator(function*(entryPath, _param = {}) { | ||
var { cwd: _cwd } = _param, options = _object_without_properties_loose(_param, [ | ||
"cwd" | ||
]); | ||
const cwd = path.resolve(process.cwd(), _cwd || ''); | ||
assignDefault(options, 'format', 'es'); | ||
assignDefault(options, 'minify', false); | ||
assignDefault(options, 'target', 'es2015'); | ||
const pkg = yield getPackageMeta(cwd); | ||
const packageType = getPackageType(pkg); | ||
const exportPaths = getExportPaths(pkg); | ||
const exportKeys = Object.keys(exportPaths).filter((key)=>key !== './package.json'); | ||
// const exportPathsLength = Object.keys(exportPaths).length | ||
const isMultiEntries = hasMultiEntryExport(exportPaths) // exportPathsLength > 1 | ||
; | ||
const tsConfig = yield resolveTsConfig(cwd); | ||
const hasTsConfig = Boolean(tsConfig == null ? void 0 : tsConfig.tsConfigPath); | ||
const defaultTsOptions = { | ||
tsConfigPath: tsConfig == null ? void 0 : tsConfig.tsConfigPath, | ||
tsCompilerOptions: (tsConfig == null ? void 0 : tsConfig.tsCompilerOptions) || {} | ||
function _run() { | ||
_run = _async_to_generator(function*(args) { | ||
var _args_external; | ||
const { source , format , watch , minify , sourcemap , target , runtime , dts , env } = args; | ||
const cwd = args.cwd || process.cwd(); | ||
const file = args.file ? path__default.default.resolve(cwd, args.file) : undefined; | ||
const bundleConfig = { | ||
dts, | ||
file, | ||
format, | ||
cwd, | ||
target, | ||
runtime, | ||
external: ((_args_external = args.external) == null ? void 0 : _args_external.split(',')) || [], | ||
watch: !!watch, | ||
minify: !!minify, | ||
sourcemap: sourcemap === false ? false : true, | ||
env: (env == null ? void 0 : env.split(',')) || [] | ||
}; | ||
// Handle single entry file | ||
if (!isMultiEntries) { | ||
// Use specified string file path if possible, then fallback to the default behavior entry picking logic | ||
// e.g. "exports": "./dist/index.js" -> use "./index.<ext>" as entry | ||
entryPath = entryPath || (yield getSourcePathFromExportPath(cwd, '.')) || ''; | ||
if (args.version) { | ||
return logger.log(version); | ||
} | ||
if (exportKeys.length === 0 && entryPath) { | ||
exportPaths['.'] = constructDefaultExportCondition(entryPath, packageType); | ||
if (args.help) { | ||
return help(); | ||
} | ||
const bundleOrWatch = (rollupConfig)=>{ | ||
const { input , exportName } = rollupConfig; | ||
const exportPath = getExportPath(pkg, cwd, exportName); | ||
// Log original entry file relative path | ||
const source = typeof input.input === 'string' ? path.relative(cwd, input.input) : exportPath; | ||
const buildMetadata = { | ||
source | ||
}; | ||
if (options.watch) { | ||
return Promise.resolve(runWatch(rollupConfig, buildMetadata)); | ||
const entry = source ? path__default.default.resolve(cwd, source) : ''; | ||
const bundle = require('./index').bundle; | ||
let timeStart = Date.now(); | ||
let timeEnd; | ||
try { | ||
yield bundle(entry, bundleConfig); | ||
timeEnd = Date.now(); | ||
} catch (err) { | ||
if (err.name === 'NOT_EXISTED') { | ||
help(); | ||
return exit(err); | ||
} | ||
return runBundle(rollupConfig); | ||
}; | ||
const hasSpecifiedEntryFile = entryPath ? (yield fileExists(entryPath)) && (yield fs__default.default.stat(entryPath)).isFile() : false; | ||
if (!hasSpecifiedEntryFile && !isMultiEntries) { | ||
const err = new Error(`Entry file \`${entryPath}\` is not existed`); | ||
err.name = 'NOT_EXISTED'; | ||
return Promise.reject(err); | ||
throw err; | ||
} | ||
// has `types` field in package.json or has `types` exports in any export condition for multi-entries | ||
const hasTypings = Object.values(exportPaths).some((condition)=>condition.hasOwnProperty('types')); | ||
// Enable types generation if it's types field specified in package.json | ||
if (hasTypings) { | ||
options.dts = hasTypings; | ||
const duration = timeEnd - timeStart; | ||
// watching mode | ||
if (watch) { | ||
logger.log(`🔍 Watching assets in ${cwd}...`); | ||
return; | ||
} | ||
let result; | ||
const buildConfigs = yield buildEntryConfig(pkg, entryPath, exportPaths, options, cwd, defaultTsOptions, false); | ||
const assetsJobs = buildConfigs.map((rollupConfig)=>bundleOrWatch(rollupConfig)); | ||
const typesJobs = hasTsConfig && options.dts ? (yield buildEntryConfig(pkg, entryPath, exportPaths, options, cwd, defaultTsOptions, true)).map((rollupConfig)=>bundleOrWatch(rollupConfig)) : []; | ||
result = yield Promise.all(assetsJobs.concat(typesJobs)); | ||
logSizeStats(); | ||
return result; | ||
// build mode | ||
logger.log(`✨ Finished in ${formatDuration(duration)}`); | ||
yield lintPackage(cwd); | ||
}); | ||
return _bundle.apply(this, arguments); | ||
return _run.apply(this, arguments); | ||
} | ||
function runWatch({ input , output }, metadata) { | ||
const watchOptions = [ | ||
_extends({}, input, { | ||
output: output, | ||
watch: { | ||
exclude: [ | ||
'node_modules/**' | ||
] | ||
} | ||
}) | ||
]; | ||
const watcher = rollup.watch(watchOptions); | ||
watcher.on('event', (event)=>{ | ||
switch(event.code){ | ||
case 'ERROR': | ||
{ | ||
return onError(event.error); | ||
} | ||
case 'START': | ||
{ | ||
logger.log(`Start building ${metadata.source} ...`); | ||
break; | ||
} | ||
case 'END': | ||
{ | ||
break; | ||
} | ||
default: | ||
return; | ||
function main() { | ||
return _main.apply(this, arguments); | ||
} | ||
function _main() { | ||
_main = _async_to_generator(function*() { | ||
let params, error; | ||
try { | ||
params = parseCliArgs(process.argv.slice(2)); | ||
} catch (err) { | ||
error = err; | ||
} | ||
if (error || !params) { | ||
if (!error) help(); | ||
return exit(error); | ||
} | ||
yield run(params); | ||
}); | ||
return watcher; | ||
return _main.apply(this, arguments); | ||
} | ||
function runBundle({ input , output }) { | ||
return rollup.rollup(input).then((bundle)=>{ | ||
const writeJobs = output.map((options)=>bundle.write(options)); | ||
return Promise.all(writeJobs); | ||
}, onError); | ||
} | ||
function onError(error) { | ||
if (!error) return; | ||
// logging source code in format | ||
if (error.frame) { | ||
process.stderr.write(error.frame + '\n'); | ||
} | ||
// filter out the rollup plugin error information such as loc/frame/code... | ||
const err = new Error(error.message); | ||
err.stack = error.stack; | ||
throw err; | ||
} | ||
exports.bundle = bundle; | ||
main().catch(exit); |
@@ -81,3 +81,2 @@ Object.defineProperty(exports, '__esModule', { value: true }); | ||
if (typeof value === 'string') { | ||
// TODO: determine cjs or esm by "type" field in package.json | ||
result = { | ||
@@ -630,3 +629,3 @@ [isCommonjs ? 'require' : 'import']: value | ||
// TODO: improve the source detection | ||
const source = (yield getSourcePathFromExportPath(cwd, entryExport)) || entryPath; | ||
const source = entryPath || (yield getSourcePathFromExportPath(cwd, entryExport)); | ||
if (!source) return undefined; | ||
@@ -867,4 +866,9 @@ const exportCondition = { | ||
} | ||
if (exportKeys.length === 0 && entryPath) { | ||
exportPaths['.'] = constructDefaultExportCondition(entryPath, packageType); | ||
if (entryPath) { | ||
// with -o option | ||
if (options.file) { | ||
exportPaths['.'] = constructDefaultExportCondition(options.file, packageType); | ||
} else if (exportKeys.length === 0) { | ||
exportPaths['.'] = constructDefaultExportCondition('dist/index.js', packageType); | ||
} | ||
} | ||
@@ -871,0 +875,0 @@ const bundleOrWatch = (rollupConfig)=>{ |
{ | ||
"name": "bunchee", | ||
"version": "3.3.0", | ||
"version": "3.3.1", | ||
"description": "zero config bundler for js/ts/jsx libraries", | ||
@@ -5,0 +5,0 @@ "bin": { |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
4
51711
1254