UNPKG

1.65 kBJavaScriptView Raw
1const path = require('path')
2const esbuild = require('esbuild')
3const { getOptions } = require('loader-utils')
4
5/** @type {import('esbuild').Service} */
6let service
7
8const exts = ['.js', '.jsx', '.ts', '.tsx']
9
10module.exports = async function (source) {
11 const done = this.async()
12 const options = getOptions(this)
13 if (!service) {
14 return done(
15 new Error(
16 `[esbuild-loader] You need to add ESBuildPlugin to your webpack config first`
17 )
18 )
19 }
20
21 try {
22 const ext = path.extname(this.resourcePath)
23 if (!exts.includes(ext)) {
24 return done(
25 new Error(`[esbuild-loader] Unsupported file extension: ${ext}`)
26 )
27 }
28
29 const result = await service.transform(source, {
30 target: options.target || 'es2015',
31 loader: ext.slice(1),
32 jsxFactory: options.jsxFactory,
33 jsxFragment: options.jsxFragment,
34 sourcemap: options.sourceMap
35 })
36 done(null, result.js, result.jsSourceMap)
37 } catch (err) {
38 done(err)
39 }
40}
41
42module.exports.ESBuildPlugin = class ESBuildPlugin {
43 /**
44 * @param {import('webpack').Compiler} compiler
45 */
46 apply(compiler) {
47 let watching = false
48
49 const startService = async () => {
50 if (!service) {
51 service = await esbuild.startService()
52 }
53 }
54
55 compiler.hooks.run.tapPromise('esbuild', async () => {
56 await startService()
57 })
58 compiler.hooks.watchRun.tapPromise('esbuild', async () => {
59 watching = true
60 await startService()
61 })
62
63 compiler.hooks.done.tap('esbuild', () => {
64 if (!watching && service) {
65 service.stop()
66 service = undefined
67 }
68 })
69 }
70}