Skip to content

Commit a1426ba

Browse files
Merge pull request #64 from privatenumber/develop
2 parents 20efa09 + b3f5ee6 commit a1426ba

18 files changed

+3150
-3029
lines changed

.github/workflows/release.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ jobs:
1717
with:
1818
node-version: 14.x
1919
- name: Install dependencies
20-
run: yarn
20+
run: npm ci
2121
- name: Test
2222
run: npm run test --if-present
2323
- name: Release

.github/workflows/test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,6 @@ jobs:
2323
with:
2424
node-version: ${{ matrix.node-version }}
2525
- name: Install dependencies
26-
run: yarn
26+
run: npm ci
2727
- name: Test
2828
run: npm run test --if-present

.gitignore

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,19 @@
1-
node_modules
2-
types
3-
dist
1+
# Mac OS X
2+
.DS_Store
3+
4+
# Logs
5+
logs
6+
*.log
7+
npm-debug.log*
8+
9+
# Dependency directories
10+
node_modules/
11+
12+
# Optional npm cache directory
13+
.npm
14+
15+
# Optional REPL history
16+
.node_repl_history
17+
18+
# Output of 'npm pack'
19+
*.tgz

.releaserc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"master",
44
{
55
"name": "next",
6-
"prerelease": true
6+
"prerelease": "alpha"
77
}
88
]
99
}

.xo-config

Lines changed: 0 additions & 15 deletions
This file was deleted.

LICENSE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
MIT License
22

3-
Copyright (c) 2020 Hiroki Osame
3+
Copyright (c) Hiroki Osame <[email protected]>
44

55
Permission is hereby granted, free of charge, to any person obtaining a copy
66
of this software and associated documentation files (the "Software"), to deal

README.md

Lines changed: 35 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@
22

33
Speed up your Webpack build with [esbuild](https://github.com/evanw/esbuild)! 🔥
44

5+
[esbuild](https://github.com/evanw/esbuild) is a JavaScript bundler written in Go that supports blazing fast ESNext & TypeScript transpilation and JS minification.
56

6-
[esbuild](https://github.com/evanw/esbuild) is written in Go, and supports blazing fast ESNext & TypeScript transpilation, and JS minification.
7+
[esbuild-loader](https://github.com/privatenumber/esbuild-loader) lets you harness the speed of esbuild in your Webpack build by offering faster alternatives for transpilation (eg. babel-loader/ts-loader) and minification (eg. Terser)!
78

9+
<sub>If you like this project, please star it & [follow me](https://github.com/privatenumber) to see what other cool projects I'm working on! ❤️</sub>
810

911
## 🚀 Install
1012

@@ -31,8 +33,8 @@ In `webpack.config.js`:
3133
+ test: /\.js$/,
3234
+ loader: 'esbuild-loader',
3335
+ options: {
34-
+ target: 'es2015', // Syntax to compile to (see options below for possible values)
35-
+ },
36+
+ target: 'es2015' // Syntax to compile to (see options below for possible values)
37+
+ }
3638
+ },
3739

3840
...
@@ -55,26 +57,41 @@ In `webpack.config.js`:
5557
rules: [
5658
- {
5759
- test: /\.tsx?$/,
58-
- use: 'ts-loader',
60+
- use: 'ts-loader'
5961
- },
6062
+ {
6163
+ test: /\.tsx?$/,
6264
+ loader: 'esbuild-loader',
6365
+ options: {
6466
+ loader: 'tsx', // Or 'ts' if you don't need tsx
65-
+ target: 'es2015',
66-
+ },
67+
+ target: 'es2015'
68+
+ }
6769
+ },
6870

6971
...
70-
],
72+
]
7173
},
7274
plugins: [
7375
+ new ESBuildPlugin()
7476
]
7577
}
7678
```
7779

80+
#### Configuration
81+
If you have a `tsconfig.json` file, you can pass it in via the `tsconfigRaw` option. Note, esbuild only supports [a subset of `tsconfig` options](https://github.com/evanw/esbuild/blob/master/lib/types.ts#L92) and does not do type checks.
82+
83+
```diff
84+
{
85+
test: /\.tsx?$/,
86+
loader: 'esbuild-loader',
87+
options: {
88+
loader: 'tsx',
89+
target: 'es2015',
90+
+ tsconfigRaw: require('./tsconfig.json')
91+
}
92+
}
93+
```
94+
7895
### Minification (eg. Terser)
7996
You can replace JS minifiers like Terser or UglifyJs. Checkout the [benchmarks](https://github.com/privatenumber/minification-benchmarks) to see how much faster esbuild is.
8097

@@ -92,8 +109,10 @@ In `webpack.config.js`:
92109
+ optimization: {
93110
+ minimize: true,
94111
+ minimizer: [
95-
+ new ESBuildMinifyPlugin()
96-
+ ],
112+
+ new ESBuildMinifyPlugin({
113+
+ target: 'es2015' // Syntax to compile to (see options below for possible values)
114+
+ })
115+
+ ]
97116
+ },
98117

99118
plugins: [
@@ -102,11 +121,15 @@ In `webpack.config.js`:
102121
}
103122
```
104123

