dts-cli
Version:
Zero-config TypeScript package development
200 lines (199 loc) • 9.24 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.createRollupConfig = void 0;
const tslib_1 = require("tslib");
const utils_1 = require("./utils");
const constants_1 = require("./constants");
const plugin_terser_1 = tslib_1.__importDefault(require("@rollup/plugin-terser"));
const core_1 = require("@babel/core");
const plugin_commonjs_1 = tslib_1.__importDefault(require("@rollup/plugin-commonjs"));
const plugin_json_1 = tslib_1.__importDefault(require("@rollup/plugin-json"));
const plugin_replace_1 = tslib_1.__importDefault(require("@rollup/plugin-replace"));
const plugin_node_resolve_1 = tslib_1.__importStar(require("@rollup/plugin-node-resolve"));
// import sourceMaps from 'rollup-plugin-sourcemaps';
const rollup_plugin_typescript2_1 = tslib_1.__importDefault(require("rollup-plugin-typescript2"));
const typescript_1 = tslib_1.__importDefault(require("typescript"));
const path_1 = tslib_1.__importDefault(require("path"));
const extractErrors_1 = require("./errors/extractErrors");
const babelPluginDts_1 = require("./babelPluginDts");
const tsconfig_1 = require("./tsconfig");
const rollupTypes_1 = require("./rollupTypes");
const errorCodeOpts = {
errorMapFilePath: constants_1.paths.appErrorsJson,
};
// shebang cache map thing because the transform only gets run once
let shebang = {};
async function createRollupConfig(appPackageJson, opts, outputNum) {
const findAndRecordErrorCodes = await (0, extractErrors_1.extractErrors)(Object.assign(Object.assign({}, errorCodeOpts), opts));
const shouldMinify = opts.minify !== undefined ? opts.minify : opts.env === 'production';
const outputSuffix = [opts.format, opts.env, shouldMinify ? 'min' : '', 'js']
.filter(Boolean)
.join('.');
let entryFileNames = `[name].${outputSuffix}`;
// if there's only one input, uses the package name instead of the filename
const inputKeys = Object.keys(opts.input);
if (inputKeys.length === 1) {
entryFileNames = `${inputKeys[0]}.${outputSuffix}`;
}
const tsCompilerOptions = (0, tsconfig_1.typescriptCompilerOptions)(opts.tsconfig);
const typesRollupEnabled = opts.rollupTypes && (0, rollupTypes_1.isTypesRollupEnabled)(appPackageJson);
const declarationDir = (0, tsconfig_1.typescriptCompilerOptions)(opts.tsconfig).declarationDir ||
(typesRollupEnabled ? path_1.default.join('dist', 'types') : undefined);
return {
// Tell Rollup the entry point to the package
input: opts.input,
// Tell Rollup which packages to ignore
external: (id) => {
// bundle in polyfills as DTS can't (yet) ensure they're installed as deps
if (id.startsWith('regenerator-runtime')) {
return false;
}
return (0, utils_1.external)(id);
},
// Rollup has treeshaking by default, but we can optimize it further...
treeshake: {
// We assume reading a property of an object never has side-effects.
// This means dts WILL remove getters and setters defined directly on objects.
// Any getters or setters defined on classes will not be effected.
//
// @example
//
// const foo = {
// get bar() {
// console.log('effect');
// return 'bar';
// }
// }
//
// const result = foo.bar;
// const illegalAccess = foo.quux.tooDeep;
//
// Punchline....Don't use getters and setters
propertyReadSideEffects: false,
},
// Establish Rollup output
output: {
// Set the output directory
dir: constants_1.paths.appDist,
// Set filenames of the consumer's package
entryFileNames,
// Pass through the file format
format: opts.format,
// Do not let Rollup call Object.freeze() on namespace import objects
// (i.e. import * as namespaceImportObject from...) that are accessed dynamically.
freeze: false,
// Respect tsconfig esModuleInterop when setting __esModule.
esModule: Boolean(tsCompilerOptions === null || tsCompilerOptions === void 0 ? void 0 : tsCompilerOptions.esModuleInterop),
name: opts.name || (0, utils_1.safeVariableName)(opts.name),
sourcemap: true,
globals: { react: 'React', 'react-native': 'ReactNative' },
exports: 'named',
},
plugins: [
!!opts.extractErrors && {
name: 'error-extractor',
async transform(source) {
await findAndRecordErrorCodes(source);
return source;
},
},
(0, plugin_node_resolve_1.default)({
mainFields: [
'module',
'main',
opts.target !== 'node' ? 'browser' : undefined,
].filter(Boolean),
extensions: [...plugin_node_resolve_1.DEFAULTS.extensions, '.jsx'],
}),
// all bundled external modules need to be converted from CJS to ESM
(0, plugin_commonjs_1.default)({
// use a regex to make sure to include eventual hoisted packages
include: opts.format === 'umd'
? /\/node_modules\//
: /\/regenerator-runtime\//,
}),
(0, plugin_json_1.default)(),
{
name: 'shebang',
// Custom plugin that removes shebang from code because newer
// versions of bublé bundle their own private version of `acorn`
// and I don't know a way to patch in the option `allowHashBang`
// to acorn. Taken from microbundle.
// See: https://github.com/Rich-Harris/buble/pull/165
transform(code) {
let reg = /^#!(.*)/;
let match = code.match(reg);
shebang[opts.name] = match ? '#!' + match[1] : '';
code = code.replace(reg, '');
return {
code,
map: null,
};
},
},
(0, rollup_plugin_typescript2_1.default)({
typescript: typescript_1.default,
tsconfig: opts.tsconfig,
tsconfigDefaults: {
exclude: [
// all TS test files, regardless whether co-located or in test/ etc
'**/*.spec.ts',
'**/*.test.ts',
'**/*.spec.tsx',
'**/*.test.tsx',
// TS defaults below
'node_modules',
'bower_components',
'jspm_packages',
constants_1.paths.appDist,
],
compilerOptions: {
sourceMap: true,
declaration: true,
jsx: 'react',
},
},
tsconfigOverride: {
compilerOptions: Object.assign(Object.assign({
// TS -> esnext, then leave the rest to babel-preset-env
target: 'esnext' }, (Boolean(declarationDir) ? { declarationDir } : {})), (outputNum > 0
? { declaration: false, declarationMap: false }
: {})),
},
check: !opts.transpileOnly && outputNum === 0,
useTsconfigDeclarationDir: Boolean(declarationDir),
}),
(0, babelPluginDts_1.babelPluginDts)({
exclude: 'node_modules/**',
extensions: [...core_1.DEFAULT_EXTENSIONS, 'ts', 'tsx'],
passPerPreset: true,
custom: {
targets: opts.target === 'node' ? { node: '10' } : undefined,
extractErrors: opts.extractErrors,
format: opts.format,
},
babelHelpers: 'bundled',
}),
opts.env !== undefined &&
(0, plugin_replace_1.default)({
'process.env.NODE_ENV': JSON.stringify(opts.env),
preventAssignment: true,
}),
// removed as it does not support rollup v3 yet.
// TODO: we could move to babel's inputSourceMap option(as it is supported in its readme)
// sourceMaps(),
shouldMinify &&
(0, plugin_terser_1.default)({
output: { comments: false },
compress: {
keep_infinity: true,
pure_getters: true,
passes: 10,
},
ecma: 5,
toplevel: opts.format === 'cjs',
}),
],
};
}
exports.createRollupConfig = createRollupConfig;