UNPKG

@rockpack/compiler

Version:

The easiest webpack config generator.

171 lines (143 loc) 5.95 kB
const babel = require('@babel/core'); const createBabelPresets = require('@rockpack/babel'); const { getMode, getRootRequireDir } = require('@rockpack/utils'); const { copyFileSync, existsSync, renameSync } = require('node:fs'); const path = require('node:path'); const rimraf = require('rimraf'); const { isArray, isObject, isString, isUndefined } = require('valid-types'); const { getFiles, getTypeScript, writeFile } = require('./file-system-utils'); const { capitalize } = require('./other'); const pathToTSConf = require('./path-to-ts-conf'); module.exports = async function sourceCompile(conf) { const root = getRootRequireDir(); const mode = getMode(); console.log('=========Source compile is starting....========='); const formats = ['cjs', 'esm']; const output = {}; formats.forEach((format) => { if (isObject(conf[format])) { output[format] = { dist: false, src: false, }; output[`has${capitalize(format)}`] = false; if (isString(conf[format].src) && isString(conf[format].dist)) { output[format].src = conf[format].src; output[format].dist = conf[format].dist; output[`has${capitalize(format)}`] = true; } } }); const state = Object.keys(output) .filter((key) => key.indexOf('has') === 0) .some((item) => output[item]); if (!state) { throw new Error(`${formats.join(', ')} fields are not object`); } let debug = false; if (mode === 'development') { debug = true; } if (conf.debug) { debug = true; } for (let i = 0, l = formats.length; i < l; i++) { const format = formats[i]; const opt = output[format]; if (isUndefined(opt)) { continue; } const dist = path.join(root, opt.dist); const src = path.join(root, opt.src); const tsAndTsx = await getTypeScript(opt.src); const copyFiles = await getFiles(opt.src, undefined, ['**/*.ts', '**/*.tsx', '**/*.js', '**/*.jsx']); const jsAndJsx = await getFiles(opt.src, '*.+(js|jsx)'); let compilerOptions; const tsConfig = pathToTSConf(root, mode, debug); rimraf.sync(dist); console.log(`=========${format} format is starting=========`); if (isArray(tsAndTsx) && tsAndTsx.length > 0) { if (existsSync(tsConfig)) { const babelOptions = createBabelPresets({ framework: 'react', isNodejs: !!conf.nodejs, isomorphic: conf.__isIsomorphic, modules: format === 'esm' ? false : 'commonjs', typescript: true, }); const cachedBabelPlugins = babelOptions.plugins; if (format === 'esm') { babelOptions.plugins = [[require.resolve('babel-plugin-add-import-extension'), { extension: 'mjs' }]]; } else if (format === 'cjs') { babelOptions.plugins = [ [require.resolve('babel-plugin-add-import-extension'), { extension: 'cjs' }], require.resolve('@babel/plugin-transform-modules-commonjs'), ]; } babelOptions.plugins = [...babelOptions.plugins, ...cachedBabelPlugins]; console.log('Babel convert:\n'); console.log(tsAndTsx.join('\n')); console.log('\n'); tsAndTsx.forEach((file) => { const { code } = babel.transformFileSync(file, babelOptions); const relativePath = path.relative(src, file); const outputPath = `${relativePath.substring(0, relativePath.lastIndexOf('.'))}${format === 'esm' ? '.mjs' : '.cjs'}`; writeFile(path.join(dist, outputPath), code); }); } else { throw new Error('tsconfig not found'); } } else if (isArray(jsAndJsx) && jsAndJsx.length > 0) { const babelOptions = createBabelPresets({ framework: 'react', isNodejs: !!conf.nodejs, isomorphic: conf.__isIsomorphic, modules: format === 'esm' ? false : 'commonjs', }); const cachedBabelPlugins = babelOptions.plugins; if (format === 'esm') { babelOptions.plugins = [[require.resolve('babel-plugin-add-import-extension'), { extension: 'mjs' }]]; } else if (format === 'cjs') { babelOptions.plugins = [ [require.resolve('babel-plugin-add-import-extension'), { extension: 'cjs' }], require.resolve('@babel/plugin-transform-modules-commonjs'), ]; } babelOptions.plugins = [...babelOptions.plugins, ...cachedBabelPlugins]; console.log('Babel convert:\n'); console.log(jsAndJsx.join('\n')); console.log('\n'); jsAndJsx.forEach((file) => { const { code } = babel.transformFileSync(file, babelOptions); const relativePath = path.relative(src, file); const outputPath = `${relativePath.substring(0, relativePath.lastIndexOf('.'))}${format === 'esm' ? '.mjs' : '.cjs'}`; writeFile(path.join(dist, outputPath), code); }); } if (isArray(copyFiles) && copyFiles.length > 0) { console.log('Files will copy:\n'); console.log(copyFiles.join('\n')); console.log('\n'); copyFiles.forEach((file) => { const filePth = path.relative(path.join(root, opt.src), file); const fileDest = path.join(dist, filePth); copyFileSync(file, fileDest); }); } const jsFiles = await getFiles(dist, '*.js'); const jsMapFiles = await getFiles(dist, '*.js.map'); if (Array.isArray(jsFiles) && jsFiles.length > 0) { jsFiles.forEach((file) => { const modified = file.substr(0, file.lastIndexOf('.')) + (format === 'cjs' ? '.cjs' : '.mjs'); renameSync(file, modified); }); } if (Array.isArray(jsMapFiles) && jsMapFiles.length > 0) { jsMapFiles.forEach((file) => { const modified = file.substr(0, file.lastIndexOf('.js.map')) + (format === 'cjs' ? '.cjs.map' : '.mjs.map'); renameSync(file, modified); }); } console.log(`=========${format} format finished=========`); } };