// Based on // https://github.com/vercel/next.js/blob/canary/packages/next/taskfile-swc.js // taskr babel plugin with Babel 7 support // https://github.com/lukeed/taskr/pull/305 const path = require('path') const transform = require('@swc/core').transform module.exports = function (task) { task.plugin( 'swc', {}, function* ( file, { server = true, stripExtension, dev, outDir = 'dist', baseUrl = '' } = {} ) { // Don't compile .d.ts if (file.base.endsWith('.d.ts')) return const swcClientOptions = { module: { type: 'es6', ignoreDynamic: true, }, jsc: { loose: true, target: 'es2016', parser: { syntax: 'typescript', dynamicImport: true, tsx: file.base.endsWith('.tsx'), }, transform: { react: { runtime: 'automatic', pragma: 'React.createElement', pragmaFrag: 'React.Fragment', throwIfNamespace: true, development: false, useBuiltins: true, }, }, }, } const swcServerOptions = { module: { type: 'es6', ignoreDynamic: true, }, env: { targets: { node: '14.0.0', }, }, jsc: { loose: true, parser: { syntax: 'typescript', dynamicImport: true, tsx: file.base.endsWith('.tsx'), }, transform: { react: { runtime: 'automatic', pragma: 'React.createElement', pragmaFrag: 'React.Fragment', throwIfNamespace: true, development: false, useBuiltins: true, }, }, }, } const swcOptions = server ? swcServerOptions : swcClientOptions const filePath = path.join(file.dir, file.base) const options = { filename: filePath, sourceMaps: false, ...swcOptions, } if (options.sourceMaps && !options.sourceFileName) { // Using `outDir` and `baseUrl` build a relative path from `outDir` to // the `baseUrl` path for source maps const basePath = path.join(__dirname, baseUrl) const relativeFilePath = path.relative(basePath, filePath) const fullFilePath = path.join(__dirname, filePath) const distFilePath = path.dirname( path.join(__dirname, outDir, relativeFilePath) ) options.sourceFileName = path.relative(distFilePath, fullFilePath) } const output = yield transform(file.data.toString('utf-8'), options) const ext = path.extname(file.base) // Replace `.ts|.tsx` with `.js` in files with an extension if (ext) { const extRegex = new RegExp(ext.replace('.', '\\.') + '$', 'i') // Remove the extension if stripExtension is enabled or replace it with `.js` file.base = file.base.replace(extRegex, stripExtension ? '' : '.js') } if (output.map) { const map = `${file.base}.map` output.code += Buffer.from(`\n//# sourceMappingURL=${map}`) // add sourcemap to `files` array this._.files.push({ base: map, dir: file.dir, data: Buffer.from(output.map), }) } file.data = Buffer.from(output.code) } ) }