UNPKG

11.4 kBJavaScriptView Raw
1#!/usr/bin/env node
2
3'use strict';
4
5function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
6
7var path = require('path');
8var async = require('async');
9var lodash = require('lodash');
10var fileExists = _interopDefault(require('file-exists'));
11var meow = _interopDefault(require('meow'));
12var chalk = _interopDefault(require('chalk'));
13var rollup = require('rollup');
14var relink = _interopDefault(require('rollup-plugin-relink'));
15var nodeResolve = _interopDefault(require('rollup-plugin-node-resolve'));
16var jsonPlugin = _interopDefault(require('rollup-plugin-json'));
17var yamlPlugin = _interopDefault(require('rollup-plugin-yaml'));
18var replacePlugin = _interopDefault(require('rollup-plugin-replace'));
19var buble = _interopDefault(require('rollup-plugin-buble'));
20var babel = _interopDefault(require('rollup-plugin-babel'));
21
22function createBubleConfig() {
23 return buble()
24}
25
26var classicPreset = [ "latest", {
27 es2015: {
28 modules: false
29 }
30}];
31
32var modernPreset = [ "babel-preset-env", {
33 targets: {
34 node: 6,
35 browsers: [
36 "Safari 10",
37 "iOS 10",
38 "Edge 14",
39 "Chrome 54",
40 "ChromeAndroid 54",
41 "Firefox 50",
42 "FirefoxAndroid 50"
43 ]
44 },
45
46 modules: false,
47 debug: false,
48 useBuiltIns: true
49}];
50
51function createHelper(modern, minified, presets, plugins) {
52 if ( presets === void 0 ) presets = [];
53 if ( plugins === void 0 ) plugins = [];
54
55 if (minified) {
56 presets = presets.concat([
57 [ "babili", {
58 booleans: false,
59 infinity: false
60 }]
61 ]);
62 }
63
64 return babel({
65 // Don't try to find .babelrc because we want to force this configuration.
66 babelrc: false,
67
68 // Allow usage of transform-runtime for referencing to a common library of polyfills
69 runtimeHelpers: true,
70
71 // Remove comments - these are often positioned on the wrong positon after transpiling anyway
72 comments: false,
73
74 // No need for preserve perfect formatting
75 compact: true,
76
77 // Should the output be minified (not printing last semicolons in blocks, printing literal string
78 // values instead of escaped ones, stripping () from new when safe)
79 minified: minified,
80
81 exclude: "node_modules/**",
82
83 presets: [
84 modern ? modernPreset : classicPreset ].concat( presets
85 ),
86
87 plugins: [
88 // Cherry-picks Lodash modules so you don’t have to.
89 // https://www.npmjs.com/package/babel-plugin-lodash
90 "lodash",
91
92 // Improve some ES3 edge case to make code parseable by older clients
93 // e.g. when using reserved words as keys like "catch"
94 "transform-es3-property-literals",
95 "transform-es3-member-expression-literals",
96
97 // Using centralized helpers but require generic Polyfills being loaded separately
98 // e.g. via Babel-Runtime or via services like polyfill.io.
99 // See also: https://github.com/babel/babel/tree/master/packages/babel-plugin-transform-runtime
100 [ "transform-runtime", {
101 // default
102 helpers: true,
103
104 // default
105 regenerator: true,
106
107 // changed from default. More efficient to use real polyfills.
108 polyfill: false
109 }],
110
111 // class { handleClick = () => { } }
112 "transform-class-properties",
113
114 // { ...todo, completed: true }
115 [ "transform-object-rest-spread", { useBuiltIns: true }],
116
117 // Eliminates unnecessary closures from your JavaScript in the name of performance
118 // https://github.com/codemix/babel-plugin-closure-elimination
119 "closure-elimination",
120
121 // Strip flow type annotations from your output code.
122 "transform-flow-strip-types" ].concat( plugins
123 )
124 })
125}
126
127function createLatestConfig(minified) {
128 return {
129 classic: createHelper(false, minified),
130 modern: createHelper(true, minified)
131 }
132}
133
134var additionalPresets = [
135 "react"
136];
137
138var additionalPlugins = [
139 // Transform JSX and prefer built-in methods
140 [ "transform-react-jsx", { useBuiltIns: true }],
141
142 // Optimization: hoist JSX that never changes out of render()
143 "transform-react-constant-elements",
144
145 // Optimization: wrap propTypes into environment checks
146 "transform-react-remove-prop-types"
147];
148
149function createReactConfig(minified) {
150 return {
151 classic: createHelper(false, minified, additionalPresets, additionalPlugins),
152 modern: createHelper(true, minified, additionalPresets, additionalPlugins)
153 }
154}
155
156// We try to benefit from native features when possible and offer
157// additional builds containing es2015 code for modern clients (Node v6, Chrome 50+, etc.)
158// For bundling you have to use a tool which is aware of the additional package entries
159// to access the additional exported library files though e.g. via 'main' fields in Webpack v2.
160function getTranspilers(mode, ref)
161{
162 var minified = ref.minified;
163
164 switch (mode)
165 {
166 case "buble":
167 return createBubleConfig(minified)
168
169 case "latest":
170 return createLatestConfig(minified)
171
172 case "react":
173 return createReactConfig(minified)
174
175 }
176}
177
178function getBanner(pkg) {
179 var banner = "/*! " + (pkg.name) + " v" + (pkg.version);
180
181 if (pkg.author) {
182 if (typeof pkg.author === "object") {
183 banner += " by " + (pkg.author.name) + " <" + (pkg.author.email) + ">";
184 } else if (typeof pkg.author === "string") {
185 banner += " by " + (pkg.author.name);
186 }
187 }
188
189 banner += " */";
190
191 return banner
192}
193
194var CWD = process.cwd();
195var PKG = require(path.resolve(CWD, "package.json"));
196
197var cache;
198
199
200
201var cli = meow("\n Usage\n $ prepublish-lib\n\n Options\n --entry-node Entry file for NodeJS environment [default = auto]\n --entry-browser Entry file for Browser environment [default = auto]\n\n --output-folder Configure the output folder [default = auto]\n\n -t, --transpiler Chose the transpiler/config to use. Either \"react\", \"latest\" or \"buble\". [default = latest]\n -x, --minified Enabled minification of output files\n -m, --sourcemap Create a source map file during processing\n\n -v, --verbose Verbose output mode [default = false]\n -q, --quiet Quiet output mode [default = false]\n", {
202 default: {
203 entryNode: null,
204 entryBrowser: null,
205
206 outputFolder: null,
207
208 transpiler: "react",
209 minified: false,
210 sourcemap: true,
211
212 verbose: false,
213 quiet: false
214 }
215});
216
217
218var verbose = cli.flags.verbose;
219var quiet = cli.flags.quiet;
220
221if (verbose) {
222 console.log(cli.flags);
223}
224
225
226/* eslint-disable dot-notation */
227var outputFileMatrix = {
228 "node-classic-commonjs": PKG["main"] || null,
229 "node-classic-esmodule": PKG["module"] || PKG["jsnext:main"] || null,
230 "node-modern-commonjs": PKG["main:modern"] || null,
231 "node-modern-esmodule": PKG["module:modern"] || null,
232 "browser-classic-esmodule": PKG["browser"] || PKG["web"] || PKG["browserify"] || null,
233 "browser-modern-esmodule": PKG["browser:modern"] || PKG["web:modern"] || PKG["browserify:modern"] || null
234};
235
236var outputFolder = cli.flags.outputFolder;
237if (outputFolder) {
238 outputFileMatrix["node-classic-commonjs"] = outputFolder + "/node.classic.commonjs.js";
239 outputFileMatrix["node-classic-esmodule"] = outputFolder + "/node.classic.esmodule.js";
240 outputFileMatrix["node-modern-commonjs"] = outputFolder + "/node.modern.commonjs.js";
241 outputFileMatrix["node-modern-esmodule"] = outputFolder + "/node.modern.esmodule.js";
242 outputFileMatrix["browser-classic-esmodule"] = outputFolder + "/browser.classic.esmodule.js";
243 outputFileMatrix["browser-modern-esmodule"] = outputFolder + "/browser.modern.esmodule.js";
244}
245
246// Rollups support these formats: 'amd', 'cjs', 'es', 'iife', 'umd'
247var format2Rollup = {
248 commonjs: "cjs",
249 esmodule: "es"
250};
251
252var moduleId = PKG.name;
253var moduleName = lodash.camelCase(moduleId);
254var banner = getBanner(PKG);
255var envs = {};
256var formats = [ "esmodule", "commonjs" ];
257var transpilers = getTranspilers("react", {
258 minified: cli.flags.minified
259});
260
261if (cli.flags.entryNode) {
262 envs.node = [ cli.flags.entryNode ];
263} else {
264 envs.node = [ "src/index.js", "module/index.js", "src/server/index.js" ];
265}
266
267if (cli.flags.entryBrowser) {
268 envs.browser = [ cli.flags.entryBrowser ];
269} else {
270 envs.browser = [ "src/browser/index.js", "src/client/index.js", "src/browser.js", "src/client.js", "src/web.js" ];
271}
272
273async.eachOfSeries(envs, function (envEntries, envId, envCallback) {
274 var entry = lookupBest(envEntries);
275 if (entry)
276 {
277 if (!quiet) {
278 console.log(("Using entry " + (chalk.blue(entry)) + " for environment " + (chalk.blue(envId))));
279 }
280
281 async.eachOfSeries(formats, function (format, formatIndex, formatCallback) {
282 async.eachOfSeries(transpilers, function (currentTranspiler, transpilerId, variantCallback) {
283 var destFile = outputFileMatrix[(envId + "-" + transpilerId + "-" + format)];
284 if (destFile) {
285 return bundleTo({ entry: entry, envId: envId, transpilerId: transpilerId, currentTranspiler: currentTranspiler, format: format, destFile: destFile, variantCallback: variantCallback })
286 } else {
287 return variantCallback(null)
288 }
289 }, formatCallback);
290 }, envCallback);
291 }
292 else
293 {
294 envCallback(null);
295 }
296});
297
298function lookupBest(candidates) {
299 var filtered = candidates.filter(fileExists);
300 return filtered[0]
301}
302
303function bundleTo(ref) {
304 var entry = ref.entry;
305 var envId = ref.envId;
306 var transpilerId = ref.transpilerId;
307 var currentTranspiler = ref.currentTranspiler;
308 var format = ref.format;
309 var destFile = ref.destFile;
310 var variantCallback = ref.variantCallback;
311
312 if (!quiet) {
313 console.log(((chalk.green(">>> Bundling")) + " " + (chalk.magenta(PKG.name)) + "-" + (chalk.magenta(PKG.version)) + " as " + (chalk.blue(transpilerId)) + " defined as " + (chalk.blue(format)) + " to " + (chalk.green(destFile)) + "..."));
314 }
315
316 var prefix = "process.env.";
317 var variables = {};
318 variables[(prefix + "NAME")] = JSON.stringify(PKG.name);
319 variables[(prefix + "VERSION")] = JSON.stringify(PKG.version);
320 variables[(prefix + "TARGET")] = JSON.stringify(envId);
321
322 var fileRelink = relink({ outputFolder: outputFolder, entry: entry, verbose: verbose });
323 rollup.rollup({
324 entry: entry,
325 cache: cache,
326 onwarn: function (msg) { return console.warn(msg); },
327 external: function external(dependency)
328 {
329 if (dependency === entry) {
330 return false
331 }
332
333 if (fileRelink.isExternal(dependency)) {
334 return true
335 }
336
337 if (path.isAbsolute(dependency)) {
338 var rel = path.relative(CWD, dependency);
339 return Boolean(/node_modules/.exec(rel))
340 }
341
342 return dependency.charAt(0) !== "."
343 },
344 plugins:
345 [
346 nodeResolve({
347 extensions: [ ".js", ".jsx", ".ts", ".tsx", ".json" ],
348 jsnext: true,
349 module: true,
350 main: true
351 }),
352 jsonPlugin,
353 yamlPlugin,
354 replacePlugin(variables),
355 currentTranspiler,
356 fileRelink
357 ]
358 })
359 .then(function (bundle) { return bundle.write({
360 format: format2Rollup[format],
361 moduleId: moduleId,
362 moduleName: moduleName,
363 banner: banner,
364 sourceMap: cli.flags.sourcemap,
365 dest: destFile
366 }); }
367 )
368 .then(function () { return variantCallback(null); }
369 )
370 .catch(function (err) {
371 console.error(err);
372 variantCallback(("Error during bundling " + format + ": " + err));
373 });
374}
375//# sourceMappingURL=prepublish-lib.js.map