Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"Passthrough" loader for select extensions #2272

Closed
jack828 opened this issue May 27, 2022 · 6 comments
Closed

"Passthrough" loader for select extensions #2272

jack828 opened this issue May 27, 2022 · 6 comments

Comments

@jack828
Copy link

jack828 commented May 27, 2022

Hi. Thank you for the fantastic package.

I am currently in the process of replacing babel with esbuild in my entire toolchain.

I am currently using babel to transpile every file in my project directories, and in another issue (i have lost it now) I use a command very similar to:

esbuild `find api -name '*.js'` --platform=node --outdir=dist --format=cjs

However this does not fulfil my requirement exactly - I have additional file types (like json, etc) so i am required to modify the find command to just include any file blindly:

esbuild `find api -type f` --platform=node --outdir=dist --format=cjs

Now comes my issue, I have a file that is just a text file with the extension .tpl (it's a template for lodash) - I read this file in when it is required and consume it.

I have a few options that i am in the process of trying, but i believe because of the way i am using esbuild to transpile files, i just need a "passthrough" loader option - one that does absolutely nothing to the file and just sends it directly to the output.

This way i could do --loader:.tpl=passthrough and still have my desired result.

This is related to my issue in privatenumber/tsx#22.

I am more than happy to (try to) write a plugin for this if you do not believe it to be part of the core package - however i do need to ask if it is still possible to use the esbuild cli with the plugin?

related #1089

@hyrious
Copy link

hyrious commented May 27, 2022

Maybe it can be the meaning of --loader=file in transform mode.

@evanw
Copy link
Owner

evanw commented May 27, 2022

I think a better fit might be a copy loader: #2255.

@jack828
Copy link
Author

jack828 commented May 27, 2022

copy sounds like it could be a great fit. So long as it leaves the file the same!

@jack828
Copy link
Author

jack828 commented May 28, 2022

Until this gets added (I know you're doing this in spare time so not a complaint!!) I got around this by using a build script instead.

I figured it may be useful for other people to see how i did it. It's a small shame to have to use javascript directly for build actions but I can't complain at the speed improvement.

My script is:

const esbuild = require('esbuild')
const { join } = require('path')
const fs = require('fs')
const naverc = fs
  .readFileSync(join(__dirname, '../.naverc'), 'utf8')
  .replace('\n', '')

const [, , dir, ...files] = process.argv

const filesToTranspile = []
const filesToCopy = []
files.forEach((file) => {
  if (/\.test\.js?$/u.test(file) || /\/test\//u.test(file)) {
    // ignore
  } else if (/\.js$/u.test(file)) {
    filesToTranspile.push(file)
  } else {
    filesToCopy.push(file)
  }
})

;(async () => {
  const result = await esbuild.build({
    entryPoints: filesToTranspile,
    platform: 'node',
    format: 'cjs',
    outdir: `dist/${dir}`,
    target: `node${naverc}`,
    logLevel: 'info'
  })

  await Promise.all(
    filesToCopy.map(async (file) => {
      const destinationFile = join(__dirname, '../dist', file)
      const destinationDir = destinationFile.slice(
        0,
        destinationFile.lastIndexOf('/')
      )
      await fs.promises.mkdir(destinationDir, { recursive: true })
      await fs.promises.copyFile(file, destinationFile)
    })
  )
  console.log(result)
})()

and it's called like: for i in components api lib; do node tasks/build-esbuild.js $i `find $i -type f`; done

The script filters out my test files + test fixtures (primitively, but it works for me!) and then just separates out the transpile targets from the copy targets. It also leverages my project specific node version (via naverc), which will tell esbuild to automatically transpile the unsupported features that i use.

Once esbuild has done it's thing, it will run a copy operation on the rest of the files.

The speed is nothing to turn your nose up at:

➜ time yarn build:babel
yarn run v1.12.3
$ for i in components api lib; do babel $i --ignore '**.test.js' --copy-files -s --out-dir dist/$i; done
Successfully compiled 527 files with Babel (6422ms).
Successfully compiled 19 files with Babel (810ms).
Successfully compiled 9 files with Babel (508ms).
Done in 8.24s.
yarn build:babel  11.89s user 0.55s system 148% cpu 8.393 total

vs new:

➜ time yarn build-esbuild
yarn run v1.12.3
$ for i in components api lib; do node tasks/build-esbuild.js $i `find $i -type f`; done
-- output snipped for brevity --
Done in 0.43s.
yarn build-esbuild  0.40s user 0.09s system 83% cpu 0.596 total

I can't even believe it!

@evanw
Copy link
Owner

evanw commented Jun 16, 2022

Closing this now that #2255 has been implemented and shipped. See also #2320.

@evanw evanw closed this as completed Jun 16, 2022
@jack828
Copy link
Author

jack828 commented Jun 16, 2022

You are my hero 💙 this works exactly as I expected it would.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants