1*8d307f52SEvan Bacon// Based on Next.js swc taskr file. 2*8d307f52SEvan Bacon// https://github.com/vercel/next.js/blob/5378db8f807dbb9ff0993662f0a39d0f6cba2452/packages/next/taskfile-swc.js 3*8d307f52SEvan Bacon 4*8d307f52SEvan Baconconst path = require('path'); 5*8d307f52SEvan Baconconst assert = require('assert'); 6*8d307f52SEvan Bacon 7*8d307f52SEvan Baconconst transform = require('@swc/core').transform; 8*8d307f52SEvan Bacon 9*8d307f52SEvan Baconmodule.exports = function (task) { 10*8d307f52SEvan Bacon const ENVIRONMENTS = { 11*8d307f52SEvan Bacon // Settings for compiling the CLI code that runs in Node.js environments. 12*8d307f52SEvan Bacon cli: { 13*8d307f52SEvan Bacon output: 'build', 14*8d307f52SEvan Bacon options: { 15*8d307f52SEvan Bacon module: { 16*8d307f52SEvan Bacon type: 'commonjs', 17*8d307f52SEvan Bacon }, 18*8d307f52SEvan Bacon env: { 19*8d307f52SEvan Bacon targets: { 20*8d307f52SEvan Bacon node: '12.13.0', 21*8d307f52SEvan Bacon }, 22*8d307f52SEvan Bacon }, 23*8d307f52SEvan Bacon jsc: { 24*8d307f52SEvan Bacon loose: true, 25*8d307f52SEvan Bacon parser: { 26*8d307f52SEvan Bacon syntax: 'typescript', 27*8d307f52SEvan Bacon dynamicImport: true, 28*8d307f52SEvan Bacon }, 29*8d307f52SEvan Bacon }, 30*8d307f52SEvan Bacon }, 31*8d307f52SEvan Bacon }, 32*8d307f52SEvan Bacon }; 33*8d307f52SEvan Bacon // Like `/^(cli|sdk)$/` 34*8d307f52SEvan Bacon const matcher = new RegExp(`^(${Object.keys(ENVIRONMENTS).join('|')})$`); 35*8d307f52SEvan Bacon 36*8d307f52SEvan Bacon task.plugin('swc', {}, function* (file, environment, { stripExtension } = {}) { 37*8d307f52SEvan Bacon // Don't compile .d.ts 38*8d307f52SEvan Bacon if (file.base.endsWith('.d.ts')) return; 39*8d307f52SEvan Bacon 40*8d307f52SEvan Bacon // Environment assertion 41*8d307f52SEvan Bacon assert.match(environment, matcher); 42*8d307f52SEvan Bacon 43*8d307f52SEvan Bacon const setting = ENVIRONMENTS[environment]; 44*8d307f52SEvan Bacon const filePath = path.join(file.dir, file.base); 45*8d307f52SEvan Bacon const inputFilePath = path.join(__dirname, filePath); 46*8d307f52SEvan Bacon const outputFilePath = path.dirname(path.join(__dirname, setting.output, filePath)); 47*8d307f52SEvan Bacon 48*8d307f52SEvan Bacon const options = { 49*8d307f52SEvan Bacon filename: path.join(file.dir, file.base), 50*8d307f52SEvan Bacon sourceMaps: true, 51*8d307f52SEvan Bacon sourceFileName: path.relative(outputFilePath, inputFilePath), 52*8d307f52SEvan Bacon ...setting.options, 53*8d307f52SEvan Bacon }; 54*8d307f52SEvan Bacon 55*8d307f52SEvan Bacon const output = yield transform(file.data.toString('utf-8'), options); 56*8d307f52SEvan Bacon const ext = path.extname(file.base); 57*8d307f52SEvan Bacon 58*8d307f52SEvan Bacon // Replace `.ts|.tsx` with `.js` in files with an extension 59*8d307f52SEvan Bacon if (ext) { 60*8d307f52SEvan Bacon const extRegex = new RegExp(ext.replace('.', '\\.') + '$', 'i'); 61*8d307f52SEvan Bacon // Remove the extension if stripExtension is enabled or replace it with `.js` 62*8d307f52SEvan Bacon file.base = file.base.replace(extRegex, stripExtension ? '' : '.js'); 63*8d307f52SEvan Bacon } 64*8d307f52SEvan Bacon 65*8d307f52SEvan Bacon if (output.map) { 66*8d307f52SEvan Bacon const map = `${file.base}.map`; 67*8d307f52SEvan Bacon 68*8d307f52SEvan Bacon output.code += Buffer.from(`\n//# sourceMappingURL=${map}`); 69*8d307f52SEvan Bacon 70*8d307f52SEvan Bacon // add sourcemap to `files` array 71*8d307f52SEvan Bacon this._.files.push({ 72*8d307f52SEvan Bacon base: map, 73*8d307f52SEvan Bacon dir: file.dir, 74*8d307f52SEvan Bacon data: Buffer.from(output.map), 75*8d307f52SEvan Bacon }); 76*8d307f52SEvan Bacon } 77*8d307f52SEvan Bacon 78*8d307f52SEvan Bacon file.data = Buffer.from(setVersionCode(output.code)); 79*8d307f52SEvan Bacon }); 80*8d307f52SEvan Bacon}; 81*8d307f52SEvan Bacon 82*8d307f52SEvan Baconfunction setVersionCode(code) { 83*8d307f52SEvan Bacon return code.replace(/process\.env\.__EXPO_VERSION/g, `"${require('./package.json').version}"`); 84*8d307f52SEvan Bacon} 85