UNPKG

3.33 kBJavaScriptView Raw
1/**
2 * Compile files
3 * @function ababel
4 * @param {string} pattern - Glob file name pattern
5 * @param {Object} [options] - Optional settings
6 * @param {string} [options.status] - Status file path
7 * @param {string} [options.cwd] - Current working directory path
8 * @param {string} [options.out] - Output directory path
9 * @param {boolean} [options.minified] - Minified or not
10 * @param {string[]} [options.reflects] - File patterns to reflects changes
11 * @returns {Promise}
12 */
13'use strict'
14
15const aglob = require('aglob')
16const convertSourceMap = require('convert-source-map')
17const writeout = require('writeout')
18const akvStatus = require('akv-status')
19const path = require('path')
20const filedel = require('filedel')
21const {statAsync} = require('asfs')
22const {isProduction} = require('asenv')
23const {transformFile} = require('@babel/core')
24const {DEFAULT_PRESET, DEFAULT_EXT} = require('./constants')
25
26const {replaceExt} = require('./helpers/file_helper')
27const relative = (filename) => path.relative(process.cwd(), filename)
28const mtime = (filename) => statAsync(filename).catch(() => null).then(({mtime}) => mtime)
29
30/** @lends ababel */
31async function ababel (pattern, options = {}) {
32 let {
33 status = 'tmp/ababel.status.json',
34 cwd = process.cwd(),
35 out = process.cwd(),
36
37 presets = DEFAULT_PRESET.split(','),
38 sourceMaps = !isProduction(),
39 minified = false,
40 ignore = [],
41 reflects = [],
42 plugins = [],
43 sourceRoot,
44 ext = DEFAULT_EXT.split(','),
45 } = options
46
47 const store = akvStatus(status)
48 try {
49 const filenames = await aglob(pattern, {cwd, ignore})
50 reflects = await aglob(reflects)
51 for (const filename of filenames) {
52 const src = relative(path.resolve(cwd, filename))
53 const dest = relative(path.resolve(out, ext.reduce((filename, ext) => replaceExt(filename, ext, '.js'), filename)))
54 if (!isProduction()) {
55 const changed = await store.filterStatusUnknown([src, dest, ...reflects])
56 if (changed.length === 0) {
57 let srcMtime = await mtime(src)
58 let destMtime = await mtime(dest)
59 let skip = srcMtime && destMtime && (srcMtime <= destMtime)
60 if (skip) {
61 continue
62 }
63 }
64 }
65 const {code, map, ast} = await new Promise((resolve, reject) => {
66 const options = {
67 presets,
68 minified,
69 sourceMaps,
70 compact: false,
71 babelrc: false,
72 filename: path.resolve(src),
73 filenameRelative: path.relative(cwd, path.resolve(src)),
74 sourceRoot: sourceRoot || path.relative(out, cwd),
75 plugins: ['@babel/plugin-transform-runtime', ...plugins],
76 }
77 transformFile(src, options, (err, result) => err ? reject(err) : resolve(result))
78 })
79 try {
80 if (dest !== src) {
81 await filedel(dest)
82 }
83 } catch (err) {
84 // Do nothing
85 }
86 const {skipped} = await writeout(dest, `${code}\n${convertSourceMap.fromObject(map).toComment()}`, {
87 mkdirp: true,
88 skipIfIdentical: true
89 })
90 if (!skipped) {
91 console.log(`File generated: ${relative(dest)}`)
92 }
93
94 await store.saveStatus([src, dest, ...reflects])
95 }
96 } catch (err) {
97 await store.destroy()
98 throw err
99 }
100}
101
102module.exports = ababel