124+
> _💁‍♀️ Protip: Use the minify plugin in-place of the loader to transpile your JS_
125+
>
126+
> The `target` option tells _esbuild_ that it can use newer JS syntax to perform better minification. If you're not using TypeScript or any syntax unsupported by Webpack, you can also leverage this as a transpilation step. It will be faster because there's less files to work on and will produce a smaller output because the polyfills will only be bundled once for the entire build instead of per file.
127+
105128
## ⚙️ Options
106129

107130
### Loader
108131
The loader supports options from [esbuild](https://github.com/evanw/esbuild#command-line-usage).
109-
- `target` `<String>` (`es2015`) - Environment target (e.g. es2017, chrome80, esnext)
132+
- `target` `<String>` (`es2015`) - [Environment target](https://github.com/evanw/esbuild#javascript-syntax-support) (e.g. es2016, chrome80, esnext)
110133
- `loader` `<String>` (`js`) - Which loader to use to handle file
111134
- [Possible values](https://github.com/evanw/esbuild/blob/master/lib/types.ts#L3): `js`, `jsx`, `ts`, `tsx`, `json`, `text`, `base64`, `file`, `dataurl`, `binary`
112135
- `jsxFactory` `<String>` - What to use instead of React.createElement
@@ -115,7 +138,8 @@ The loader supports options from [esbuild](https://github.com/evanw/esbuild#comm
115138
Enable source-maps via [`devtool`](https://webpack.js.org/configuration/devtool/)
116139

117140
### MinifyPlugin
118-
- `minify` `<Boolean>` (`true`) - Sets all `--minify-*` flags
141+
- `target` `<String>` (`esnext`) - [Environment target](https://github.com/evanw/esbuild#javascript-syntax-support) (e.g. es2016, chrome80, esnext)
142+
- `minify` `<Boolean>` (`true`) - Sets all `minify` flags
119143
- `minifyWhitespace` `<Boolean>` - Remove whitespace
120144
- `minifyIdentifiers` `<Boolean>` - Shorten identifiers
121145
- `minifySyntax` `<Boolean>` - Use equivalent but shorter syntax

lib/loader.js

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,27 @@ async function ESBuildLoader(source) {
1313
);
1414
}
1515

16+
const transformOptions = {
17+
...options,
18+
target: options.target || 'es2015',
19+
loader: options.loader || 'js',
20+
sourcemap: this.sourceMap,
21+
sourcefile: this.resourcePath,
22+
};
23+
1624
try {
17-
const result = await service.transform(source, {
18-
...options,
19-
target: options.target || 'es2015',
20-
loader: options.loader || 'js',
21-
sourcemap: this.sourceMap,
22-
sourcefile: this.resourcePath,
25+
const result = await service.transform(source, transformOptions).catch(async error => {
26+
// Target might be a TS file accidentally parsed as TSX
27+
if (transformOptions.loader === 'tsx' && error.message.includes('Unexpected')) {
28+
transformOptions.loader = 'ts';
29+
return service.transform(source, transformOptions).catch(_ => {
30+
throw error;
31+
});
32+
}
33+
34+
throw error;
2335
});
24-
done(null, result.js, result.jsSourceMap);
36+
done(null, result.code, result.map);
2537
} catch (error) {
2638
done(error);
2739
}

lib/minify-plugin.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ class ESBuildMinifyPlugin {
2323
}
2424

2525
/**
26-
* @param {import('webpack').Compiler} compiler
27-
*/
26+
* @param {import('webpack').Compiler} compiler
27+
*/
2828
apply(compiler) {
2929
compiler.hooks.compilation.tap(pluginName, compilation => {
3030
if (!compiler.$esbuildService) {
@@ -101,14 +101,14 @@ class ESBuildMinifyPlugin {
101101
assetName,
102102
sourcemap ?
103103
new SourceMapSource(
104-
result.js || '',
104+
result.code || '',
105105
assetName,
106-
result.jsSourceMap,
106+
result.map,
107107
source,
108108
map,
109109
true,
110110
) :
111-
new RawSource(result.js || ''),
111+
new RawSource(result.code || ''),
112112
{
113113
...info,
114114
minimized: true,

lib/plugin.js

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
1-
const esbuild = require('esbuild');
1+
const {startService} = require('esbuild');
22

33
class ESBuildPlugin {
44
/**
5-
* @param {import('webpack').Compiler} compiler
6-
*/
5+
* @param {import('webpack').Compiler} compiler
6+
*/
77
apply(compiler) {
88
let watching = false;
99

10-
const startService = async () => {
10+
const safeStartService = async () => {
1111
if (!compiler.$esbuildService) {
12-
compiler.$esbuildService = await esbuild.startService();
12+
compiler.$esbuildService = await startService();
1313
}
1414
};
1515

@@ -20,12 +20,12 @@ class ESBuildPlugin {
2020
});
2121

2222
compiler.hooks.run.tapPromise('esbuild', async () => {
23-
await startService();
23+
await safeStartService();
2424
});
2525

2626
compiler.hooks.watchRun.tapPromise('esbuild', async () => {
2727
watching = true;
28-
await startService();
28+
await safeStartService();
2929
});
3030

3131
compiler.hooks.done.tap('esbuild', () => {

0 commit comments

Comments
 (0)