UNPKG

4.83 kBJavaScriptView Raw
1import fs from 'fs'
2import path from 'path'
3
4import builtins from 'builtin-modules'
5import { flatMap } from 'lodash'
6import { terser } from 'rollup-plugin-terser'
7import babel from 'rollup-plugin-babel'
8import commonjs from 'rollup-plugin-commonjs'
9import json from 'rollup-plugin-json'
10import replace from 'rollup-plugin-replace'
11import nodeResolve from 'rollup-plugin-node-resolve'
12import typescript from 'rollup-plugin-typescript'
13import { getGlobals, normalizePkg, upperCamelCase } from '@pkgr/umd-globals'
14import { namedExports } from '@pkgr/named-exports'
15
16const PRODUCTION = 'production'
17
18const BASIC_PLUGINS = [
19 nodeResolve({
20 mainFields: [
21 'esnext',
22 'es2015',
23 'esm2015',
24 'fesm2015',
25 'esm5',
26 'fesm5',
27 'module',
28 'main',
29 ],
30 }),
31 commonjs({ namedExports }),
32 json(),
33]
34
35const DEFAULT_FORMATS = ['cjs', 'es2015', 'esm']
36
37let isTsAvailable = false
38
39try {
40 isTsAvailable = !!require.resolve('typescript')
41} catch (e) {}
42
43// eslint-disable-next-line node/no-deprecated-api
44const EXTENSIONS = Object.keys(require.extensions)
45
46if (isTsAvailable) {
47 EXTENSIONS.unshift('.ts', '.tsx')
48}
49
50const tryExtensions = filepath => {
51 const ext = EXTENSIONS.find(ext => fs.existsSync(filepath + ext))
52 return ext ? filepath + ext : filepath
53}
54
55const configBase = ({
56 formats,
57 monorepo,
58 input,
59 outputDir = 'lib',
60 exports,
61 externals = [],
62 globals: umdGlobals,
63 prod = process.env.NODE_ENV === PRODUCTION,
64} = {}) => {
65 const pkgsPath = path.resolve(
66 typeof monorepo === 'string' ? monorepo : 'packages',
67 )
68
69 if (monorepo !== false) {
70 monorepo = fs.existsSync(pkgsPath)
71 }
72
73 const pkgs = monorepo ? fs.readdirSync(pkgsPath) : ['']
74
75 const globals = getGlobals(umdGlobals)
76
77 const configs = flatMap(pkgs, pkg => {
78 const pkgPath = path.resolve(monorepo ? pkgsPath : '', pkg)
79 const srcPath = path.resolve(pkgPath, 'src')
80
81 let pkgInput = input
82 let pkgOutputDir = outputDir
83
84 if (!fs.existsSync(srcPath) && pkgInput == null) {
85 pkgInput = 'index'
86 }
87
88 pkgInput = tryExtensions(path.resolve(pkgPath, pkgInput || 'src/index'))
89
90 const isAbsolute = path.isAbsolute(pkgInput)
91
92 if (pkgOutputDir && !pkgOutputDir.endsWith('/')) {
93 pkgOutputDir = pkgOutputDir + '/'
94 }
95
96 if (
97 !fs.existsSync(pkgInput) ||
98 (isAbsolute && !pkgInput.startsWith(pkgPath))
99 ) {
100 return []
101 }
102
103 const {
104 name,
105 engines: { node } = {},
106 dependencies = {},
107 peerDependencies = {},
108 } = require(path.resolve(pkgPath, 'package.json'))
109
110 pkg = pkg || name
111
112 const external = externals.concat(
113 Object.keys(peerDependencies),
114 node ? Object.keys(dependencies).concat(builtins) : [],
115 )
116
117 const isTsInput = /\.tsx?/.test(pkgInput)
118 const pkgFormats =
119 formats && formats.length
120 ? formats
121 : DEFAULT_FORMATS.concat(node ? [] : 'umd')
122 const pkgGlobals = external.reduce((pkgGlobals, pkg) => {
123 if (pkgGlobals[pkg] == null) {
124 pkgGlobals[pkg] = upperCamelCase(normalizePkg(pkg))
125 }
126 return pkgGlobals
127 }, globals)
128
129 return pkgFormats.map(format => {
130 const isEsVersion = /^es(\d+|next)$/.test(format) && format !== 'es5'
131 return {
132 input: pkgInput,
133 output: {
134 file: path.resolve(
135 pkgPath,
136 `${pkgOutputDir}${format}${prod ? '.min' : ''}.js`,
137 ),
138 format: isEsVersion ? 'esm' : format,
139 name: pkgGlobals[pkg] || upperCamelCase(normalizePkg(pkg)),
140 globals,
141 exports,
142 },
143 external,
144 plugins: [
145 isTsAvailable && isTsInput
146 ? typescript({
147 target: isEsVersion ? format : 'es5',
148 })
149 : babel({
150 exclude: ['*.min.js', '*.production.js'],
151 presets: [
152 [
153 '@babel/preset-env',
154 isEsVersion
155 ? {
156 targets: {
157 esmodules: true,
158 },
159 }
160 : undefined,
161 ],
162 ],
163 }),
164 ].concat(
165 BASIC_PLUGINS,
166 prod
167 ? [
168 replace({
169 'process.env.NODE_ENV': JSON.stringify(PRODUCTION),
170 }),
171 terser(),
172 ]
173 : [],
174 ),
175 }
176 })
177 })
178
179 console.assert(
180 configs.length,
181 "No configuration resolved, mark sure you've setup correctly",
182 )
183
184 return configs
185}
186
187export default (options = {}) =>
188 configBase(options).concat(
189 options.prod
190 ? configBase(
191 Object.assign({}, options, {
192 prod: false,
193 }),
194 )
195 : [],
196 )