-
Notifications
You must be signed in to change notification settings - Fork 33
/
index.js
executable file
·118 lines (97 loc) · 3.23 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#!/usr/bin/env node
/* eslint-disable no-console */
'use strict'
import program from 'commander'
import fg from 'fast-glob'
import fs from 'fs-extra'
import path from 'node:path'
import {transformFile} from '@swc/core'
import {getSWCConfig} from '@s-ui/compiler-config'
const SOURCE_DIR = './src'
const OUTPUT_DIR = './lib'
const TS_EXTENSION_REGEX = /(\.ts)x?/
const COMPILED_EXTENSION = '.js'
const DEFAULT_TS_CONFIG = {
declaration: true,
emitDeclarationOnly: true,
incremental: true,
jsx: 'react-jsx',
module: 'es6',
esModuleInterop: true,
noImplicitAny: false,
baseUrl: '.',
outDir: OUTPUT_DIR,
skipLibCheck: true,
strict: true,
target: 'es5',
types: ['react', 'node']
}
const getTsConfig = () => {
// Get TS config from the package dir.
const tsConfigPath = path.join(process.cwd(), 'tsconfig.json')
let tsConfig
try {
if (fs.existsSync(tsConfigPath)) {
tsConfig = JSON.parse(fs.readFileSync(tsConfigPath, {encoding: 'utf8'}))
}
} catch (err) {
console.error(err)
}
return tsConfig
}
const compileFile = async (file, options) => {
const {code} = await transformFile(file, getSWCConfig(options))
const outputPath = file.replace(SOURCE_DIR, OUTPUT_DIR).replace(TS_EXTENSION_REGEX, COMPILED_EXTENSION)
await fs.outputFile(outputPath, code)
}
const compileTypes = async (files, options) => {
const {createCompilerHost, createProgram} = await import('typescript').then(module => module.default)
const createdFiles = {}
const host = createCompilerHost(options)
host.writeFile = (fileName, contents) => (createdFiles[fileName] = contents)
const program = createProgram(files, options, host)
program.emit()
return Promise.all(
Object.keys(createdFiles).map(async outputPath => {
const code = createdFiles[outputPath]
await fs.outputFile(outputPath, code)
})
)
}
const commaSeparatedList = value => value.split(',')
program
.option('--ignore [glob]', 'List of patterns to ignore during the compilation', commaSeparatedList)
.option('--modern', 'Transpile using modern browser targets')
.on('--help', () => {
console.log(' Examples:')
console.log('')
console.log(' $ sui-js-compiler')
console.log(' $ sui-js-compiler ./custom-folder')
console.log(' $ sui-js-compiler --ignore="./src/**/*Spec.js"')
console.log(' $ sui-js-compiler --modern"')
console.log('')
})
.parse(process.argv)
const {ignore: ignoreOpts = [], modern: isModern = false} = program.opts()
const ignore = [...ignoreOpts, '**/__tests__']
;(async () => {
console.time('[sui-js-compiler]')
const files = await fg('./src/**/*.{js,jsx,ts,tsx}', {ignore})
const filesToCompile = Promise.all(
files.map(async file => {
const isTypeScript = Boolean(file.match(TS_EXTENSION_REGEX))
await compileFile(file, {isModern, isTypeScript})
})
)
const tsConfig = getTsConfig()
// If TS config exists, set TypeScript as enabled.
const isTypeScriptEnabled = Boolean(tsConfig)
const typesToCompile = isTypeScriptEnabled
? await compileTypes(files, {
...DEFAULT_TS_CONFIG,
...(tsConfig?.compilerOptions ?? {})
})
: Promise.resolve()
await Promise.all([filesToCompile, typesToCompile])
console.timeEnd('[sui-js-compiler]')
})()